When reserve == 0, amountIn for all the tokens will be set to the same amount: ratio, regardless of the weights, decimals and market prices of the assets.
The first liquidity provider may not be aware of this so that it may create an arbitrage opportunity for flashbots to take a significant portion of the value of The first liquidity provider's liquidity.
/// @dev Mints LP tokens - should be called via the router after transferring `bento` tokens.
/// The router must ensure that sufficient LP tokens are minted by using the return value.
function mint(bytes calldata data) public override lock returns (uint256 liquidity) {
(address recipient, uint256 toMint) = abi.decode(data, (address, uint256));
uint120 ratio = uint120(_div(toMint, totalSupply));
for (uint256 i = 0; i < tokens.length; i++) {
address tokenIn = tokens[i];
uint120 reserve = records[tokenIn].reserve;
// @dev If token balance is '0', initialize with `ratio`.
uint120 amountIn = reserve != 0 ? uint120(_mul(ratio, reserve)) : ratio;
require(amountIn >= MIN_BALANCE, "MIN_BALANCE");
// @dev Check Trident router has sent `amountIn` for skim into pool.
unchecked {
// @dev This is safe from overflow - only logged amounts handled.
require(_balance(tokenIn) >= amountIn + reserve, "NOT_RECEIVED");
records[tokenIn].reserve += amountIn;
}
emit Mint(msg.sender, tokenIn, amountIn, recipient);
}
_mint(recipient, toMint);
liquidity = toMint;
}
Proof of Concept
Given:
A IndexPool of 99% USDT and 1% WBTC;
Alice is the first liquidity provider.
Alice transfers 1e18 WBTC and 1e18 USDT to mint 100e18 of liquidity;
Bob can use 100e18 USDT (~$100) to swap out most of the balance of WBTC.
Impact
A significant portion (>90% in the case above) of the user's funds can be lost due to arbitrage.
Recommendation
Consider allowing the first liquidity provider to use custom amountIn values for each token or always takes the MIN_BALANCE of each token.
Handle
WatchPug
Vulnerability details
When
reserve == 0
,amountIn
for all the tokens will be set to the same amount:ratio
, regardless of the weights, decimals and market prices of the assets.The first liquidity provider may not be aware of this so that it may create an arbitrage opportunity for flashbots to take a significant portion of the value of The first liquidity provider's liquidity.
https://github.com/sushiswap/trident/blob/6bd4c053b6213ffc612987eb565aa3813d5f0d13/contracts/pool/IndexPool.sol#L93-L105
Proof of Concept
Given:
Impact
A significant portion (>90% in the case above) of the user's funds can be lost due to arbitrage.
Recommendation
Consider allowing the first liquidity provider to use custom
amountIn
values for each token or always takes the MIN_BALANCE of each token.