I'm learning how the Uniswapv2 contracts work but I can't seem to wrap my mind around the swap()
function.
Reference: https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2Pair.sol#L173
Lines 173-174 contain:
balance0 = IERC20(_token0).balanceOf(address(this));
balance1 = IERC20(_token1).balanceOf(address(this));
My question is, when & whose balances are these?
A. These are the same as _reserve0
& _reserve1
after the most recent swap and will be used to synchronize reserves.
B. These are the quantities of each token the user making the swap currently possesses.
C. None of the above. It's something else. Please explain the flow of this function. I cannot find a clear and concise definition anywhere.
answer is "C" :)
balanceOf
is a mapping in ERC20
implementation to return the amount that given address holds:
// address => holds uint amount
mapping(address => uint) public balanceOf;
Since current contract is inheriting from UniswapV2ERC20
:
contract UniswapV2Pair is IUniswapV2Pair, UniswapV2ERC20{}
it can access to UniswapV2ERC20.sol
Since the mapping balanceOf
is public, solidity assigns getters to the public variables
In the functions:
balance0 = IERC20(_token0).balanceOf(address(this));
balance1 = IERC20(_token1).balanceOf(address(this));
address(this)
refers to the current contract which is UniswapV2Pair
. So balance0
is how much the current contract owns _token0
and balance1
is how much the current contract address owns _token1
. token0
and token1
are contract addresses and each ERC20
token contract, keeps track of addresses and their balances. so you are visiting each token contract and getting how much balance the current contract has.
Think ERC20
contract like a bank. you have token0
bank and token1
bank. Each bank keeps track of the balances of their users. balancesOf
is where ERC20
tokens store those balances. Your current contract also owns some of those tokens so you just want to get how much tokens the current contract holds
swap
function will be called by the user. Before executing the swap, contract checks if it has enough funds
uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
require(amount0In > 0 || amount1In > 0, 'UniswapV2: INSUFFICIENT_INPUT_AMOUNT');