The Rebalancing AMM (RAMM) is an AMM that takes prices from an oracle in order to avoid impermanent loss. This code was written for the Solana network using Seahorse 0.2.5.
The particular code of this repository is designed for a SOL/USDC/USDT pool, but with a few tweaks in can be easily adapted to any pool with any number of tokens.
One of the features of the OAMM is that liquidity providers can provide liquidity of just one asset, and the pool will mint a certain type of LP tokens according to the asset the liquidity provider is depositing. In consequence, this particular pool will mint three types of LP tokens: LPSOL, LPUSDC and LPUSDT.
Each OAMM pool consists of a single account that belongs to the oamm class and contains the data described below.
-
balance_sol:f64The current balance of SOL in the pool. -
balance_usdc:f64The current balance of USDC in the pool. -
balance_usdt:f64The current balance of USDT in the pool. -
lp_sol_tokens:f64The current amount of LPSOL tokens in circulation. -
lp_usdc_tokens:f64The current amount of LPUSDT tokens in circulation. -
lp_usdt_tokens:f64The current amount of LPUSDC tokens in circulation. -
base_fee:f64The base fee that the pool charges. The suggested value for the Solana network is0.0008, which amounts to 0.08%. -
protocol_fee:f64The share of the fees that the protocol charges for itself. The suggested value is0.5, which means that half of the collected fees will be kept as revenue for the protocol, while the other half will be deposited into the pool and shared among the liquidity providers. -
base_leverage:f64The base leverage parameter that the pool will use. This serves to concentrate liquidity around the current market price. The suggested value for this parameter is100. -
delta:f64The maximum deviation in the imbalances ratios permitted. The suggested value for this parameter is0.25, which means that the imbalance ratios that are allowed are those between0.75and1.25. Trades that push imbalance ratios outside this range will not be allowed. This parameter is designed to prevent the pool from being heavy unbalanced. -
bump:u8The value of thebumpparameter of the pool account.
Before describing what our program does, we will describe all the Solana accounts that are involved in the different instructions.
Pool accounts
-
pool: The Solana account of the pool. Belongs to theoammclass as described above. Holds the SOL deposited into the pool. -
pool_usdc_tkn_acc: TheTokenAccountthat will hold the USDC deposited into the pool. The owner of this account is thepool's account. -
pool_usdc_tkn_acc: TheTokenAccountthat will hold the USDT deposited into the pool. The owner of this account is thepool's account. -
mint_lpsol: TheTokenMintaccount that willmintandburnthe LPSOL tokens. -
mint_lpusdc: TheTokenMintaccount that willmintandburnthe LPUSDC tokens. -
mint_lpusdt: TheTokenMintaccount that willmintandburnthe LPUSDT tokens.
User accounts
-
user:Signeraccount. The account of the user that interacts with the OAMM. -
user_usdc_tkn_acc: User'sTokenAccountthat holds USDC. Its owner is theuseraccount. -
user_usdt_tkn_acc: User'sTokenAccountthat holds USDT. Its owner is theuseraccount. -
user_lp_sol_tkn_acc: User'sTokenAccountthat holds LPSOL. Its owner is theuseraccount. -
user_lp_usdc_tkn_acc: User'sTokenAccountthat holds LPUSDC. Its owner is theuseraccount. -
user_lp_usdt_tkn_acc: User'sTokenAccountthat holds LPUSDT. Its owner is theuseraccount.
Price accounts
-
price_account_sol: The Pyth network Solana account that tracks the price of the pair SOL/USD. -
price_account_usdc: The Pyth network Solana account that tracks the price of the pair USDC/USD. -
price_account_usdt: The Pyth network Solana account that tracks the price of the pair USDT/USD.
Fee accounts
-
fee_acc_sol: Solana account that holds the fees collected in SOL. -
fee_acc_usdc:TokenAccountthat holds the fees collected in USDC. -
fee_acc_usdt:TokenAccountthat holds the fees collected in USDT.
Remark: When a parameter given to an instruction is denoted by *_usd_tkn_acc instead of *_usdc_tkn_acc or *_usdt_tkn_acc it means that the instruction will be used for both cases and the account that is passed in as a parameter should be the one that corresponds to the token that will be traded. A similar reasoning applies when we use fee_acc_usd instead of fee_acc_usdc or fee_acc_usdt.
Now, we describe our program's instructions.
-
init: Initializes the pool account and the threeTokenMintaccounts that correspond to the three types of LP tokens to be minted. Takes as parametersbasefee,protocolfee,baseleverageanddelta, which are set and fixed with this instruction and can not be changed later. -
deposit_sol: Performs a liquidity deposit of a certain amount of SOL. Its parameters areamount_sol(the amount of SOL to be provided as liquidity), the corresponding Solana accounts,TokenAccounts andTokenMintaccounts needed, and the price accounts. -
deposit_usdc: Performs a liquidity deposit of a certain amount of USDC. Its parameters areamount_usdc(the amount of USDC to be deposited), the corresponding Solana accounts,TokenAccounts andTokenMintaccounts needed, and the price accounts. -
deposit_usdt: Performs a liquidity deposit of a certain amount of USDT. Its parameters areamount_usdt(the amount of USDT to be deposited), the corresponding Solana accounts,TokenAccounts andTokenMintaccounts needed, and the price accounts. -
withdraw_sol: Performs a liquidity withdrawal of SOL. Its parameters areamount_lp_sol, which is the amount of LPSOL to be redeemed, the corresponding Solana accounts,TokenAccounts andTokenMintaccounts needed, and the price accounts. -
withdraw_usdc: Performs a liquidity withdrawal of USDC. Its parameters areamount_lp_usdc, which is the amount of LPUSDC to be redeemed, the corresponding Solana accounts,TokenAccounts andTokenMintaccounts needed, and the price accounts. -
withdraw_usdt: Performs a liquidity withdrawal of USDT. Its parameters areamount_lp_usdt, which is the amount of LPUSDT to be redeemed, the corresponding Solana accounts,TokenAccounts andTokenMintaccounts needed, and the price accounts. -
trade_sol_in: Performs a trade in which SOL goes into the pool and either USDC or USDT goes out of the pool. Apart from the necessary accounts, the parameters of this instruction areamount_sol_in,amount_usd_outandtoken_out. The parametertoken_outis a string that can beUSDCorUSDTaccording to which token the user wants to obtain. On the other hand, if the parameteramount_sol_inis not zero, the trade is performed as if the user depositedamount_sol_inSOL into the pool, and the program computes the amount of either USDC or USDT to be given to the user. In this case, the parameteramount_usd_outis ignored. Ifamount_sol_inis zero, the trade is performed as if the user wants to obtainamount_usd_outof either USDC or USDT from the pool, and the program computes the amount of SOL that the user needs to deposit. -
trade_sol_out: Performs a trade in which SOL goes out of the pool and either USDC or USDT goes into the pool. Apart from the necessary accounts, the parameters of this instruction areamount_usd_in,amount_sol_outandtoken_in. The parametertoken_inis a string that can beUSDCorUSDTaccording to which token the user will deposit. On the other hand, if the parameteramount_usd_inis not zero, the trade is performed as if the user depositedamount_usd_inof either USDC or USDT into the pool, and the program computes the amount of SOL to be given to the user. In this case, the parameteramount_sol_outis ignored. Ifamount_usd_inis zero, the trade is performed as if the user wants to obtainamount_sol_outof SOL from the pool, and the program computes the amount of either USDC or USDT that the user needs to deposit. -
trade_usdc_in_usdt_out: Performs a trade in which USDC goes into the pool and USDT goes out of the pool. Apart from the necessary accounts, the parameters of this instruction areamount_usdc_inandamount_usdt_out. Ifamount_usdc_inis not zero, the trade is performed as if the user depositedamount_usdc_inUSDC into the pool, and the program computes the amount of USDT to be given to the user. In this case, the parameteramount_usdt_outis ignored. Ifamount_usdc_inis zero, the trade is performed as if the user wants to obtainamount_usdt_outUSDT from the pool, and the program computes the amount of USDC that the user needs to deposit. -
trade_usdt_in_usdc_out: Performs a trade in which USDT goes into the pool and USDC goes out of the pool. Apart from the necessary accounts, the parameters of this instruction areamount_usdt_inandamount_usdc_out. Ifamount_usdt_inis not zero, the trade is performed as if the user depositedamount_usdt_inUSDT into the pool, and the program computes the amount of USDC to be given to the user. In this case, the parameteramount_usdc_outis ignored. Ifamount_usdt_inis zero, the trade is performed as if the user wants to obtainamount_usdc_outUSDC from the pool, and the program computes the amount of USDT that the user needs to deposit. -
pool_state: Logs the current state of the pool: balances, LP tokens of each type issued and the current imbalance ratios.