QuantAMM

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

Incorrect fee state variable usage in UpdateWeightRunner contract

Summary

The UpdateWeightRunner contract contains a critical vulnerability where the setQuantAMMUpliftFeeTake function incorrectly updates the quantAMMSwapFeeTake state variable instead of maintaining a separate state variable for uplift fees. This causes swap fees and uplift fees to overwrite each other, leading to incorrect fee handling in the protocol.

Vulnerability Details

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

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

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; // Bug: Updates wrong state variable
emit UpliftFeeTakeSet(oldSwapFee, _quantAMMUpliftFeeTake);
}
function getQuantAMMUpliftFeeTake() external view returns (uint256) {
return quantAMMSwapFeeTake; // Bug: Returns wrong state variable
}

The contract uses the same state variable (quantAMMSwapFeeTake) for both swap fees and uplift fees, instead of maintaining separate state variables for each fee type. This causes:

  1. Uplift fee updates to overwrite swap fee values

  2. Incorrect fee retrieval through the getter function

  3. Misleading event emissions with incorrect old fee values

Impact

  1. Financial: Incorrect fee calculations and distributions

  2. Operational: Unexpected behavior when updating fees

  3. Transparency: Misleading event logs for fee changes

  4. Protocol Integrity: Compromised fee management system

Tools Used

Manual code review

Recommendations

  1. Add a separate state variable for uplift fees:

uint256 public quantAMMUpliftFeeTake = 0.5e18;
  1. Update the setter function:

function setQuantAMMUpliftFeeTake(uint256 _quantAMMUpliftFeeTake) external {
require(msg.sender == quantammAdmin, "ONLYADMIN");
require(_quantAMMUpliftFeeTake <= 1e18, "Uplift fee must be less than 100%");
uint256 oldUpliftFee = quantAMMUpliftFeeTake;
quantAMMUpliftFeeTake = _quantAMMUpliftFeeTake;
emit UpliftFeeTakeSet(oldUpliftFee, _quantAMMUpliftFeeTake);
}
  1. Update the getter function:

function getQuantAMMUpliftFeeTake() external view returns (uint256) {
return quantAMMUpliftFeeTake;
}
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!