## Adding Liquidity The function `add_liquidity` is called to add tokens into Curve V1's AMM. For the inputs, it's going to take in the amount of coins to put in and the minimum amount of LP token to mint. `min_mint_amount`. Next, it initializes some variables: `fees` is an array that will be used later for imbalance fee. Curve V1 allows you to add liquidity in a way that makes the token balances imbalanced. For example, you can decide to put only one token in, or you can decide to put all tokens in. And when you add one token as liquidity, this will make the current pool balance imbalanced. So that is what this `fees` array is used for. We'll come back to this later. Next, we have a variable called `_fee`. This number is used to charge for an imbalance fee. If you take a look at this, it has a weird formula: `fee * N_COINS / (4 * (N_COINS - 1))`. Basically, what this does is it makes sure that when you add liquidity, and then remove liquidity, it won't be like swapping tokens without any swap fee. Let me explain this further. Let's say that we have token X, and then we swap, and then we get back token Y. In this case, we will have a swap fee on token Y. Now, in Curve V1, we can also add liquidity in such a way that makes the token balances of the pool imbalanced. For example, we can decide only to add one token. So, let's say that we add X token to the pool. X token add liquidity. Now, Curve V1 also allows us to remove liquidity in such a way that makes the token balances of the pool imbalanced. So, for example, after we had only one token as liquidity, let's say that we remove liquidity, and we remove liquidity in another coin. Say remove liquidity, and we request token Y out. So effectively, what we did here was we put in X token and then, we took out token Y. This is the same as swapping token X for token Y. Now, if we do not have fee on imbalance fee when we're adding liquidity, Basically, this allows us to swap tokens for free. And to make sure that this does not happen, this weird equation makes sure that when we add liquidity and then remove liquidity, it is basically like a swap. For the math for how to derive this part of the equation, I'll put a link in the course. So, that's what this fee is used for. And then we get the admin fee and then calculate the `_A`. Next, we get the `token_supply`. This will be the total supply of LP tokens that are minted. And then, we first calculate liquidity D0. D0 will be the liquidity before we add any tokens into this pool. And we can see this over here. D0 is equal to `get_D_mem(old_balances, amp)`. `old_balances` are the token balances of this pool. And then, we initialize an array called `new_balances`, which is basically copying the old balances. Then, the next part of the code deals with transferring in the tokens. So, scrolling down, we can see that inside the for loop, we get the coins to put in as liquidity. And then, we call the function `transferFrom`. And notice that here we're using `raw_call`. This is to go around the problem that USDT does not return any Boolean when `transferFrom` is called. If you were to use the ERC20 interface for `transferFrom`, when we call `transferFrom` on USDT, this part of the code will fail. So, to avoid this problem, it's using a `raw_call` to call `transferFrom`. So, for each iteration, it's going to transfer the tokens in. And then, it updates this `new_balances`. Remember, this `new_balances` was initialized as `old_balances`. So, to the old balances, we add some amount, the amount that came in. And with this `new_balances`, next we calculate the D again. This time it is called D1. Again, this D represents liquidity. We added some new tokens. And here, what it's doing is it's asking: with this `new_balances`, what is the new liquidity. The next part of the code is calculating the imbalance fee. Imbalance fee basically means that if we were to add tokens into this pool in such a way that does not change the token balance ratios, then we've added tokens in an ideal way. Otherwise, if the ratios of the token change when we had liquidity, then there is some kind of fee that we will have to pay. So, the first question is: well, what is the ideal balance to add as liquidity? And the answer is simple. We take the `old_balances` and we look at D0. This will be the liquidity before adding liquidity, and then D1, this will be the liquidity after adding liquidity. D1 divided by D0 will be the increase in liquidity. So, the old balance should increase by this much amount, D1 divided by D0. As an example, let's say that D1 is 110. D0 is 100. So, D1 divided by D0, so the ideal new balance will be 1.1 times the old balance. Next, we calculate how much the new balance is off from this ideal balance. If the ideal balance is greater than `new_balances` of I, then the difference is ideal balance minus `new_balances` of I. Otherwise, it's the opposite: `new_balances` of I minus ideal balance. Here, we're just getting the difference of ideal balance and `new_balances` of I. And then, fees will be equal to this magic number fee that we saw over here, and then multiplies it by the difference, and then divides it by the fee denominator. This is the imbalance fee that will be charged for each token. Looking at this equation, let's imagine the case that we added liquidity so that the difference will be equal to zero. This will mean that the `new_balances` is exactly equal to the ideal balance. And when we execute this part of the equation, we see that the difference will be equal to zero. So, the fee for adding liquidity, in this case, the fee will be equal to zero. The next part of the code is to update the balance of the tokens. The balance of tokens will be the new balance and then a fraction of the imbalance fee will be given to the admin. This is what this part of the code is doing: Take the imbalance fee multiplied by some ratio which are given to the admin. Here, admin means the owner of this contract. And then, from this `new_balances`, we minus the fees, and using this `new_balances`, we calculate the liquidity again, D2. And the last part of the code is to mint LP based on the increase from D0 to D2. And you can see this over here. `token_supply` multiplied by D2 minus D0. That's the difference between D2 and D0, and then divided by D0. And then, it checks that this LP amount is greater than the `min_mint_amount` specified by the user. And then, it actually mints the LP tokens. So, that is the function `add_liquidity`.
The function add_liquidity is called to add tokens into Curve V1's AMM. For the inputs, it's going to take in the amount of coins to put in and the minimum amount of LP token to mint. min_mint_amount.
Next, it initializes some variables: fees is an array that will be used later for imbalance fee. Curve V1 allows you to add liquidity in a way that makes the token balances imbalanced. For example, you can decide to put only one token in, or you can decide to put all tokens in. And when you add one token as liquidity, this will make the current pool balance imbalanced. So that is what this fees array is used for. We'll come back to this later.
Next, we have a variable called _fee. This number is used to charge for an imbalance fee. If you take a look at this, it has a weird formula: fee * N_COINS / (4 * (N_COINS - 1)). Basically, what this does is it makes sure that when you add liquidity, and then remove liquidity, it won't be like swapping tokens without any swap fee. Let me explain this further. Let's say that we have token X, and then we swap, and then we get back token Y. In this case, we will have a swap fee on token Y.
Now, in Curve V1, we can also add liquidity in such a way that makes the token balances of the pool imbalanced. For example, we can decide only to add one token. So, let's say that we add X token to the pool. X token add liquidity. Now, Curve V1 also allows us to remove liquidity in such a way that makes the token balances of the pool imbalanced. So, for example, after we had only one token as liquidity, let's say that we remove liquidity, and we remove liquidity in another coin. Say remove liquidity, and we request token Y out. So effectively, what we did here was we put in X token and then, we took out token Y. This is the same as swapping token X for token Y.
Now, if we do not have fee on imbalance fee when we're adding liquidity, Basically, this allows us to swap tokens for free. And to make sure that this does not happen, this weird equation makes sure that when we add liquidity and then remove liquidity, it is basically like a swap. For the math for how to derive this part of the equation, I'll put a link in the course. So, that's what this fee is used for. And then we get the admin fee and then calculate the _A.
Next, we get the token_supply. This will be the total supply of LP tokens that are minted. And then, we first calculate liquidity D0. D0 will be the liquidity before we add any tokens into this pool. And we can see this over here. D0 is equal to get_D_mem(old_balances, amp). old_balances are the token balances of this pool. And then, we initialize an array called new_balances, which is basically copying the old balances. Then, the next part of the code deals with transferring in the tokens. So, scrolling down, we can see that inside the for loop, we get the coins to put in as liquidity. And then, we call the function transferFrom. And notice that here we're using raw_call. This is to go around the problem that USDT does not return any Boolean when transferFrom is called. If you were to use the ERC20 interface for transferFrom, when we call transferFrom on USDT, this part of the code will fail. So, to avoid this problem, it's using a raw_call to call transferFrom. So, for each iteration, it's going to transfer the tokens in. And then, it updates this new_balances. Remember, this new_balances was initialized as old_balances. So, to the old balances, we add some amount, the amount that came in. And with this new_balances, next we calculate the D again. This time it is called D1. Again, this D represents liquidity. We added some new tokens. And here, what it's doing is it's asking: with this new_balances, what is the new liquidity. The next part of the code is calculating the imbalance fee. Imbalance fee basically means that if we were to add tokens into this pool in such a way that does not change the token balance ratios, then we've added tokens in an ideal way. Otherwise, if the ratios of the token change when we had liquidity, then there is some kind of fee that we will have to pay. So, the first question is: well, what is the ideal balance to add as liquidity? And the answer is simple. We take the old_balances and we look at D0. This will be the liquidity before adding liquidity, and then D1, this will be the liquidity after adding liquidity. D1 divided by D0 will be the increase in liquidity. So, the old balance should increase by this much amount, D1 divided by D0. As an example, let's say that D1 is 110. D0 is 100. So, D1 divided by D0, so the ideal new balance will be 1.1 times the old balance.
Next, we calculate how much the new balance is off from this ideal balance. If the ideal balance is greater than new_balances of I, then the difference is ideal balance minus new_balances of I. Otherwise, it's the opposite: new_balances of I minus ideal balance. Here, we're just getting the difference of ideal balance and new_balances of I. And then, fees will be equal to this magic number fee that we saw over here, and then multiplies it by the difference, and then divides it by the fee denominator. This is the imbalance fee that will be charged for each token. Looking at this equation, let's imagine the case that we added liquidity so that the difference will be equal to zero. This will mean that the new_balances is exactly equal to the ideal balance. And when we execute this part of the equation, we see that the difference will be equal to zero. So, the fee for adding liquidity, in this case, the fee will be equal to zero.
The next part of the code is to update the balance of the tokens. The balance of tokens will be the new balance and then a fraction of the imbalance fee will be given to the admin. This is what this part of the code is doing: Take the imbalance fee multiplied by some ratio which are given to the admin. Here, admin means the owner of this contract. And then, from this new_balances, we minus the fees, and using this new_balances, we calculate the liquidity again, D2. And the last part of the code is to mint LP based on the increase from D0 to D2. And you can see this over here. token_supply multiplied by D2 minus D0. That's the difference between D2 and D0, and then divided by D0. And then, it checks that this LP amount is greater than the min_mint_amount specified by the user. And then, it actually mints the LP tokens. So, that is the function add_liquidity.
A detailed breakdown of Curve B1's add liquidity function - The lesson covers the inputs, fees, and how the function determines the amount of LP tokens to mint based on the change in liquidity.
Previous lesson
Previous
Next lesson
Next
Course Overview
About the course
AMM math for Curve Stableswap
How to calculate swap amount and liquidity
Curve Stableswap contracts
How to implement a swap function
How to implement the add and remove liquidity functions
How to quantify liquidity pools
How to control the flatness of the curve
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Blockchain Financial Analyst
$100,000 - $150,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Last updated on January 12, 2026
Duration: 14min
Duration: 33min
Duration: 27min
Duration: 23min
Duration: 21min
Duration: 23min
Course Overview
About the course
AMM math for Curve Stableswap
How to calculate swap amount and liquidity
Curve Stableswap contracts
How to implement a swap function
How to implement the add and remove liquidity functions
How to quantify liquidity pools
How to control the flatness of the curve
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Blockchain Financial Analyst
$100,000 - $150,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Last updated on January 12, 2026