β SyncAndSkim
The test file creates a scenario where user transfers both tokens to pair "for free" (did not mint LP tokens). Two things we can do here, either sync or skim.
Sync: This is manual "force" update, the transferred tokens from user will be "merged" into pair accounting. Also sync()
can refresh price0Cumulativelast
and price1CumulativeLast
when twap oracle needs a snapshot: https://rareskills.io/post/twap-uniswap-v2

// force reserves to match balances
function sync() external lock {
_update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
}
Skim: This method lets you harvest all accidently transferred token from the pair. User is responsible to either swap or mint LP token within the same tx, if not, the transferred tokens will be arbitraged by anyone.
// force balances to match reserves
function skim(address to) external lock {
address _token0 = token0; // gas savings
address _token1 = token1; // gas savings
_safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));
_safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "./interfaces/IUniswapV2Pair.sol";
contract Sync {
/**
* SYNC EXERCISE
*
* AMPL token had a negative rebase, meaning there was reduction in supply by adjusting the
* balance among all holders including ETH/AMPL pool, allowing trades to receive sub-optimal rates.
* The challenge is to force reserves to match the current balances in the ETH/AMPL pool.
*
*/
function performSync(address pool) public {
// Call sync() to update reserves to match current token balances
IUniswapV2Pair(pool).sync();
}
}
contract Skim {
/**
* SKIM EXERCISE
*
* AMPL token had a positive rebase, meaning there was addition in supply by adjusting the
* balance among all holders including ETH/AMPL pool. Due to this addition, the pool balance
* overflows uint112 storage slot for reserves.
* The challange is to rectify this by forcing balances to match the reserves and sending the
* difference to this contract.
*
*/
function performSkim(address pool) public {
// Call skim() to remove excess tokens and send them to this contract
IUniswapV2Pair(pool).skim(address(this));
}
}
Last updated