QuantAMM

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

Swap Fee and Uplift Fee share the same storage variable

Vulnerability Details

The UpdateWeightRunner contract incorrectly reuses the same storage variable (quantAMMSwapFeeTake) for both the “swap fee” and the “uplift fee.” Whenever setQuantAMMSwapFeeTake or setQuantAMMUpliftFeeTake is called, it overwrites the same variable, causing one fee configuration to replace the other.

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

function setQuantAMMSwapFeeTake(uint256 _quantAMMSwapFeeTake) external override {
require(msg.sender == quantammAdmin, "ONLYADMIN");
require(_quantAMMSwapFeeTake <= 1e18, "Swap fee must be less than 100%");
uint256 oldSwapFee = quantAMMSwapFeeTake;
@> quantAMMSwapFeeTake = _quantAMMSwapFeeTake;
emit SwapFeeTakeSet(oldSwapFee, _quantAMMSwapFeeTake);
}
function getQuantAMMSwapFeeTake() external view override returns (uint256) {
return quantAMMSwapFeeTake;
}
/// @notice Set the quantAMM uplift fee % amount allocated to the protocol for running costs
/// @param _quantAMMUpliftFeeTake The new uplift fee % amount allocated to the protocol for running costs
function setQuantAMMUpliftFeeTake(uint256 _quantAMMUpliftFeeTake) external{
require(msg.sender == quantammAdmin, "ONLYADMIN");
require(_quantAMMUpliftFeeTake <= 1e18, "Uplift fee must be less than 100%");
uint256 oldSwapFee = quantAMMSwapFeeTake;
@> quantAMMSwapFeeTake = _quantAMMUpliftFeeTake;
emit UpliftFeeTakeSet(oldSwapFee, _quantAMMUpliftFeeTake);
}

Notice in the interface that those variables represent different fees:

https://github.com/Cyfrin/2024-12-quantamm/blob/a775db4273eb36e7b4536c5b60207c9f17541b92/pkg/interfaces/contracts/pool-quantamm/IUpdateWeightRunner.sol#L131-L139

/// @notice Get the quantAMM swap fee % amount allocated to the protocol for running costs
function getQuantAMMSwapFeeTake() external view returns (uint256);
/// @notice Get the quantAMM uplift fee % amount allocated to the protocol for running costs
function getQuantAMMUpliftFeeTake() external view returns (uint256);

Take the following case as an example:

If the admin sets the swap fee to 0.3 (30%) and then sets the uplift fee to 0.4 (40%), the swap fee becomes 0.4 as well. Subsequent calculations for swap-based revenue or uplift-based revenue will be incorrect.

Impact

  • Admin cannot set two different fees: setting the uplift fee destroys the swap fee, and vice versa, causing critical fee miscalculations.

  • Protocol can become insolvent as stated in the interface above "% amount allocated to the protocol for running costs".

Tools Used

Manual Review

Recommendations

Declare two separate state variables, e.g.:

uint256 public quantAMMSwapFeeTake;
uint256 public quantAMMUpliftFeeTake;
  • Update the setters/getters so each fee is stored and retrieved from its own variable.

  • Ensure all logic that references either fee is updated accordingly.

Updates

Lead Judging Commences

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

finding_quantAMMSwapFeeTake==quantAMMUplfitFeeTake

Likelyhood: High, calling setters or getters Impact: Low/Medium, both getters return `quantAMMSwapFeeTake` and `setQuantAMMUpliftFeeTake` modify `quantAMMUplfitFeeTake`. Real impact: those 2 values will be always the same.

Support

FAQs

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

Give us feedback!