Summary
The getInputAmountBasedOnOutput function incorrectly uses a fee factor of 10000 instead of the intended 1000 when calculating the input amount required to obtain a specific output amount. This discrepancy can lead to significant overestimation of the required input amount, causing users to provide more input tokens than necessary.
Vulnerability Details
In automated market makers (AMMs) like Uniswap, the correct fee factor is typically derived from the transaction fee structure. For example, with a 0.3% fee, the correct multiplier would be 997 out of 1000. Using a factor of 10000 instead of 1000 significantly distorts the input amount calculations.
function getInputAmountBasedOnOutput(
uint256 outputAmount,
uint256 inputReserves,
uint256 outputReserves
)
public
pure
revertIfZero(outputAmount)
revertIfZero(outputReserves)
returns (uint256 inputAmount)
{
@> return (inputReserves * outputAmount * 10000) / ((outputReserves - outputAmount) * 997);
}
POC
function testFeeFactor() public {
vm.startPrank(liquidityProvider);
weth.approve(address(pool), 200e18);
poolToken.approve(address(pool), 200e18);
pool.deposit(100e18, 100e18, 100e18, uint64(block.timestamp));
assertEq(pool.balanceOf(liquidityProvider), 100e18);
assertEq(weth.balanceOf(liquidityProvider), 100e18);
assertEq(poolToken.balanceOf(liquidityProvider), 100e18);
assertEq(weth.balanceOf(address(pool)), 100e18);
assertEq(poolToken.balanceOf(address(pool)), 100e18);
pool.deposit(100e18, 100e18, 100e18, uint64(block.timestamp));
assertEq(pool.balanceOf(liquidityProvider), 200e18);
assertEq(weth.balanceOf(liquidityProvider), 0);
uint256 expected =
pool.getInputAmountBasedOnOutput(10e18, weth.balanceOf(address(pool)), poolToken.balanceOf(address(pool)));
assert(expected <= 10e18);
vm.stopPrank();
}
Impact
User Overpayment: Users will overpay for their trades, resulting in a much less favorable exchange rate.
Market Inefficiency: The incorrect calculations can lead to substantial inefficiencies in the liquidity pool, affecting the overall trading experience.
Tools Used
Manual Review
Recommendations
Correct Fee Factor: Update the getInputAmountBasedOnOutput function to use the correct fee factor of 1000 instead of 10000.
Review and Testing: Conduct thorough reviews and tests of all functions that involve fee calculations to ensure accuracy.
function getInputAmountBasedOnOutput(
uint256 outputAmount,
uint256 inputReserves,
uint256 outputReserves
)
public
pure
revertIfZero(outputAmount)
revertIfZero(outputReserves)
returns (uint256 inputAmount)
{
- return (inputReserves * outputAmount * 10000) / ((outputReserves - outputAmount) * 997);
+ return (inputReserves * outputAmount * 1000) / ((outputReserves - outputAmount) * 997);
}