SEP: 0017 Title: Issuer account funding protocol (CAP-13 Based) Author: Tom Quisel Status: Draft Created: 2018-12-14
Account funding via issuer is a method for an issuer to easily fund a user's account. The goal is to make it fast and easy for users with assets outside the Stellar network to move those assets into Stellar and begin sending payments + trading assets. The process also aims to be easy for issuers & wallets to develop. It begins at the point where an issuer has just received a deposit of assets external to the Stellar network (crypto, fiat, or other) from a user. It finishes with the user in possession of the deposited asset issued on the Stellar network and a Stellar account that has a sufficient XLM balance for them to get started using Stellar. It works in cases where the user's account is not yet created and cases where the user's account has a low XLM balance. It depends on CAP-13.
The current way that issuers handle depositing external (off-Stellar) funds into user accounts is explained briefly in SEP-6. It involves a four-step process where:
- A user initiates a deposit with an issuer, specifies the destination account ID for the deposit, and sends the deposit to the issuer's address
- The issuer waits until the external asset deposit arrives in their account, and when it arrives uses some of the deposit value to create the user's account
- The user waits until their account is created, and then adds a trustline for the deposit asset
- The issuer waits until the trustline shows up, and then sends the on-chain asset to the user
This is a poor user experience because of the multiple intermediate steps that require the user or issuer to wait. This SEP uses CAP-13 to provide an experience where the user only has to wait once: between the time they send their external deposit to the issuer and the time the assets arrive in their account.
This SEP is an alternative to SEP-13, and has some extra desirable properties:
- The wallet implementation is simpler
- The issuer implementation is simpler
- At no point does the user need to seek an external source of XLM to complete the deposit
- The deposit ends up in the account ID originally specified by the user, avoiding situations where the user does not have XLM funds to merge accounts or the user's trustlines are spread across multiple accounts and they are unable to trade between assets they hold.
The general setup is the case of an Issuer processing a deposit of an external asset (FunBucks) for a specific User. The User has already initiated a deposit with the Issuer, and specified the Stellar account ID (U) where they want the deposit to arrive.
We consider a few cases:
- U is not yet created
- U is created, but has no FunBucks trustline
- U is created, has a FunBucks trustline, but has insufficient XLM to create an offer (in this case the User's account is wedged even if the FunBucks deposit is received)
- U is created, has a FunBucks trustline, and has plenty of XLM
Case 1: Account Needed
In this case, the Issuer creates U and deducts the cost from the value of the deposit.
- The User deposits 10 FunBucks with the Issuer, external to the Stellar network. the Issuer must now transfer 10 FunBucks tokens to U on Stellar.
- The Issuer determines the amount of XLM that will be required to create a functional account for the User. The breakdown is:
- 2 *
base reserve(for the new account)
base reserve(for the trustline)
base reserve(so the User will be able to create an offer to sell more FunBucks once the deposit completes)
- 10 *
base fee(so the User is able to pay fees for their first several transactions)
- 2 *
- In total, at the current
base reserveof 0.5 XLM and
base feeof 0.00001 XLM, that's 2.0001 XLM.
- The Issuer computes the value of that total in FunBucks at the market rate (say 2.0001 XLM = 1.5 FunBucks), and deducts it from the deposit amount to get that the User will receive 8.5 FunBucks in their new account.
- the Issuer executes a transaction, which:
- creates the User's account U
- performs the CAP-13 AddBalance operation with FunBucks as the asset and U as the destination
- pays 8.5 FunBucks to U
- pays 0.5001 XLM to U
- The next time the User looks at their account, it's fully created, contains their deposit, and is not wedged since they are able to create an offer to sell more FunBucks for XLM if desired.
These cases proceed just like Case 1, but remove unnecessary steps.
- Case 2 removes account creation and the 2 *
base reservededuction that the Issuer needs to fund it
- Case 3 removes the Add Balance operation and the 1 *
base reservededuction that the Issuer needs to fund it
- Case 4 removes the XLM deduction and XLM payment operation necessary to top up the User's account to the point where they have 1 *
base reserve+ 10 *
base feemore XLM than their minimum balance.
In case 1, a third party creates U before the Issuer
In this case, the Issuer checks to see which case applies, sees that U has not been created, and determines that case 1 applies. The Issuer executes the transaction to create & fund U, but the transaction fails because a third party created U between the check and the transaction execution. In this case, the Issuer should re-check and decide which case applies (it will be case 2, 3, or 4), and then execute the appropriate transaction for that case. At this point, if the transaction fails (due to U being merged into some other account, or
ALLOW_ADD_BALANCE being set to
false as described in the CAP-13 proposal), the Issuer should fail the deposit and return the external funds to the User.
Other errors during funding transaction
In other error cases that are not transient (like U has
ALLOW_ADD_BALANCE set to
AUTH_EXTERIOR_IMMUTABLE from CAP-9 is set), the Issuer should fail as soon as possible and return the external funds to the User.
The User spends their extra XLM, and has insufficient XLM to create an offer to sell FunBucks
In this situation the User's Stellar account is wedged. He needs more XLM from an external source to be able to do anything, even though he has a positive FunBucks balance. It is the responsibility of the wallet to prevent a user from taking any actions that reduce their XLM balance below the amount needed to create a sell offer.
Error Handling Flow
To summarize the cases above, this is the full Issuer error handling flow:
- Start: The funding transaction fails
- If the transaction failed because U did not exist when the transaction was generated but now exists:
- Issuer should re-check U's state and decide which case applies (it will be case 2, 3, or 4)
- Issuer creates & executes the appropriate transaction
- If it fails: abort and refund User
- If the transaction failed for any other reason:
- abort and refund User