Can anyone explain to me what I fail to understand/misunderstand when reading the mint function of the UniswapV2Pair.sol contract after the addLiqudity function of the UniswapV2Router.sol initiates a call to it:
This is the addLiquidity function of the UniswapV2Router.sol contract:
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
(amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);
TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
liquidity = IUniswapV2Pair(pair).mint(to);
}
Once the amounts to be deposited have been calculated, the TransferHelper, at the end using the .safeTransferFrom transfers amountA and B from depositors address to the exchange pair address.
For examples sake let's say transferred amount turns out to be:
amountA = 50 amountB = 50
and say that this 50 / 50 is deposited to a pool with an existing 100 / 100 amounting to 150 / 150 in total after the transfer.
This is followed by a call to mint liquidity tokens which is ultimately implemented in the mint function in the UniswapV2Pair.sol contract as part of the agnostic transfer pattern.
This is the mint function of the UniswapV2Pair.sol contract:
function mint(address to) external lock returns (uint liquidity) {
(uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
uint balance0 = IERC20(token0).balanceOf(address(this));
uint balance1 = IERC20(token1).balanceOf(address(this));
uint amount0 = balance0.sub(_reserve0);
uint amount1 = balance1.sub(_reserve1);
bool feeOn = _mintFee(_reserve0, _reserve1);
uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
if (_totalSupply == 0) {
liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
} else {
liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
}
require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
_mint(to, liquidity);
_update(balance0, balance1, _reserve0, _reserve1);
if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
emit Mint(msg.sender, amount0, amount1);
}
MY ISSUE/QUESTION:
concerns how amount0 and amount1 is calculated:
When .getReserves(...) is called in the mint function, it retrieves:
_reserve0 = 150
_reserve1 = 150
(these are the total reserves of both tokens in the exchange pair after deposit of 50/50 has been received to that original 100/100. no timeStamp included)
Since .balanceOf gets the total balance of token0 and token1 of the exchange pair address which would each be 150
to find amounts = balance - _reserves, which essentially would be 150 - 150
Then how can amount0 and amount1 ever equal 50?
I obviously understand that my understanding is flawed. Where am I going wrong?
Can anyone savvy help clarify.