Variables
MINIMUM_LIQUIDITY
MINIMUM_LIQUIDITY
is the minimum amount of liquidity burned at first liquidity provision.
SELECTOR
ABI selector for transfer
function.
kLast
kLast
is value of reserve0
* reserve1
. Uniswap keeps kLast
constant, and decides the exchange rate based on it.
Modifiers
Lock
Lock
modifier prevent functions from being called while they are running.(within the same transaction).
Function is called only when unlocked
is 1. While the function is running the value of unlocked
is 0.
Misc. Functions
getReserves (public)
Returns current reserve0
, reserve1
, blockTimestampLast
.
_safeTransfer (private)
Transfer value
of ERC20 tokens from the exchange to to
. SELECTOR
specifies that function we are calling is transfer(address,uint)
.
To avoid having to import an interface for the token function, we "manually" create the call using one of the ABI functions. ???
Events
Mint
When liquidity provider deposit liquidity.
Burn
When liquidity provider withdraw liquidity.
Swap
When trader swap tokens.
Sync
Provide latest reserve information, every tokens are added or withdrawn.
Setup Functions
constructor
Set factory
to the deployer of this contract.
initialize
Initialize the address of the two ERC-20 tokens that consist the pair. Only possible for factory
address.
Internal Update Functions
_update (private)
Called every time tokens are deposited or withdrawn.
- Measure
timeElapsed
which is time passed from last block timestamp and current one. -
Update the cumulative price of token1 and token2.
Cumulative price of token 0 += reserve1/reserve0 * timeElapsed
price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed; price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
Update new reserves and block timestamp.
_mintFee
0.05% of protocol fee may go to Uniswap if the factory choose to do it.
If factory
assigned feeTo
variable, 0.05% of fee goes to Uniswap.
address feeTo = IUniswapV2Factory(factory).feeTo();
feeOn = feeTo != address(0);
-
For gas saving, we access memory variable instead of storage variable.
uint _kLast = kLast; // gas savings
-
Liquidity tokens are calculated in following formula which is explained in whitepaper.
uint numerator = totalSupply.mul(rootK.sub(rootKLast)); uint denominator = rootK.mul(5).add(rootKLast); uint liquidity = numerator / denominator;
-
_mint
from UniswapV2ERC20 is used to create additional liquidity tokens and assign tofeeTo
address.
if (liquidity > 0) _mint(feeTo, liquidity);
External accessible functions
Still, it’s not recommended to call this functions; used periphery contract.
mint
Called when liquidity provide adds liquidity to the pool. It mints additional liquidity tokens as a reward.
-
We calculate how much is added by subtracting the reserves from balance of this address.
(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);
-
Calculate the protocol fee, if it exists. The parameter is based on old reserve values.
bool feeOn = _mintFee(_reserve0, _reserve1);
If it is the first deposit, create
MINIMUM_LIQUIDITY
tokens and send them to address zero to lock them. Initial liquidity is measured to square ofreserve0
*reserve1
.Liquidity token is minted based on the amount the liquidity provider provided relative to reserve.
_mint
is used.
burn
Called when liquidity is withdrawn and regarding liquidity tokens need to be burned. Should be called from periphery account.
swap
Swap token
-
What I don’t get it
{ // scope for reserve{0,1}Adjusted, avoids stack too deep errors uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3)); uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3)); require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'UniswapV2: K'); }
Top comments (0)