5/5
The function that we will use to calculate the amount of tokens we will receive from a swap with a Curve B1 AMM is called `get_dy`. There is another function called `get_dy_underlying` that has the same purpose but behaves differently. The difference between these two functions makes sense when the tokens inside the pool contract are yield bearing. For example, for a three pool, the tokens are DAI, USDC, and USDT. If you were to hold these tokens, they would not give you any yield. In this case, calling the functions `get_dy` and `get_dy_underlying` will give you back the exact same amounts. Now, let's consider the case when the tokens inside the pool earn some kind of yield. For example, let's say we have the tokens DAI and cUSDC. The token cUSDC is a token that you get for depositing USDC into Compound. This token is yield bearing. If you were to hold on to this cUSDC over time, you will earn some interest. Let's say you wanted to find out how much USDC you will get for putting in DAI. The pool tokens are DAI and cUSDC. In this case, to answer the question of how much USDC we will get for putting in DAI, we will call the function `get_dy_underlying`. This function will calculate how much USDC we will get if we were to put in DAI. For a stable swap three pool, the tokens are DAI, USDC, and USDT. The functions `get_dy_underlying` and `get_dy` are the same. Let's take a look at the function `get_dy`. As input, it's going to take the index of the token in and the index of the token out, and the amount of tokens you are going to put in, dx. Then, it calculates the amount of tokens that the AMM will give you back. First, it gets the rates. Remember for this stable swap three pool, the rates are a fixed number of 1e18, 1e30, and 1e30. Next, it gets the token balances, which are normalized to all have 18 decimals. The tokens are DAI, USDC, and USDT. DAI has 18 decimals, but USDC and USDT have six decimals. By calling this function, all of the token balances are normalized with 18 decimals. The next part of the code calculates the amount of tokens that will come out, and the fees on tokens out. ```javascript def get_dy(i: int128, j: int128, dx: uint256) -> uint256: # dx and dy in c-units rates: uint256[N_COINS] = RATES xp: uint256[N_COINS] = self.xp() x: uint256 = xp[i] + (dx * rates[i]) // PRECISION y: uint256 = self.get_y(i, j, x, xp) dy: uint256 = (xp[j] - y - 1) * PRECISION // rates[j] _fee: uint256 = self.fee * dy // FEE_DENOMINATOR return dy - _fee ``` The first part is adding the amount of token in to the current balance of token in, inside this pool. ```javascript x: uint256 = xp[i] + (dx * rates[i]) // PRECISION ``` This part normalizes the amount of token in to have 18 decimals. Next, it calculates the pool balance of token out, if we were to put in the dx amount of tokens into this pool. Remember that this function uses the Newton's method to calculate the new balance of token out. ```javascript y: uint256 = self.get_y(i, j, x, xp) ``` Since token is coming in, the balance of token out will decrease. Taking the difference of the current balance of token out, and the new balance of token out, accounting for rounding errors, we also minus one. Basically, this difference of the old balance of token out, minus the new balance of token out, is the calculation for the amount of token that will come out. This is named dy. ```javascript dy: uint256 = (xp[j] - y - 1) * PRECISION // rates[j] ``` A fraction of this dy will be kept inside the pool as swap fee. And this is calculated by taking some fraction of dy. ```javascript _fee: uint256 = self.fee * dy // FEE_DENOMINATOR ``` The actual amount of tokens that will come out is dy minus the fee. ```javascript return dy - _fee ``` So, that's the function `get_dy`.
The function that we will use to calculate the amount of tokens we will receive from a swap with a Curve B1 AMM is called get_dy
. There is another function called get_dy_underlying
that has the same purpose but behaves differently.
The difference between these two functions makes sense when the tokens inside the pool contract are yield bearing.
For example, for a three pool, the tokens are DAI, USDC, and USDT. If you were to hold these tokens, they would not give you any yield. In this case, calling the functions get_dy
and get_dy_underlying
will give you back the exact same amounts.
Now, let's consider the case when the tokens inside the pool earn some kind of yield. For example, let's say we have the tokens DAI and cUSDC. The token cUSDC is a token that you get for depositing USDC into Compound. This token is yield bearing. If you were to hold on to this cUSDC over time, you will earn some interest.
Let's say you wanted to find out how much USDC you will get for putting in DAI. The pool tokens are DAI and cUSDC. In this case, to answer the question of how much USDC we will get for putting in DAI, we will call the function get_dy_underlying
. This function will calculate how much USDC we will get if we were to put in DAI.
For a stable swap three pool, the tokens are DAI, USDC, and USDT. The functions get_dy_underlying
and get_dy
are the same.
Let's take a look at the function get_dy
. As input, it's going to take the index of the token in and the index of the token out, and the amount of tokens you are going to put in, dx. Then, it calculates the amount of tokens that the AMM will give you back.
First, it gets the rates. Remember for this stable swap three pool, the rates are a fixed number of 1e18, 1e30, and 1e30. Next, it gets the token balances, which are normalized to all have 18 decimals. The tokens are DAI, USDC, and USDT. DAI has 18 decimals, but USDC and USDT have six decimals. By calling this function, all of the token balances are normalized with 18 decimals.
The next part of the code calculates the amount of tokens that will come out, and the fees on tokens out.
The first part is adding the amount of token in to the current balance of token in, inside this pool.
This part normalizes the amount of token in to have 18 decimals. Next, it calculates the pool balance of token out, if we were to put in the dx amount of tokens into this pool. Remember that this function uses the Newton's method to calculate the new balance of token out.
Since token is coming in, the balance of token out will decrease. Taking the difference of the current balance of token out, and the new balance of token out, accounting for rounding errors, we also minus one. Basically, this difference of the old balance of token out, minus the new balance of token out, is the calculation for the amount of token that will come out. This is named dy.
A fraction of this dy will be kept inside the pool as swap fee. And this is calculated by taking some fraction of dy.
The actual amount of tokens that will come out is dy minus the fee.
So, that's the function get_dy
.
A detailed explanation of the get_dy function used in the Curve StableSwap3Pool.vy contract. This lesson covers how the function calculates the output amount of tokens for a given input amount, taking into account the token balances, rates, and swap fees.
Previous lesson
Previous
Next lesson
Next
Give us feedback
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 June 6, 2025
Duration: 14min
Duration: 32min
Duration: 26min
Duration: 23min
Duration: 20min
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 June 6, 2025