Curve StableSwap Exchange: Deposit Contracts
Curve pools may rely on a different contract, called a deposit zap for the addition and removal of underlying coins. This is particularly useful for lending pools, which may only support the addition/removal of wrapped coins. Furthermore, deposit zaps are also useful for metapools, which do not support the addition/removal of base pool coins.
Lending Pool Deposits
While Curve lending pools support swaps in both the wrapped and underlying coins, not all lending pools allow liquidity providers to deposit or withdraw the underlying coin.
For example, the Compound Pool allows swaps between cDai
and cUSDC
(wrapped coins), as well as swaps between DAI
and USDC
(underlying coins). However, liquidity providers are not able to deposit DAI
or USDC
to the pool directly. The main reason for why this is not supported by all Curve lending pools lies in the size limit of contracts. Lending pools may differ in complexity and can end up being very close to the contract byte code size limit. In order to overcome this restriction, liquidity can be added and removed to and from a lending pool in the underlying coins via a different contract, called a deposit zap, tailored to lending pools.
For an overview of the Curve lending pool implementation, please refer to the Lending Pool section.
The template source code for a lending pool deposit zap may be viewed on GitHub.
Note
Lending pool deposit zaps may differ in their API. Older pools do not implement the newer API template.
Deposit Zap API (OLD)
Older Curve lending pool deposit zaps do not implement the template API. The deposit zaps which employ an older API are:
DepositBUSD
: BUSD pool deposit zap
DepositCompound
: Compound pool deposit zap
DepositPAX
: PAX pool deposit zap
DepositUSDT
: USDT pool deposit zap
DepositY
: Y pool deposit zap
While not a lending pool, note that the following contract also implements the newer deposit zap API:
DepositSUSD
: SUSD pool deposit zap
Get Deposit Zap Information
Note
Getters generated for public arrays changed between Vyper 0.1.x
and 0.2.x
to accept uint256
instead of int128
in order to handle the lookups. Older deposit zap contracts (v1) use vyper 0.1.x...
, while newer zaps (v2) use vyper 0.2.x...
.
The following Brownie console interaction examples are using the Compound Pool Deposit Zap.
- DepositZap.curve() address: view
Getter for the pool associated with this deposit contract.
>>> zap.curve() '0xA2B47E3D5c44877cca798226B7B8118F9BFb7A56'
- DepositZap.underlying_coins(i: int128) address: view
Getter for the array of underlying coins within the associated pool.
i
: Index of the underlying coin for which to get the address
>>> zap.underlying_coins(0) '0x6B175474E89094C44Da98b954EedeAC495271d0F' >>> zap.underlying_coins(1) '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
- DepositZap.coins(i: int128) address: view
Getter for the array of wrapped coins within the associated pool.
i
: Index of the coin for which to get the address
>>> zap.coins(0) '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643' >>> zap.coins(1) '0x39AA39c021dfbaE8faC545936693aC917d5E7563'
- DepositZap.token() address: view
Getter for the LP token of the associated pool.
>>> zap.token() '0x845838DF265Dcd2c412A1Dc9e959c7d08537f8a2'
Adding/Removing Liquidity
- DepositZap.add_liquidity(uamounts: uint256[N_COINS], min_mint_amount: uint256)
Wrap underlying coins and deposit them in the pool
uamounts
: List of amounts of underlying coins to depositmin_mint_amount
: Minimum amount of LP token to mint from the deposit
- DepositZap.remove_liquidity(_amount: uint256, min_uamounts: uint256[N_COINS])
Withdraw and unwrap coins from the pool.
_amount
: Quantity of LP tokens to burn in the withdrawalmin_uamounts
: Minimum amounts of underlying coins to receive
- DepositZap.remove_liquidity_imbalance(uamounts: uint256[N_COINS], max_burn_amount: uint256)
Withdraw and unwrap coins from the pool in an imbalanced amount.
uamounts
: List of amounts of underlying coins to withdrawmax_burn_amount
: Maximum amount of LP token to burn in the withdrawal
- DepositZap.remove_liquidity_one_coin(_token_amount: uint256, i: int128, min_uamount: uint256, donate_dust: bool = False)
Withdraw and unwrap a single coin from the pool
_token_amount
: Amount of LP tokens to burn in the withdrawali
: Index value of the coin to withdrawmin_uamount
: Minimum amount of underlying coin to receive
- DepositZap.calc_withdraw_one_coin(_token_amount: uint256, i: int128) uint256
Calculate the amount received when withdrawing a single underlying coin.
_token_amount
: Amount of LP tokens to burn in the withdrawali
: Index value of the coin to withdraw
- DepositZap.withdraw_donated_dust()
Donates any LP tokens of the associated pool held by this contract to the contract owner.
Deposit Zap API (NEW)
Compared to the older deposit zaps, the newer zaps mainly optimize for gas efficiency. The API is only modified in part, specifically with regards to return
values and variable naming.
Get Deposit Zap Information
- DepositZap.curve() address: view
Getter for the pool associated with this deposit contract.
- DepositZap.underlying_coins(i: uint256) address: view
Getter for the array of underlying coins within the associated pool.
i
: Index of the underlying coin for which to get the address
- DepositZap.coins(i: uint256) address: view
Getter for the array of wrapped coins within the associated pool.
i
: Index of the coin for which to get the address
- DepositZap.lp_token() address: view
Getter for the LP token of the associated pool.
Adding/Removing Liquidity
- DepositZap.add_liquidity(_underlying_amounts: uint256[N_COINS], _min_mint_amount: uint256) uint256
Wrap underlying coins and deposit them in the pool
_underlying_amounts
: List of amounts of underlying coins to deposit_min_mint_amount
: Minimum amount of LP tokens to mint from the deposit
Returns the amount of LP token received in exchange for the deposited amounts.
- DepositZap.remove_liquidity(_amount: uint256, _min_underlying_amounts: uint256[N_COINS]) uint256[N_COINS]
Withdraw and unwrap coins from the pool.
_amount
: Quantity of LP tokens to burn in the withdrawal_min_underlying_amounts
: Minimum amounts of underlying coins to receive
Returns list of amounts of underlying coins that were withdrawn.
- DepositZap.remove_liquidity_imbalance(_underlying_amounts: uint256[N_COINS], _max_burn_amount: uint256) uint256[N_COINS]
Withdraw and unwrap coins from the pool in an imbalanced amount. Amounts in _underlying_amounts correspond to withdrawn amounts before any fees charge for unwrapping.
_underlying_amounts
: List of amounts of underlying coins to withdraw_max_burn_amount
: Maximum amount of LP token to burn in the withdrawal
Returns list of amounts of underlying coins that were withdrawn.
- DepositZap.remove_liquidity_one_coin(_amount: uint256, i: int128, _min_underlying_amount: uint256) uint256
Withdraw and unwrap a single coin from the pool
_amount
: Amount of LP tokens to burn in the withdrawali
: Index value of the coin to withdraw_min_underlying_amount
: Minimum amount of underlying coin to receive
Returns amount of underlying coin received.
Metapool Deposits
While Curve metapools support swaps between base pool coins, the base pool LP token and metapool coins, they do not allow liquidity providers to deposit and/or withdraw base pool coins.
For example, the GUSD metapool is a pool consisting of GUSD
and 3CRV
(the LP token of the 3Pool) and allows for swaps between GUSD
, DAI
, USDC
, USDT
and 3CRV
. However, liquidity providers are not able to deposit DAI
, USDC
or USDT
to the pool directly. The main reason why this is not possible lies in the maximum byte code size of contracts. Metapools are complex and can therefore end up being very close to the contract byte code size limit. In order to overcome this restriction, liquidity can be added and removed to and from a metapool in the base pool’s coins through a metapool deposit zap.
For an overview of the Curve metapool implementation, please refer to the Metapool section.
The template source code for a metapool deposit “zap” may be viewed on GitHub.
A list of all deployed metapool deposit zaps can be found here.
Note
Metapool deposit zaps contain the following private and hardcoded constants:
N_COINS
: Number of coins in the metapool (excluding base pool coins)BASE_N_COINS
: Number of coins in the base poolN_ALL_COINS
: All coins in the metapool, excluding the base pool LP token (N_COINS + BASE_N_COINS - 1
)
Get Deposit Zap Information
- DepositZap.pool() address: view
Getter for the metapool associated with this deposit contract.
- DepositZap.base_pool() address: view
Getter for the base pool of the metapool associated with this deposit contract.
- DepositZap.base_coins(i: uint256) address: view
Getter for the array of the coins of the metapool’s base pool.
i
: Index of the underlying coin for which to get the address
- DepositZap.coins(i: uint256) address: view
Getter for the array of metapool’s coins.
i
: Index of the coin for which to get the address
- DepositZap.token() address: view
Getter for the LP token of the associated metapool.
Adding/Removing Liquidity
Note
For methods taking the index argument i
, a number in the range from 0
to N_ALL_COINS - 1
is valid. This refers to all coins apart from the base pool LP token.
- DepositZap.add_liquidity(_amounts: uint256[N_ALL_COINS], _min_mint_amount: uint256) uint256
Wrap underlying coins and deposit them in the pool.
_amounts
: List of amounts of underlying coins to deposit_min_mint_amount
: Minimum amount of LP tokens to mint from the deposit
Returns the amount of LP token received in exchange for depositing.
- DepositZap.remove_liquidity(_amount: uint256, _min_amounts: uint256[N_ALL_COINS]) uint256[N_ALL_COINS]
Withdraw and unwrap coins from the pool.
_amount
: Quantity of LP tokens to burn in the withdrawal_min_amounts
: Minimum amounts of underlying coins to receive
Returns a list of amounts of underlying coins that were withdrawn.
- DepositZap.remove_liquidity_one_coin(_token_amount: uint256, i: int128, _min_amount: uint256) uint256
Withdraw and unwrap a single coin from the metapool.
_token_amount
: Amount of LP tokens to burn in the withdrawali
: Index value of the coin to withdraw_min_amount
: Minimum amount of underlying coin to receive
Returns the amount of the underlying coin received.
- DepositZap.remove_liquidity_imbalance(_amounts: uint256[N_ALL_COINS], _max_burn_amount: uint256) uint256
Withdraw coins from the pool in an imbalanced amount
_amounts
: List of amounts of underlying coins to withdraw_max_burn_amount
: Maximum amount of LP token to burn in the withdrawal
Returns the actual amount of the LP token burned in the withdrawal.
- DepositZap.calc_withdraw_one_coin(_token_amount: uint256, i: int128) uint256
Calculate the amount received when withdrawing and unwrapping a single coin
_token_amount
: Amount of LP tokens to burn in the withdrawali
: Index value of the coin to withdraw (i
should be in the range from0
toN_ALL_COINS - 1
, where the LP token of the base pool is removed).
Returns the amount of coin
i
received.
- DepositZap.calc_token_amount(_amounts: uint256[N_ALL_COINS], _is_deposit: bool) uint256
Calculate addition or reduction in token supply from a deposit or withdrawal.
_amounts
: Amount of each underlying coin being deposited_is_deposit
: Set True for deposits, False for withdrawals
Returns the expected amount of LP tokens received.