BriVault

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

deposit() allows deposits to continue after event starts

Root + Impact

Description

  • Normal behavior:
    Users should not be able to deposit tokens after the event starts, as this allows unfair entry once outcomes may already be predictable.

  • Specific issue:
    Although the contract has this check in deposit():if (block.timestamp >= eventStartDate) {
    revert eventStarted();
    }

    it is not sufficient because deposit() does not prevent deposits after the event has ended or after the winner is set.

// Root cause in the codebase with @> marks to highlight the relevant section
@ if (block.timestamp >= eventStartDate) {
revert eventStarted();
}

Risk

Likelihood:

  • This will occur when the contract owner delays calling setWinner(). During that gap, users can still call deposit() and joinEvent() to stake on teams after knowing outcomes.

It can also occur during testing or production if there’s a delay between event end and owner action, since deposit() does not lock once eventEndDate passes.

Impact:

  • Attackers or late users can deposit after the match or event and join the winning team before the winner is officially set by the owner.

These users can later withdraw and unfairly share the prize pool.

  • This leads to fund misallocation and loss of fairness in the vault distribution.

Proof of Concept

Goal: Deposit after the real-world outcome is known but before the owner calls setWinner(), then join the winning team to steal a share of the pool.
-Observe the real-world tournament result (team A wins).

  • Wait until eventEndDate passes (or use any misconfiguration where deposits are still allowed).

  • Call deposit(amount, attacker) to put funds into the vault after outcomes are known.

  • Call joinEvent(winnerId) to assign the new deposit to the winning team.

  • After the owner calls setWinner(), call withdraw() and receive a share of the final pool — attacker entered after outcome was known and gained unfair profit.

// Attacker deposits after seeing real-world match result but before winner is set
contract LateDepositAttack {
function exploit(BriVault vault, uint256 amount, uint256 teamId) external {
vault.deposit(amount, msg.sender);
vault.joinEvent(teamId); // join team that already won
}
}

Recommended Mitigation

Brief explanation:

  • Disallow deposits after eventStartDate and after eventEndDate.

  • Ideally, lock deposits immediately when the event starts.

- remove this code
+ add this code
function deposit(uint256 assets, address receiver) public override returns (uint256) {
require(receiver != address(0));
- if (block.timestamp >= eventStartDate) {
- revert eventStarted();
- }
+ if (block.timestamp >= eventStartDate || block.timestamp >= eventEndDate) {
+ revert eventStarted();
+ }
Updates

Appeal created

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

Support

FAQs

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

Give us feedback!