Last Man Standing

First Flight #45
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Predictable Grace Period + Public Timer Enables Deterministic Sniping

Root Cause + Impact

Description

  • The contract exposes the exact time remaining in the gracePeriod using the public getRemainingTime() view function.

  • Combined with public variables like lastClaimTime and gracePeriod, this allows external actors to precisely predict when the game state will change, removing any uncertainty in timing.

  • This leads to automated sniping, where a bot or MEV agent can claim the throne just before declareWinner() becomes callable — defeating the game’s intent.

function getRemainingTime() public view returns (uint256) {
if (block.timestamp >= lastClaimTime + gracePeriod) {
return 0;
}
return (lastClaimTime + gracePeriod) - block.timestamp;
}
@> `getRemainingTime()` exposes real-time countdown
@> Relies on public `block.timestamp`, `lastClaimTime`, and `gracePeriod`
@> Allows exact prediction of when to front-run claim

Risk

Likelihood: High

  • The grace period timer is fully observable and deterministic.

  • Any external bot with mempool access can calculate optimal sniping windows in real-time.

Impact: Medium

  • Funds are not directly at risk.

  • However, game integrity is undermined, and human players are at a systemic disadvantage compared to automated bots.


Proof of Concept

// Pseudo-code for an automated sniping bot
const secondsLeft = await contract.getRemainingTime();
if (secondsLeft < 10) {
await contract.claimThrone({ value: throneBid });
}

This logic can be wrapped in a loop, scheduled off-chain, or embedded in MEV bots to monitor the mempool and submit a claimThrone() just before the grace period ends.


Recommended Mitigation

- function getRemainingTime() public view returns (uint256) {
- if (block.timestamp >= lastClaimTime + gracePeriod) {
- return 0;
- }
- return (lastClaimTime + gracePeriod) - block.timestamp;
- }
+ // Consider removing this function entirely
+ // Or making it internal with restricted access logic

Additional improvements:

  1. Randomize Grace Period Expiry
    Use blockhash or VRF to add jitter to the grace period end time.

  2. Commit-Reveal System
    Require users to commit a claim, then reveal it later — increasing fairness.

  3. Anti-Sniping Extension Logic
    Automatically extend the grace period if a claim happens too close to expiry.


Updates

Appeal created

inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

MEV/Frontrunning/Sniping

0xalipede Auditor
about 2 months ago
nem0thefinder Auditor
about 2 months ago
thesandf Submitter
about 2 months ago
inallhonesty Lead Judge
about 2 months ago
inallhonesty Lead Judge about 2 months ago
Submission Judgement Published
Validated
Assigned finding tags:

MEV/Frontrunning/Sniping

Support

FAQs

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