QuantAMM

QuantAMM
49,600 OP
View results
Submission Details
Severity: high
Valid

Loss of precision leading to incorrect fee calculations in UpliftOnlyExample.onAfterSwap()

Summary

Currently the fee calculation in the swap hook is vulnerable to precision loss and can lead to incorrect admin and owner fees being distributed.

Vulnerability Details

The fee calculation in onAfterSwap will be impacted by a precision loss at the following operation: adminFee = hookFee / (1e18 / quantAMMFeeTake).

https://github.com/Cyfrin/2024-12-quantamm/blob/main/pkg/pool-hooks/contracts/hooks-quantamm/UpliftOnlyExample.sol#L335

The precision loss will be dependent on the value of quantAMMFeeTake. Since it can be updated by a setter function and it accepts any value below 1e18, the precision loss can happen in practice. Although it can be fixed by setting a new value, once the precision loss happen it's irreversible on the affected swaps.

https://github.com/Cyfrin/2024-12-quantamm/blob/main/pkg/pool-quantamm/contracts/UpdateWeightRunner.sol#L141-L148

Please note this precision loss issue was not reported by the bot report.

Numerical POC:

Assume:
quantAMMFeeTake = 0.3e18
amountsCalculatedRaw = 3000e18
hookSwapFeePercentage = 0.02e18
uint256 hookFee = params.amountCalculatedRaw.mulUp(hookSwapFeePercentage);
hookFee = 600e18
uint256 adminFee = hookFee / (1e18 / quantAMMFeeTake);
adminFee = 600e18 / (1e18 / 0.3e18)
adminFee = 600e18 / 3
adminFee = 200e18

If we multiply the numerator and denominator by 1e18 we would receive a more accurate result:

adminFee = hookFee * 1e18 / (1e18 * 1e18 / quantAMMFeeTake)
adminFee = 600e36 / (1e36 / 0.3e18)
adminFee = 600e36 / 3.333333333333333333e18
adminFee = 180e18

With the precision loss the adminFee would be 200e18 and the ownerFee would be 400e18.

Without the precision loss, the adminFee would be 180e18 and the ownerFee would be 420e18.

Therefore, in this example we can see a 20e18 in difference for the adminFee and ownerFee.

Impact

The consequence would be miscalculations of the fees received by the quant AMM and the pool.

As these calculations will be executed via the hook on every swap, the inaccuracies can accumulate over time.

The bigger the raw token amount calculated by the swap entered via the hook, the bigger the difference will be.

Tools Used

Manual review.

Recommendations

Multiply the numerator and the denominator by 1e18 to avoid the precision loss while calculating the adminFee:

uint256 adminFee = hookFee * 1e18 / (1e18 * 1e18 / quantAMMFeeTake)
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_onAfterSwap_adminFee_overestimated_solidity_rounding_down

Likelyhood: High, quantAMMFeeTake is a percentage on calculated fees. Being between 30-70% is very likely. Impact: High, fees for LP providers will be lower than expected and 0 if the admin fees is above 50%.

Support

FAQs

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

Give us feedback!