QuantAMM

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

Incorrect implementation of mask in `UpdateWeightRunner::_getData` function

Summary

The comment above the UpdateWeightRunner::MASK_POOL_GET_DATA variable states:

Mask to check if a pool is allowed to get data.

This means that the admin can decide whether a specific pool is allowed to retrieve data. Accessing data externally is acceptable since it doesn't impact the protocol. However, using incorrect checks here, leads to getting oracle data in a case that internalCall is true, regardless of the admin's permissions.

Vulnerability Details

Copy a test bellow in UpdateWeightRunner.sol . we expect test to revert, since getting data from oracle is not allowed but test fails to revert.

POC

function testUpdateRevertsWhenAdminBanGetData() public {
int256[] memory initialWeights = new int256[]();
initialWeights[0] = 0.0000000005e18;
initialWeights[1] = 0.0000000005e18;
initialWeights[2] = 0;
initialWeights[3] = 0;
// Set initial weights
mockPool.setInitialWeights(initialWeights);
mockPool.setPoolRegistry(57);
vm.startPrank(owner);
updateWeightRunner.setApprovedActionsForPool(address(mockPool), 57); // all actions approved minus GetData (32+16+8+2+1) - (2)
vm.stopPrank();
int216 fixedValue = 1000;
chainlinkOracle = deployOracle(fixedValue, 3601);
vm.startPrank(owner);
updateWeightRunner.addOracle(OracleWrapper(chainlinkOracle));
vm.stopPrank();
vm.startPrank(address(mockPool));
address[][] memory oracles = new address[][]();
oracles[0] = new address[]();
oracles[0][0] = address(chainlinkOracle);
uint64[] memory lambda = new uint64[]();
lambda[0] = 0.0000000005e18;
updateWeightRunner.setRuleForPool(
IQuantAMMWeightedPool.PoolSettings({
assets: new IERC20[](0),
rule: IUpdateRule(mockRule),
oracles: oracles,
updateInterval: 1,
lambda: lambda,
epsilonMax: 0.2e18,
absoluteWeightGuardRail: 0.2e18,
maxTradeSizeRatio: 0.2e18,
ruleParameters: new int256[][](),
poolManager: addr2
})
);
vm.stopPrank();
vm.startPrank(addr2);
updateWeightRunner.InitialisePoolLastRunTime(address(mockPool), 1);
vm.stopPrank();
vm.warp(block.timestamp + 10000000);
mockRule.CalculateNewWeights(
initialWeights,
new int256[](0),
address(mockPool),
new int256[][](),
new uint64[](0),
0.2e18,
0.2e18
);
vm.expectRevert("Not allowed to get data");
updateWeightRunner.performUpdate(address(mockPool));
}

Impact

Pools can get oracle data even admin ban it.

Tools Used

Manual review

Recommendations

function _getData(address _pool, bool internalCall) private view returns (int256[] memory outputData) {
- require(internalCall || (approvedPoolActions[_pool] & MASK_POOL_GET_DATA > 0), "Not allowed to get data");
+ if(internalCall){
+ require(approvedPoolActions[_pool] & MASK_POOL_GET_DATA > 0, "Not allowed to get data");
+ }
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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