QuantAMM

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

Negative Kappa Value Check Missing in DifferenceMomentumUpdateRule::validParameters

Summary

The DifferenceMomentumUpdateRule::validParameters function lacks a negative kappa value check when setting rules for a pool, which allows negative kappa values to be configured. Having a negative kappa value would impact the intended functionality of the strategy.

Vulnerability Details

In DifferenceMomentumUpdateRule::validParameters, there is a condition to validate kappa values by checking if they are `== 0`. However, this validation does not account for negative kappa values.

function validParameters() {
...
@> if (kappa[i] == 0) {
unchecked {
valid = 0;
}
}

Although only the pool creator can configure the rules and set kappa values, given the significant impact of allowing negative kappa values, it should be validated before rule-setting. Negative kappa values reverse the intended functionality of the momentum strategy, causing weightage adjustment in the opposite direction.

Proof of Concept

Add this in the QuantAMMWEightedPoolFactory.t.sol test file

Prepare create pool param

function _createPoolParams() internal returns (QuantAMMWeightedPoolFactory.NewPoolParams memory retParams) {
PoolRoleAccounts memory roleAccounts;
IERC20[] memory tokens = [address(dai), address(usdc)].toMemoryArray().asIERC20();
MockMomentumRule momentumRule = new MockMomentumRule(owner);
// deploys differenceMomentumUpdateRule
DifferenceMomentumUpdateRule differenceMomentumRule;
vm.startPrank(owner);
differenceMomentumRule = new DifferenceMomentumUpdateRule(address(updateWeightRunner));
vm.stopPrank();
uint32[] memory weights = new uint32[]();
weights[0] = uint32(uint256(0.5e18));
weights[1] = uint32(uint256(0.5e18));
int256[] memory initialWeights = new int256[]();
initialWeights[0] = 0.5e18;
initialWeights[1] = 0.5e18;
uint256[] memory initialWeightsUint = new uint256[]();
initialWeightsUint[0] = 0.5e18;
initialWeightsUint[1] = 0.5e18;
uint64[] memory lambdas = new uint64[]();
lambdas[0] = 0.2e18;
// Intialize parameters with 2 params
int256[][] memory parameters = new int256[][]();
// Setting negative kappa value
parameters[0] = new int256[]();
parameters[0][0] = -0.2e18;
// Second array for shortLambda (must be between 0 and 1)
parameters[1] = new int256[]();
parameters[1][0] = 0.2e18; // Valid shortLambda
address[][] memory oracles = new address[][]();
oracles[0] = new address[]();
oracles[0][0] = address(chainlinkOracle);
retParams = QuantAMMWeightedPoolFactory.NewPoolParams(
"Pool With Donation",
"PwD",
vault.buildTokenConfig(tokens),
initialWeightsUint,
roleAccounts,
MAX_SWAP_FEE_PERCENTAGE,
address(0),
true,
false, // Do not disable unbalanced add/remove liquidity
ZERO_BYTES32,
initialWeights,
IQuantAMMWeightedPool.PoolSettings(
new IERC20[](2),
IUpdateRule(differenceMomentumRule), // Replace with differenceMomentumRule
oracles,
60,
lambdas,
0.2e18,
0.2e18,
0.2e18,
parameters,
address(0)
),
initialWeights,
initialWeights,
3600,
0,
new string[][]()
);
}

Test deploy pool with a negative kappa value

function test_negativeKappaInDifferenceMomentum() public {
// Create pool parameters with negative kappa
QuantAMMWeightedPoolFactory.NewPoolParams memory params = _createPoolParams();
// This should succeed as there's no check for negative kappa
(address pool, ) = quantAMMWeightedPoolFactory.create(params);
// Verify the pool was created
assertTrue(pool != address(0), "Pool should be created");
}

Test passed, indicating a pool using the Difference Momentum Rule can be deployed with a negative kappa value

Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 29.41ms (2.80ms CPU time)

Impact

Allowing negative kappa values disrupts the core functionality of the momentum strategy by reversing its effect.

Tools Used

  • Manual review

  • Foundry

Recommendations

Change the comparison operator from == to <= to include checks for negative value

function validParameters() {
...
- if (kappa[i] == 0) {
+ if (kappa[I] <= 0) {
unchecked {
valid = 0;
}
}
Updates

Lead Judging Commences

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

invalid_weights_can_be_negative_or_extreme_values

_clampWeights will check that these weights are positive and in the boundaries before writing them in storage.

Support

FAQs

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

Give us feedback!