QuantAMM

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

The `UpdateWeightRunner::setRuleForPool` function is not restricted causing everybody can call it and change the states

Summary

The UpdateWeightRunner::setRuleForPool function is intended to be called only by pools during their creation. However, this function is defined as an external type without any restrictions, which means that anyone can call it.

Vulnerability Details

The QuantAMMWeightedPool::initialize function only be called when a new pool is created. Within this function, there is a private method called QuantAMMWeightedPool::_setRule, which uses the UpdateWeightRunner::setRuleForPool function. This is the only approved way to use this method, and it should not be called separately. Calling UpdateWeightRunner::setRuleForPool directly will modify the state variables: poolOracles, poolBackupOracles, rules, and poolRuleSettings.

Impact

  • Since there are getter functions for all the poolOracles, poolBackupOracles, rules, and poolRuleSettings variables, a malicious user could create a fake pool, then call UpdateWeightRunner::setRuleForPool and use the getter functions to falsely validate this fake pool for certain target users, potentially exploiting them through other functions.

  • everybody could even call performUpdate function for the fake pool without any restriction.

Tools Used

Manual review

Recommendations

  • All weighted pools are originated from creation functions in the QuantAMMWeightedPoolFactory contract. So set the address of this contract in UpdateWeightRunner :

+ address poolFactoryAddr;
+ function setPoolFactoryAddr(address _poolFactoryAddr) external {
+ require(msg.sender == quantammAdmin, "ONLYADMIN");
+ poolFactoryAddr = _poolFactoryAddr;
+ }
  • Then check the factory address with tx.origin in UpdateWeightRunner::setRuleForPool function:

function setRuleForPool(IQuantAMMWeightedPool.PoolSettings memory _poolSettings) external {
+ require(tx.origin == poolFactoryAddr, "Pool not originated from pool factory");
require(address(rules[msg.sender]) == address(0), "Rule already set");
require(_poolSettings.oracles.length > 0, "Empty oracles array");
require(poolOracles[msg.sender].length == 0, "pool rule already set");
...
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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