Category: Coding Mistakes
Uniswap mint reverts when exactly one of the second token is owed
Low Severity
Low Impact
Low Likelihood
Description
When minting liquidity on a Uniswap V3 pool, the amount of tokens required are not transferred beforehand, but instead the Uniswap pool calls the uniswapV3MintCallback
callback and passes it the amount of tokens that need to be transferred. This callback is implemented as follows.
function uniswapV3MintCallback(uint256 amount0, uint256 amount1, bytes memory /*data*/) external {
if (msg.sender != pool) revert NotPool();
if (!minting) revert InvalidEntry();
if (amount0 > 0) IERC20Metadata(lpToken0).safeTransfer(pool, amount0);
if (amount1 > 1) IERC20Metadata(lpToken1).safeTransfer(pool, amount1);
minting = false;
}
In the case where amount1 = 1
, this would not transfer any token1 to the Uniswap pool, which would then make the minting of liquidity revert.
Impact
Minting of liquidity by _addLiquidity
can revert in a very rare edge case.
Recommendations
function uniswapV3MintCallback(uint256 amount0, uint256 amount1, bytes memory /*data*/) external {
if (msg.sender != pool) revert NotPool();
if (!minting) revert InvalidEntry();
if (amount0 > 0) IERC20Metadata(lpToken0).safeTransfer(pool, amount0);
- if (amount1 > 1) IERC20Metadata(lpToken1).safeTransfer(pool, amount1);
+ if (amount1 > 0) IERC20Metadata(lpToken1).safeTransfer(pool, amount1);
minting = false;
}
Remediation
This issue has been acknowledged by Beefy, and a fix was implemented in commit 78b20f76↗.