QuantAMM

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

Unprotected External Calls to UpdateWeightRunner

Summary

The QuantAMMWeightedPool contract initializes the UpdateWeightRunner instance without verifying its authenticity or admin control. An attacker can deploy a malicious UpdateWeightRunner contract and gain unauthorized control over the pool’s weight updates, potentially manipulating token swaps and draining liquidity.

Vulnerability Details

Issue: Unprotected External Calls to UpdateWeightRunner

updateWeightRunner = UpdateWeightRunner(params.updateWeightRunner);
quantammAdmin = updateWeightRunner.quantammAdmin();
  • The contract blindly assigns params.updateWeightRunner as the UpdateWeightRunner instance.

  • There is no verification to check if this contract is trusted or deployed by a legitimate admin.

  • This allows an attacker to deploy a malicious UpdateWeightRunner that returns a fake quantammAdmin, granting full admin control over the pool.

Exploit Scenario:

  1. Attacker deploys a fake UpdateWeightRunner contract.

  2. Sets quantammAdmin to attacker’s wallet.

  3. Deploys QuantAMMWeightedPool using the fake runner.

  4. Calls setUpdateWeightRunnerAddress() to replace the real runner with an attacker-controlled contract.

  5. Manipulates weight calculations and pool liquidity.

Example Malicious UpdateWeightRunner Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract FakeUpdateWeightRunner {
address public quantammAdmin;
constructor() {
quantammAdmin = msg.sender; // Attacker becomes the admin
}
function setWeights(int256[] calldata, address, uint40) external {
// Malicious function to modify pool weights
}
}

Impact

  • Full Admin Takeover: The attacker can arbitrarily change pool weights, affecting swaps.

  • Price Manipulation: The attacker can control token ratios, enabling unfair arbitrage.

  • Potential Liquidity Drain: If weight updates allow underpriced swaps, liquidity providers lose funds.

Proof of Concept (PoC)

Attack Steps

1️⃣ Deploy the FakeUpdateWeightRunner contract.
2️⃣ Deploy QuantAMMWeightedPool using the malicious runner’s address.
3️⃣ Replace updateWeightRunner using setUpdateWeightRunnerAddress().
4️⃣ Manipulate pool weights to favor the attacker.

function testAdminTakeover() public {
// Deploy the attack contract
FakeUpdateWeightRunner fakeRunner = new FakeUpdateWeightRunner();
// Deploy QuantAMMWeightedPool with the fake runner
QuantAMMWeightedPool pool = new QuantAMMWeightedPool(params, IVault(mockVault));
// Set the malicious runner in the pool
pool.setUpdateWeightRunnerAddress(address(fakeRunner));
// Verify attacker has admin control
assertEq(pool.quantammAdmin(), address(attacker), "Admin takeover failed!");
}

Tools Used

  • Foundry (forge test) for testing unauthorized admin changes.

  • Slither (slither . --detect access-control) for static analysis.

  • Mythril for symbolic execution and logic flow detection.

Recommendations

Verify UpdateWeightRunner Before Assigning

  • Ensure updateWeightRunner is from a trusted source.

require(updateWeightRunner.quantammAdmin() == expectedAdmin, "Invalid weight runner admin");

Restrict setUpdateWeightRunnerAddress() to Admins

  • Only pre-approved addresses should modify the runner.

function setUpdateWeightRunnerAddress(address _updateWeightRunner) external onlyAdmin {

Use Immutable Admin Control

  • Define an immutable trustedAdmin during deployment.

    address immutable trustedAdmin;
    constructor(address _admin) {
    trustedAdmin = _admin;
    }
Updates

Lead Judging Commences

n0kto Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
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!