DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: low
Invalid

[H01] Improper Segregation of User & Protocol Funds (Admin-Controlled Treasury)

Summary

The PerpetualVault.sol contract allows the owner to set or change the treasury address via PerpetualVault.sol::setTreasury(), which lacks multi-signature control, a time delay, or on-chain tracking. This introduces a centralisation risk, as the owner (or a compromised admin) could redirect protocol funds to an attacker-controlled wallet.

Vulnerable code:

function setTreasury(address _treasury) external onlyOwner {
if (_treasury == address(0)) revert Error.ZeroValue();
treasury = _treasury;
}
  • Only the contract owner (onlyOwner) can update treasury, meaning one person has full control.

  • No event is emitted, making treasury updates difficult to track.

  • No time delay or governance process, allowing instant fund redirection.

Vulnerability Details

Current Security Checks

  • Access Control is enforced via onlyOwner, meaning only the contract owner can change the treasury.

  • The function requires \_treasury to be non-zero, preventing accidental null assignments:

if (_treasury == address(0)) revert Error.ZeroValue();

Remaining Issues & Exploitable Scenarios

While the above checks improve security, it does not fully prevent fund mismanagement.

  1. Admin Can Still Redirect Funds (Centralisation Risk)

  • The onlyOwner modifier does not prevent a malicious or compromised owner from setting treasury to an attacker-controlled address.

Example Exploit Path

vault.setTreasury(attackerAddress); // Owner sets treasury to attacker's wallet

If withdrawal fees or revenue-sharing rely on the treasury, fees can be siphoned away before users withdraw.

No Event Emitted (Lack of On-Chain Transparency)

  • The treasury can change at any time without on-chain tracking.

  • Users and security auditors won’t notice malicious treasury updates.

No Time-Locked Governance for Treasury Changes

  • Treasury updates happen immediately.

  • A rogue owner can change it, withdraw fees, and exit before users react.

Impact

  • Exit Scam Risk: A rogue admin can change the treasury, drain protocol fees, and disappear.

  • Lack of Transparency: Users cannot verify where fees are going in real-time.

  • Protocol Governance Bypass: No community oversight exists over treasury updates.

  • Centralised Control: Even if the owner is trusted, the lack of multi-sig security makes it a single point of failure.

  • Lack of User Protection: Users cannot veto or delay treasury changes.

Tools Used

From my professional background I had a hunch of potential issues that this and other DeFi protocols might have, I used OpenAI's GPT-4 to help explore the in-scope codebase.

Recommended Mitigation Steps

  1. Implement Multi-Signature Approval for Treasury Updates

    modifier onlyMultiSig() {
    require(isApprovedByMultisig(msg.sender), "Not multi-sig approved");
    _;
    }
  2. Emit an Event for Transparency

    event TreasuryUpdated(address indexed oldTreasury, address indexed newTreasury);
  3. Enforce a Delay on Treasury Changes

    • Prevent instant updates by adding a timelock (e.g., 24-hour delay).

    mapping(address => uint256) public pendingTreasury;
    uint256 public treasuryUpdateDelay = 1 days;
    function proposeTreasury(address _newTreasury) external onlyOwner {
    pendingTreasury[_newTreasury] = block.timestamp + treasuryUpdateDelay;
    }
    function executeTreasuryUpdate(address _newTreasury) external onlyOwner {
    require(block.timestamp >= pendingTreasury[_newTreasury], "Timelock active");
    treasury = _newTreasury;
    emit TreasuryUpdated(msg.sender, _newTreasury);
    }
Updates

Lead Judging Commences

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

Admin is trusted / Malicious keepers

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point. Keepers are added by the admin, there is no "malicious keeper" and if there is a problem in those keepers, that's out of scope. ReadMe and known issues states: " * System relies heavily on keeper for executing trades * Single keeper point of failure if not properly distributed * Malicious keeper could potentially front-run or delay transactions * Assume that Keeper will always have enough gas to execute transactions. There is a pay execution fee function, but the assumption should be that there's more than enough gas to cover transaction failures, retries, etc * There are two spot swap functionalies: (1) using GMX swap and (2) using Paraswap. We can assume that any swap failure will be retried until success. " " * Heavy dependency on GMX protocol functioning correctly * Owner can update GMX-related addresses * Changes in GMX protocol could impact system operations * We can assume that the GMX keeper won't misbehave, delay, or go offline. " "Issues related to GMX Keepers being DOS'd or losing functionality would be considered invalid."

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

Admin is trusted / Malicious keepers

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point. Keepers are added by the admin, there is no "malicious keeper" and if there is a problem in those keepers, that's out of scope. ReadMe and known issues states: " * System relies heavily on keeper for executing trades * Single keeper point of failure if not properly distributed * Malicious keeper could potentially front-run or delay transactions * Assume that Keeper will always have enough gas to execute transactions. There is a pay execution fee function, but the assumption should be that there's more than enough gas to cover transaction failures, retries, etc * There are two spot swap functionalies: (1) using GMX swap and (2) using Paraswap. We can assume that any swap failure will be retried until success. " " * Heavy dependency on GMX protocol functioning correctly * Owner can update GMX-related addresses * Changes in GMX protocol could impact system operations * We can assume that the GMX keeper won't misbehave, delay, or go offline. " "Issues related to GMX Keepers being DOS'd or losing functionality would be considered invalid."

Support

FAQs

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