BriVault

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

Owner can set winner before or manipulate winner shares

Root + Impact

Description

  • Normal behavior:
    Owner sets the winning team after the event ends, and winning users receive proportional rewards.


  • Specific issue:

    The setWinner() function relies entirely on the owner:

// Root cause in the codebase with @> marks to highlight the relevant section
@> function setWinner(uint256 countryIndex) public onlyOwner returns (string memory) {
@> if (block.timestamp <= eventEndDate) { revert eventNotEnded(); }
@> ...
@> _getWinnerShares();
@> _setFinallizedVaultBalance();
@> }

Risk

Likelihood:

  • This occurs whenever the owner is malicious, compromised, or coerced, allowing them to set the winner to any team.

This also occurs if the owner accidentally calls setWinner() with the wrong index or before proper event finalization, due to lack of checks beyond onlyOwner and the timestamp check.

Impact:

  • Owner can steal all staked tokens by falsely setting the winner.

Winning users receive 0 payout or incorrect amounts.

Proof of Concept

Explanation:
If the owner is malicious or compromised, setWinner allows them to choose any team, potentially giving themselves (or nobody) all the rewards.

contract VaultAttack {
function cheatWinner(BriVault vault, uint256 fakeWinner) external {
// Exploit: owner calls setWinner with manipulated index
vault.setWinner(fakeWinner);
}
}

Recommended Mitigation

Short explanation:

  • Use time locks or multi-sig governance to set the winner.

  • Optionally, allow off-chain reporting with signed proofs or commit-reveal to avoid single-point manipulation.

  • Introduce onlyAfter(uint256 timestamp) modifier

Replace single-owner control with multisig or DAO voting

- remove this code
+ add this code
- function setWinner(uint256 countryIndex) public onlyOwner returns (string memory) {
+ function setWinner(uint256 countryIndex) public onlyOwner onlyAfter(eventEndDate) onlyMultisig returns (string memory) {
Updates

Appeal created

bube Lead Judge 19 days ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

The winner is set by the owner

This is owner action and the owner is assumed to be trusted and to provide correct input arguments.

Support

FAQs

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

Give us feedback!