The UniswapV2Pair.sol
fails in the mint
method, called by the contract UniswapV2Router02.sol
during the addLiquidityETH
/addLiquidity
method. The problem is that the pair requires a small amount of balance of both tokens, such that a minimum amount of liquidity can be added.
In short, just transfer more than 1000 wei of each token to the pair address and addLiquidityETH
/addLiquidity
will work.
Longer version:
The failing line is marked with XXX
:
// this low-level function should be called from a contract which performs important safety checks
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) {
// XXX next line fails with ds-math-sub-underflow
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);
}
when deploying new tokens, their reserve is 0 and also the balance of the token held by the pair address is 0. This means in the above mint
function, the variables amount0
and amount1
are also 0.
But sqrt(amount0 * amount1) - MINIMUM_LIQUIDITY > 0
, otherwise one gets that ds-math-sub-underflow
error.
With MINIMUM_LIQUIDITY = 10**3
and amount0 * amount1 > MINIMUM_LIQUIDITY**2
, one can calculate that this requirement is fulfilled when the pair address holds just more of 1000 wei of each token.
Hello Team Have Finally Resolved It
One Has To First
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [market.address],
});
Then Get The Signer Using the Following
const signer = await ethers.getSigner(market.address);
One Can Then Use the Signer In The Connect Of The Contract Call From Within Your Hardhat Test
await media.connect(signer).functionName(1,addr2.address);
and end impersonating the contract using the following
await hre.network.provider.request({
method: "hardhat_stopImpersonatingAccount",
params: [market.address],
});
I Hope This Can Help Anyone Else Facing this Issue
Thank You
Best Answer
@ethersproject/address
provides agetContractAddress()
function to find future deployment address.