MyCut

AI First Flight #8
Beginner FriendlyFoundry
EXP
View results
Submission Details
Impact: high
Likelihood: medium
Invalid

[H-1] Use of `block.timestamp` in `Pot::constructor` could lead to denial of service

[H-1] Use of `block.timestamp` in `Pot::constructor` could lead to denial of service

Description

  • The `Pot::constructor` function stores the deployment time using `block.timestamp`. This is because the protocol's owner needs to wait 90 days before being able to close the pot.

  • However, `block.timestamp` can be manipulated by malicious miners, causing the pot to have wrong deployment time, leading to denial of service.

constructor(address[] memory players, uint256[] memory rewards, IERC20 token, uint256 totalRewards) {
i_players = players;
i_rewards = rewards;
i_token = token;
i_totalRewards = totalRewards;
remainingRewards = totalRewards;
@> i_deployedAt = block.timestamp;
// i_token.transfer(address(this), i_totalRewards);
for (uint256 i = 0; i < i_players.length; i++) {
playersToRewards[i_players[i]] = i_rewards[i];
}
}

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2

Impact:

  • The deployment time could be so far in the future that it would not be closeable.

Proof of Concept

1. A malicious miner sets the time far in the future

2. User creates a contest and funds it, but the tx is validated by the malicious miner

3. Users closes the pot in a tx validated by a regular miner

4. It reverts

Add the following test to `TestMyCut.t.sol`

function testTimestampManipulationDenialOfService() public mintAndApproveTokens {
ContestManager contestManager = ContestManager(conMan);
// Step 0 : Assume we are in a time long after genesis
vm.warp(100 weeks);
// Step 1 : Malicious miner sets the time far in the future
vm.warp(52000000 * 1 weeks);
// Step 2 : User creates a contest and funds it
vm.startPrank(user);
contest = contestManager.createContest(players, rewards, IERC20(address(weth)), totalRewards);
contestManager.fundContest(0);
vm.stopPrank();
// Now we're going back to a "normal" miner, 91 days after the pot was created
vm.warp(100 weeks + 91 days);
// Step 3 : User closes the pot
vm.startPrank(user);
vm.expectRevert();
contestManager.closeContest(contest);
vm.stopPrank();
}

Recommended Mitigation

Don't rely on `block.timestamp`. Use `block.number` instead.

constructor(address[] memory players, uint256[] memory rewards, IERC20 token, uint256 totalRewards) {
i_players = players;
i_rewards = rewards;
i_token = token;
i_totalRewards = totalRewards;
remainingRewards = totalRewards;
- i_deployedAt = block.timestamp;
+ i_deployedAt = block.number;
// i_token.transfer(address(this), i_totalRewards);
for (uint256 i = 0; i < i_players.length; i++) {
playersToRewards[i_players[i]] = i_rewards[i];
}
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 1 day 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!