QuantAMM

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

Permission registry is spread over 2 different places and is used inconsistently

Summary

Permission checks in UpdateWeightRunner are split between two different sources without proper synchronization or hierarchy. Having different functions check different permission sources can lead to potential permission bypass or permanently disabled permissions.

Vulnerability Details

The contract alternates between two different sources for permission checks:

  1. Pool's immutable poolRegistry:

    function setWeightsManually(...) external {
    uint256 poolRegistryEntry = QuantAMMWeightedPool(_poolAddress).poolRegistry();
    if (poolRegistryEntry & MASK_POOL_OWNER_UPDATES > 0) {
    // ...
    }
  2. Own mutable storage map approvedPoolActions:

    function performUpdate(address _pool) public {
    // ...
    uint256 poolRegistryEntry = approvedPoolActions[_pool];
    if (poolRegistryEntry & MASK_POOL_PERFORM_UPDATE > 0) {
    // ...
    }

There is no obvious reason why 2 different sources for pool registry would be used. Same action masks are sometimes checked in approvedPoolActions and sometimes in poolRegistry.

Here's the list of functions that check action masks using pool's poolRegistry:

  • setWeightsManually() -> MASK_POOL_OWNER_UPDATES and MASK_POOL_QUANTAMM_ADMIN_UPDATES

  • calculateMultiplierAndSetWeightsFromRule() -> MASK_POOL_RULE_DIRECT_SET_WEIGHT

QuantAMMWeightedPool's poolRegistry is immutable and is set by deployer at the deployment time, cannot be modified.

And here's the list of functions checking action masks using approvedPoolActions mapping:

  • performUpdate() -> MASK_POOL_PERFORM_UPDATE

  • getData() -> MASK_POOL_GET_DATA

  • setIntermediateValuesManually() -> MASK_POOL_OWNER_UPDATES and MASK_POOL_QUANTAMM_ADMIN_UPDATES

  • InitialisePoolLastRunTime() -> MASK_POOL_OWNER_UPDATES and MASK_POOL_QUANTAMM_ADMIN_UPDATES

UpdateWeightRunner's approvedPoolActions can be set and modified at any time by admin doing the setApprovedActionsForPool call.

Impact

This design inconsistency can lead to a quite some permission issues. Some examples:

  • Deployer deploys pool with no MASK_POOL_OWNER_UPDATES action enabled, thinking this will be the permenant immutable config. However admin enables MASK_POOL_OWNER_UPDATES using setApprovedActionsForPool call and in that way enables pool manager to set intermediate values and last run time manually (but can't set weight manually)

  • Admin enables MASK_POOL_QUANTAMM_ADMIN_UPDATES action in order to be able to set weights manually in the emergency situation. However, even though MASK_POOL_QUANTAMM_ADMIN_UPDATES is successfully set, admin's calls to setWeightsManually fail because that function looks only into immutable registry set by deployer where this action is not enabled

In latter case there is no way to ever set weights manually, making breakglass function unusable. I consider this to be medium risk vulnerability.

Tools Used

Manual code review

Recommendations

Use a single source of truth for permissions, which is mutable by admin.

Updates

Lead Judging Commences

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

Informational or Gas / Admin is trusted / Pool creation is trusted / User mistake / Suppositions

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Appeal created

goran Submitter
10 months ago
n0kto Lead Judge
10 months ago
n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Design choice
Assigned finding tags:

Informational or Gas / Admin is trusted / Pool creation is trusted / User mistake / Suppositions

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelyhood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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

Give us feedback!