QuantAMM

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

Swap and Uplift Fees Share the Same Variable .

Summary

In the UpdateWeightRunner contract both setQuantAMMSwapFeeTake() and setQuantAMMUpliftFeeTake() functions update the same state variable quantAMMSwapFeeTake. This leads to overwriting of values set by each. The onAfterSwap function of the UpliftOnlyExample contract tries to fetch uplift fee from the UpdateWeightRunner contract but due to the state variable collision, the fetched uplift fee might incorrectly reflect the fee, resulting in inaccurate adjustments to the protocal fee. This directly impacts the protocol's revenue and stability.

Vulnerability Details

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

The contract uses a single state variable; quantAMMSwapFeeTake for both swap and uplift fees.
The setQuantAMMSwapFeeTake Updates the swap fee and writes the value to the shared variable

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; ///@audit Updates shared variable
emit SwapFeeTakeSet(oldSwapFee, _quantAMMSwapFeeTake);
}

Similarly, setQuantAMMUpliftFeeTake Updates the uplift fee overwriting the same variable.

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; ///@audit Overwrites shared variable
emit UpliftFeeTakeSet(oldSwapFee, _quantAMMUpliftFeeTake);
}

In the onAfterSwap function of the UpliftOnlyExample contract, the uplift fee is fetched from the WeightRunner contract using the getQuantAMMUpliftFeeTake() function.

uint256 quantAMMFeeTake = IUpdateWeightRunner(_updateWeightRunner).getQuantAMMUpliftFeeTake();

However, since the quantAMMSwapFeeTake variable is shared, the returned uplift fee may incorrectly reflect the last uplift fee update

Impact

An improperly set quantAMMFeeTake results in inaccurate fee allocation between the adminFee for protocol operations and the Owner fee during swaps . This mismanagement can lead to incorrect adjustments during swaps causing financial imbalances and directly impacting the protocol's sustainability.

Tools Used

Manual review

Recommendations

Introduce Separate Variables; quantAMMSwapFeeTake to store the swap fee and quantAMMUpliftFeeTake to store the uplift fee.

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!