The vulnerability stems from the use of Clock::get().unwrap().unix_timestamp for critical deadline checks in the program. In Solana, relying on unix_timestamp for strict deadline enforcement can be risky if precise timing is required, or if the logic assumes the timestamp cannot be influenced by the environment or specific transaction context variations.
The affected code performs deadline validation in functions like contribute and refund using a direct comparison:
This check is vulnerable because:
Clock Manipulation: While direct Sysvar manipulation represents a challenging attack vector on Mainnet, logic relying on unix_timestamp is susceptible to validator timestamp drift (up to nearly a minute generally accepted).
Logic Bypass: If the check is strictly <, an attacker might exploit edge cases where the timestamp is exactly equal or slightly skewed due to network cluster time differences.
Severity: Critical
Likelihood: Medium
Impact: High
Impact Details:
Unauthorized Fund Withdrawals: Attackers can bypass deadline restrictions and withdraw funds before the intended deadline, leading to direct financial losses for users or the protocol.
Protocol Integrity Violation: Critical time-based logic (e.g., refund periods, vesting schedules) can be circumvented, breaking core protocol invariants.
Denial of Service (DoS): In some cases, premature fund withdrawals could drain liquidity pools or disrupt protocol operations.
The following test demonstrates how the deadline check can be tested against manipulated time. In a local testing environment (solana-program-test), we can explicitly warp the clock to simulate a scenario where the validator produces a block at a specific timestamp that bypasses the deadline check logic.
The reliance on unix_timestamp for deadline checks should be replaced with Block Slots, which are strictly monotonic and harder to manipulate in a CPI context.
This change ensures that deadlines are enforced based on the blockchain's block height (slot) rather than the validator's local clock, effectively preventing the timestamp manipulation attack.
Apply the following diff to the program logic (likely in src/lib.rs or src/processor.rs):
Implementation Check:
Update the Fund data structure to store deadline_slot (u64) instead of, or in addition to, deadline (i64).
Initialize deadline_slot using Clock::get()?.slot + duration_in_slots during the fund initialization.
Deploy the updated program.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.