DeFiFoundrySolidity
16,653 OP
View results
Submission Details
Severity: low
Invalid

Absence of Emergency Mode or Pause Mechanism

Description

The strategy contracts include methods like _emergencyWithdraw, but they lack an overarching “emergency mode” that can pause normal operations (e.g., _deployFunds, claimAndSwap). If an external dependency (such as the router or transmuter) is compromised, users and keepers might still call these functions, leading to additional losses or reverted transactions. An emergency or “pause” toggle would allow authorized entities to halt risky interactions promptly until the vulnerability is addressed.

  1. Additional Losses in a Live Attack

    • If the router is compromised or transmuter logic is broken, continuing normal swaps or deposits could exacerbate losses.

  2. Operational Chaos

    • Without a pause mechanism, the team must rely on external communication (e.g., “Don’t call these functions!”) or code changes that take time to deploy.

  3. Delayed Mitigation

    • Every minute of inaction during an exploit can result in more funds being drained or stuck.


Evidence from Code

No code segment provides a “pause” state check for critical operations:

function _deployFunds(uint256 _amount) internal override {
// No check if the strategy is paused or in emergency mode
transmuter.deposit(_amount, address(this));
}
function claimAndSwap(...) external onlyKeepers {
// Also no check to see if the function is disabled in an emergency
transmuter.claim(_amountClaim, address(this));
...
}

Potential Attack / Failure Scenario

  1. Router/Transmuter Exploit

    • Attackers find a flaw allowing them to siphon tokens upon any interaction with the compromised contract.

  2. Ongoing Calls

    • Users or keepers continue to call claimAndSwap or _deployFunds, unwittingly performing malicious transactions for the attacker.

  3. Extended Damage

    • Without an emergency pause, the protocol struggles to halt these interactions, magnifying losses.


Recommended Mitigations

  1. Add an Emergency/Pause Toggle

    • Implement a simple paused or emergencyMode boolean to block critical functions:

      bool public emergencyMode;
      modifier notPaused() {
      require(!emergencyMode, "Strategy is in emergency mode");
      _;
      }
      function setEmergencyMode(bool _status) external onlyEmergencyAuthorized {
      emergencyMode = _status;
      }
  2. Integrate This Check Into Critical Operations

    • For example:

      function _deployFunds(uint256 _amount) internal override notPaused {
      transmuter.deposit(_amount, address(this));
      }
      function claimAndSwap(...) external onlyKeepers notPaused {
      ...
      }
  3. Coordinate With _emergencyWithdraw

    • In emergency mode, keep normal deposits/swaps off-limits but allow _emergencyWithdraw to free up user funds safely without further exposures.

  4. Consider Timelocks or Multi-Sig

    • Control the setEmergencyMode function via timelocked governance or a multi-signature wallet for additional security.


Conclusion

Without an emergency pause mechanism, the protocol remains vulnerable to continued calls on compromised contracts during a crisis. Introducing a simple toggle to disable risk-sensitive logic dramatically improves the protocol’s ability to respond rapidly and contain damage in worst-case scenarios, providing both user protection and operational resilience.

Updates

Appeal created

inallhonesty Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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