CAP: 0064
Title: Memo Authorization for Soroban
Working Group:
Owner: dmkozh@stellar.org
Authors: Dmytro Kozhevin <@dmkozh>
Consulted: Leigh McCulloch <@leighmcculloch>, Siddharth Suresh <@sisuresh>
Status: Draft
Created: 2025-01-09
Discussion: https://github.com/stellar/stellar-protocol/discussions/1610
Protocol version: 23
This CAP adds a new type of Soroban authorization payload that allows for signing the transaction memo.
As specified in the Preamble.
Standalone Soroban authorization payloads (those with SOROBAN_CREDENTIALS_ADDRESS
, see CAP-46-11 for details) for smart contract transactions are designed to be completely independent of the transaction envelope they belong to. This is done in order to support arbitrary custom multi-party authorization schemes that smart contracts may want to implement. As long as an authorization payload has been properly signed, it can be attached to any valid transaction.
However, in some cases there may be a dependency between the transaction envelope and the inner authorization payload that currently can not be signed for. Specifically, transaction memos are often used to identify 'sub-destinations' within the actual destination account. This approach is often used by exchanges for attributing the incoming token transfers to specific exchange users.
Since custom accounts (smart wallets) require using SOROBAN_CREDENTIALS_ADDRESS
in order to sign any operations, it is currently not possible to e.g. sent token from a custom account balance to an exchange account. This is a common procedure for off-ramp or CEX-based trading and thus not supporting it significantly hinders the adoption of custom accounts and requires unsafe workarounds (like using an intermediary classic Stellar account for performing the payment). Custom account adoption itself provides a way of improving the overall user experience of Stellar network.
This CAP is aligned with the following Stellar Network Goals:
- The Stellar Network should make it easy for developers of Stellar projects to create highly usable products.
This CAP introduces a new version of Soroban address credentials that allows users to specify a memo that the transaction must have in order for credentials to be valid for authorization. The new version of credentials doesn't supersede the existing one, i.e. protocol will support both versions.
This patch of XDR changes is based on the XDR files in commit a41b2db15ea34a9f9da5326b996bb8a7ceb5740f
of stellar-xdr.
Stellar-ledger-entries.x | 3 ++-
Stellar-transaction.x | 27 ++++++++++++++++++++++++++-
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/Stellar-ledger-entries.x b/Stellar-ledger-entries.x
index 5bf4f9d..f0bf9ea 100644
--- a/Stellar-ledger-entries.x
+++ b/Stellar-ledger-entries.x
@@ -676,7 +676,8 @@ enum EnvelopeType
ENVELOPE_TYPE_OP_ID = 6,
ENVELOPE_TYPE_POOL_REVOKE_OP_ID = 7,
ENVELOPE_TYPE_CONTRACT_ID = 8,
- ENVELOPE_TYPE_SOROBAN_AUTHORIZATION = 9
+ ENVELOPE_TYPE_SOROBAN_AUTHORIZATION = 9,
+ ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_V2 = 10
};
enum BucketListType
diff --git a/Stellar-transaction.x b/Stellar-transaction.x
index 7d32481..763531c 100644
--- a/Stellar-transaction.x
+++ b/Stellar-transaction.x
@@ -569,10 +569,22 @@ struct SorobanAddressCredentials
SCVal signature;
};
+struct SorobanAddressCredentialsV2
+{
+ ExtensionPoint ext;
+
+ SCAddress address;
+ int64 nonce;
+ uint32 signatureExpirationLedger;
+ Memo txMemo;
+ SCVal signature;
+};
+
enum SorobanCredentialsType
{
SOROBAN_CREDENTIALS_SOURCE_ACCOUNT = 0,
- SOROBAN_CREDENTIALS_ADDRESS = 1
+ SOROBAN_CREDENTIALS_ADDRESS = 1,
+ SOROBAN_CREDENTIALS_ADDRESS_V2 = 2
};
union SorobanCredentials switch (SorobanCredentialsType type)
@@ -581,6 +593,8 @@ case SOROBAN_CREDENTIALS_SOURCE_ACCOUNT:
void;
case SOROBAN_CREDENTIALS_ADDRESS:
SorobanAddressCredentials address;
+case SOROBAN_CREDENTIALS_ADDRESS_V2:
+ SorobanAddressCredentialsV2 addressV2;
};
/* Unit of authorization data for Soroban.
@@ -729,6 +743,17 @@ case ENVELOPE_TYPE_SOROBAN_AUTHORIZATION:
uint32 signatureExpirationLedger;
SorobanAuthorizedInvocation invocation;
} sorobanAuthorization;
+case ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_V2:
+ struct
+ {
+ ExtensionPoint ext;
+
+ Hash networkID;
+ int64 nonce;
+ uint32 signatureExpirationLedger;
+ Memo txMemo;
+ SorobanAuthorizedInvocation invocation;
+ } sorobanAuthorizationV2;
};
enum MemoType
--
A new type of of address credentials is introduced for SorobanAuthorizationEntry
: SOROBAN_CREDENTIALS_ADDRESS_V2
of type SorobanAddressCredentialsV2
. The semantics of the new credentials is identical to the semantics of SOROBAN_CREDENTIALS_ADDRESS
defined by CAP-46-11 with the following exceptions:
- During the authorization process the value of
txMemo
field is validated against the memo of the transaction being executed. In case of a mismatch, the authorization is considered to have failed. - SHA-256 hash of
ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_V2
envelope must be signed instead ofENVELOPE_TYPE_SOROBAN_AUTHORIZATION
envelope used forSOROBAN_CREDENTIALS_ADDRESS
signatures. The envelope is built using the respectively named fields fromSorobanAddressCredentialsV2
, and the target network id that the authorization has to be used for. - No-op extension point has been added for the future extensions to both the authorization entry and the envelope
The first version of the credentials will still be supported by the protocol. It can be considered to be semantically equivalent to SOROBAN_CREDENTIALS_ADDRESS_V2
with txMemo
set to MEMO_NONE
(i.e. it may only pass authorization check when the transaction memo is MEMO_NONE
).
In order to avoid confusion between memos and muxed source accounts, transactions that contain both of:
- Muxed transaction source account and/or muxed operation source account
- At least one Soroban authorization entry with credentials that are not set to
SOROBAN_CREDENTIALS_SOURCE_ACCOUNT
are considered invalid and thus they won't be ever included into ledger.
The design is simply the minimal necessary set of changes that allows for signing transaction memos. We had to come up with the new XDR structures because the initial versions did not have any extension points. In order to simplify potential future changes, the extension point has been introduced as well.
Muxed accounts are an alternative to transaction memos and serve a similar purpose of defining off-chain sub-accounts for the actual accounts. However, they don't align with the change proposed by this CAP due to the following reasons:
- When a muxed account is a source account of a transaction or operation, it defines the source (not the destination) of a transfer and thus the main motivational use case of supporting exchange transfers is not covered by that.
- Muxed account can not be a destination of any Soroban operation because
ScAddress
doesn't allow expressing muxed accounts.
We may consider supporting muxed accounts more holistically as an address type in the future CAPs, but that falls out of scope of this particular change.
There are other transaction fields (currently preconditions and Soroban resources data), that could in theory also be signed as a part of Soroban authorization payloads. However, unlike memos, these fields are normally not used for any sort of identification and provide functionality that can already be replicated in Soroban to some degree. For example, all the Soroban authorization entries must have signature expiration ledger and there is no particular need for also tying the signature to the preconditions of the external transaction. Soroban resources can't be signed at all, as they may depend on the signature itself.
As soon as this CAP becomes active, validators will start accepting the transactions with SOROBAN_CREDENTIALS_ADDRESS_V2
credentials and performing the corresponding authorization checks.
The old credentials format is still accepted and thus no backwards incompatibilities are expected.
There is no measurable impact on resource utilization.
This CAP doesn't raise any new security concerns.
Support for muxed accounts in Soroban or Soroban-specific multiplexed addresses might be done in the future, given the real use cases and demand.
TBD
TBD