QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: low
Invalid

Incorrect Calculation of `lpTokenDepositValue` in `addLiquidityProportional`

Summary

When a user deposits or adds liquidity using the addLiquidityProportional function, they receive an lpNFT, and corresponding data is stored in the poolsFeeData mapping. This data includes the token ID, amount, lpTokenDepositValue, blockTimestampDeposit, and upliftFeeBps.

However, the calculation of lpTokenDepositValue is incorrect. The value is currently calculated after liquidity is added, which can lead to inaccuracies in edge cases. Even though the liquidity is added proportionally, due to the muldown operation, the token values may differ before and after adding liquidity.

Proof of Code

The following test case demonstrates the issue:

function deployPriceCalculator() internal {\
mockPrice = new MockBptPrice();\
}
function testPrice(uint256\[] memory inputArray, uint256\[] memory prices, uint256 UnnoundedbptTotalSupply, uint256 bptAmountOut) public {\
deployPriceCalculator();
vm.assume(inputArray.length > 1);
vm.assume(prices.length > 8);
uint256 maxLength = 8;
uint256 boundedLength = bound(inputArray.length, 2, maxLength);
uint256[] memory balances = new uint256[]();
uint256[] memory pricesBounded = new uint256[]();
for (uint256 i = 0; i < boundedLength; i++) {
balances[i] = inputArray[i];
pricesBounded[i] = prices[i];
}
uint256 bptTotalSupply = bound(UnnoundedbptTotalSupply, 10e18, 1000e18);
bptAmountOut = bound(bptAmountOut, 1e18, 3e18);
for (uint256 i = 0; i < balances.length; i++) {
balances[i] = bound(balances[i], 100e18, 1000e18);
pricesBounded[i] = bound(pricesBounded[i], 1, 10000);
}
uint256 bptPriceBeforeAddingLiq = mockPrice.getPoolLPTokenValue(pricesBounded, balances, bptTotalSupply);
uint256[] memory amountsIn;
amountsIn = mockPrice.computeProportionalAmountsIn(balances, bptTotalSupply, bptAmountOut);
for (uint256 i = 0; i < amountsIn.length; i++) {
balances[i] = balances[i] + amountsIn[i];
}
bptTotalSupply += bptAmountOut;
uint256 bptPriceAfterAddingLiq = mockPrice.getPoolLPTokenValue(pricesBounded, balances, bptTotalSupply);
assertEq(bptPriceBeforeAddingLiq, bptPriceAfterAddingLiq);
}

The output demonstrates a mismatch in the values:

Output = 4889 != 4990

This discrepancy highlights that the price of lpToken changes before and after liquidity addition.

Vulnerability Details

The calculation of lpTokenDepositValue after adding liquidity leads to incorrect values being stored in the poolsFeeData mapping.

Impact

  • Users are assigned incorrect lpTokenDepositValue, which may result in inaccurate fee calculations or discrepancies in system behavior.

Tools Used

Foundry Fuzzer

Recommendations

Calculate the value of the lpToken before adding the liquidity.

Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Informational or Gas / Admin is trusted / Pool creation is trusted / User mistake / Suppositions

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.