HardhatDeFi
15,000 USDC
View results
Submission Details
Severity: medium
Invalid

Lack of Emergency Pause Mechanism

Summary

The protocol does not implement a mechanism to pause critical functionality during emergencies. This could prevent the team from responding quickly to attacks or other unforeseen issues in contracts AaveDIVAWrapper.sol and IAave.sol for both supply, withdraw , or the interaction with reserves..

Vulnerability Details

Core functions, such as batchRemoveLiquidity line 138 and batchRegisterCollateralToken on line 100, can be exploited continuously during an attack without any way to halt the system.

Example:
If a reentrancy or token manipulation attack occurs, the protocol cannot pause operations to prevent further damage.

Impact

Medium Impact:

  • Indirect Risk to Funds: While funds may not be directly at risk, the inability to halt operations could exacerbate ongoing attacks.

  • Reputation Damage: Lack of emergency mechanisms could erode user trust during an incident.

Proof of Concept

Overview

The protocol lacks an emergency pause mechanism, preventing the team from stopping critical operations if an attack is detected.

Actors

  • Attacker: Exploits a vulnerability (e.g., a pricing oracle manipulation) to drain liquidity.

  • Victim: Users unable to react quickly before their funds are impacted.

  • Protocol: Lacks a way to freeze operations to prevent further exploitation.

Exploit Scenerio

  1. Initial State: An attacker manipulates an oracle (or exploits a logic flaw) to create a favorable condition for liquidity extraction.

  2. Step 1: The attacker calls removeLiquidity or redeemPositionToken at an inflated value.

  3. Step 2: Without a pause mechanism, the attack continues without intervention.

  4. Outcome: The protocol loses significant funds before a manual response is possible.

Working Test Case:

Smart Contract Without Pause Mechanism

// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
contract PoC_NoPauseMechanism {
mapping(bytes32 => uint256) public poolLiquidity;
bool public emergencyPaused = false; // This should exist but currently does not
function removeLiquidity(bytes32 _poolId, uint256 _amount) external {
require(poolLiquidity[_poolId] >= _amount, "Not enough liquidity");
// Step 1: Attacker removes liquidity at inflated price
poolLiquidity[_poolId] -= _amount;
payable(msg.sender).transfer(_amount);
}
function redeemPositionToken(bytes32 _poolId, uint256 _amount) external {
require(poolLiquidity[_poolId] >= _amount, "Not enough collateral");
// Step 2: Attack continues unchecked
poolLiquidity[_poolId] -= _amount;
payable(msg.sender).transfer(_amount);
}
}

Implications

  • Significant financial loss: Attackers can continuously drain liquidity without a stopgap.

  • Trust erosion: Users may lose faith in the protocol’s security.

  • Operational delay: Manual intervention may not be fast enough.

Fix Recommendation

Implement an emergency pause mechanism, such as:

modifier whenNotPaused() {
require(!emergencyPaused, "Contract is paused");
_;
}
function pause() external onlyOwner {
emergencyPaused = true;
}
function unpause() external onlyOwner {
emergencyPaused = false;
}
function removeLiquidity(bytes32 _poolId, uint256 _amount) external whenNotPaused {
require(poolLiquidity[_poolId] >= _amount, "Not enough liquidity");
poolLiquidity[_poolId] -= _amount;
payable(msg.sender).transfer(_amount);
}

Outcome:

  • Funds are drained from the protocol.

Implications:

  • Severe financial losses and reputational damage.

Tools Used

Manual code review

Recommendations

Implement an emergency pause mechanism.

Fixed.

Updates

Lead Judging Commences

bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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