BriVault

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

Catastrophic Time Validation Vulnerability Creating Exploitable Contract State

[C-1] Catastrophic Time Validation Vulnerability Creating Exploitable Contract State

Description

The contract doesn't validate that eventStartDate is less than eventEndDate in the constructor, creating a critical vulnerability that can be exploited in multiple ways. This flaw fundamentally breaks the contract's temporal logic and creates exploitable states.

constructor (IERC20 _asset, uint256 _participationFeeBsp, uint256 _eventStartDate, address _participationFeeAddress, uint256 _minimumAmount, uint256 _eventEndDate) ERC4626 (_asset) ERC20("BriTechLabs", "BTT") Ownable(msg.sender) {
if (_participationFeeBsp > PARTICIPATIONFEEBSPMAX){
revert limiteExceede();
}
// check event start date is not after event end date
participationFeeBsp = _participationFeeBsp;
eventStartDate = _eventStartDate;
eventEndDate = _eventEndDate;
participationFeeAddress = _participationFeeAddress;
minimumAmount = _minimumAmount;
_setWinner = false;
}

Risk

Likelihood: HIGH

Impact: HIGH

If eventStartDate > eventEndDate, multiple catastrophic states are created:

  1. Deposit Trap: Users can deposit even after the event has technically ended (if current time > endDate but < startDate), as the contract only checks block.timestamp >= eventStartDate to prevent deposits

  2. Winner Selection Manipulation: A malicious owner can exploit this to set an arbitrary winner if they deploy with an end date in the past

  3. Permanent Fund Lock: If owner never calls setWinner(), all funds remain permanently locked

Proof of Concept

The PoC demonstrates how a malicious deployer can create a broken contract by setting the end date before the start date:

// Malicious deployment scenario
uint256 pastEndDate = block.timestamp - 1 days;
uint256 futureStartDate = block.timestamp + 30 days;
// Deploy with inverted dates
BriVault vault = new BriVault(
asset,
100, // fee in basis points
futureStartDate,
ownerControlledFeeAddress,
1 ether, // minimum amount
pastEndDate // end date already passed
);
// Users deposit funds believing they're joining a tournament
// Deposit function allows this since block.timestamp < eventStartDate
vault.deposit(10 ether, user1);
vault.joinEvent(0);
// Users can't cancel since they'd check event hasn't started
// But owner can immediately set winner since end date is in the past
vault.setWinner(winnerOfOwnerChoice);
// Only users who selected owner's chosen winner can withdraw
// Others lose their funds permanently

This creates multiple exploitable states:

  1. Users can deposit funds (as block.timestamp < startDate)

  2. Owner can immediately set any winner (as block.timestamp > endDate)

  3. Only users who selected the owner's chosen winner can withdraw

Recommended Mitigation

The fix adds proper validation in the constructor:

These checks prevent deployment with invalid time parameters, ensuring the contract's temporal logic functions correctly and can't be manipulated to trap user funds.

To futher improve consider adding following constants MIN_TIME_BEFORE_EVENT_START, MAX_TIME_BEFORE_EVENT_START and MIN_EVENT_TIME, MAX_EVENT_TIME to avoid unreasonable time.

constructor (IERC20 _asset, uint256 _participationFeeBsp, uint256 _eventStartDate, address _participationFeeAddress, uint256 _minimumAmount, uint256 _eventEndDate) ERC4626 (_asset) ERC20("BriTechLabs", "BTT") Ownable(msg.sender) {
if (_participationFeeBsp > PARTICIPATIONFEEBSPMAX){
revert limiteExceede();
}
// Validate event dates
require(_eventStartDate < _eventEndDate, "Event start must be before end");
require(_eventStartDate > block.timestamp, "Event start must be in the future");
require(_eventEndDate > block.timestamp, "Event end must be in the future");
participationFeeBsp = _participationFeeBsp;
eventStartDate = _eventStartDate;
eventEndDate = _eventEndDate;
participationFeeAddress = _participationFeeAddress;
minimumAmount = _minimumAmount;
_setWinner = false;
}
Updates

Appeal created

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

Missing Constructor Validation

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!