BriVault

First Flight #52
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

No pause mechanism in the vault

Root + Impact

Description

  • Normally, a vault should include a mechanism to pause deposits, withdrawals, or other critical operations in case of emergencies or detected vulnerabilities.

  • The contract currently does not have any pause or emergency stop functionality, leaving it fully operational even if a vulnerability is discovered, which could result in loss of funds or exploitation.

// Root cause in the codebase with @> marks to highlight the relevant section
pragma solidity ^0.8.0;
contract NoPauseVault {
mapping(address => uint256) public userShares;
function deposit(uint256 amount) external {
@> // no pause check here
@> userShares[msg.sender] += amount;
}
function withdraw(uint256 amount) external {
@> // no pause check here
@> require(userShares[msg.sender] >= amount);
@> userShares[msg.sender] -= amount;
@> payable(msg.sender).transfer(amount);
}
}

Risk

Likelihood:

  • Occurs whenever a vulnerability is discovered or unexpected behavior occurs, as there is no way to pause operations.

  • Occurs whenever deposits or withdrawals continue despite an exploit being detected, potentially amplifying losses.

Impact:

  • Impact 1: Users’ funds could be drained or manipulated without any way to halt operations.

  • Impact 2: Attackers can fully exploit vulnerabilities while the vault remains active, increasing the severity of potential losses.

Proof of Concept

The PoC shows that deposits and withdrawals can occur without restriction, even during an emergency or exploit. Without a pause mechanism, the vault cannot halt operations, leaving user funds exposed to potential loss.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract NoPausePoC {
NoPauseVault public vault;
constructor(NoPauseVault _vault) { vault = _vault; }
function depositAndWithdraw(uint256 amt) external {
vault.deposit(amt); // deposit continues normally
vault.withdraw(amt); // withdraw continues normally even if an issue exists
}
}

Recommended Mitigation

Explanation: Introduce a pause mechanism with a modifier that prevents deposits and withdrawals when activated. This allows the owner to halt operations in emergencies or during exploits to protect user funds.

+ bool public paused;
+
+ modifier whenNotPaused() {
+ require(!paused, "contract is paused");
+ _;
+ }
+
+ function setPaused(bool _paused) external /*onlyOwner*/ {
+ paused = _paused;
+ }
+
+ function deposit(uint256 amount) external whenNotPaused {
+ userShares[msg.sender] += amount;
+ }
+
+ function withdraw(uint256 amount) external whenNotPaused {
+ require(userShares[msg.sender] >= amount);
+ userShares[msg.sender] -= amount;
+ payable(msg.sender).transfer(amount);
+ }
Updates

Appeal created

bube Lead Judge 19 days ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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

Give us feedback!