BriVault

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

Incomplete access control on administrative functions

Root + Impact

Description

  • Normally, administrative functions such as setting the winner, finalizing deposits, or pausing the contract should be restricted to trusted addresses, typically the contract owner or a multisig.

  • The contract currently lacks strict access control on some administrative functions, allowing any user or attacker to call them, potentially taking control of critical operations.

// Root cause in the codebase with @> marks to highlight the relevant section
pragma solidity ^0.8.0;
contract AdminAccess {
uint256 public winnerTeam;
bool public paused;
function setWinner(uint256 teamId) external {
@> winnerTeam = teamId; // no access restriction
}
function setPaused(bool _paused) external {
@> paused = _paused; // no access restriction
}
}

Risk

Likelihood:

  • Occurs whenever a user or attacker calls functions that should be restricted, due to missing onlyOwner or access modifiers.

  • Occurs whenever the contract relies on administrative functions to maintain fair or secure operation, as anyone can override them.

Impact:

  • Impact 1: Attackers can arbitrarily set the winning team or pause/unpause the contract, compromising fairness and security.

  • Impact 2: Users’ funds and trust are at risk because critical operations can be hijacked by unauthorized parties.

Proof of Concept

The PoC shows that any user can call administrative functions like setWinner() or setPaused() because access control is missing. This allows unauthorized parties to hijack critical operations, compromise fairness, and put user funds at risk.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract AdminAccessPoC {
AdminAccess public vault;
constructor(AdminAccess _vault) { vault = _vault; }
function hijackWinner(uint256 teamId) external {
vault.setWinner(teamId); // called by anyone, not restricted
}
function hijackPause(bool state) external {
vault.setPaused(state); // called by anyone
}
}

Recommended Mitigation

Restrict all administrative functions using an onlyOwner modifier or multisig control to ensure only trusted parties can execute critical operations.

+ modifier onlyOwner() {
+ require(msg.sender == owner, "not owner");
+ _;
+ }
+
+ address public owner;
+
+ constructor() {
+ owner = msg.sender;
+ }
+
+ function setWinner(uint256 teamId) external onlyOwner {
+ winnerTeam = teamId;
+ }
+
+ function setPaused(bool _paused) external onlyOwner {
+ paused = _paused;
+ }
Updates

Appeal created

bube Lead Judge 19 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!