Rust Fund

AI First Flight #9
Beginner FriendlyRust
EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

Clock::get().unwrap() and try_into().unwrap() can panic, and the deadline u64 vs unix_timestamp i64 conversion is fragile

Clock/timestamp unwrap() panics and fragile i64-to-u64 conversion in time handling

Description

contribute (lib.rs:29) and refund (lib.rs:69) read the clock and convert the timestamp with chained unwrap()s, and compare a deadline: u64 against an i64 unix_timestamp via try_into().unwrap(). Any failure panics the instruction, and the signed-to-unsigned conversion is brittle.

if fund.deadline != 0
&& fund.deadline < Clock::get().unwrap().unix_timestamp.try_into().unwrap() {
// @> unwrap panics on clock failure
// @> i64 -> u64 try_into().unwrap() panics if negative :29 (and :69)
return Err(ErrorCode::DeadlineReached.into());
}

Risk

Likelihood:

Clock::get() failure is rare, and unix_timestamp is non-negative under normal validator conditions, so a panic is unlikely in practice. The conversion is nonetheless unsound by construction (no guarantee the i64 is in u64 range) and relies on a runtime invariant rather than the type system.

Impact:

A failed unwrap() aborts the instruction with a non-descriptive panic instead of a typed error, degrading diagnosability. The u64 deadline vs i64 timestamp mismatch is an accident waiting to happen if either side's representation changes, and inconsistent time typing across instructions makes the deadline logic harder to reason about and audit.

Proof of Concept

Static/logic review: the two unwrap()s on Clock::get() and try_into() are infallible-by-assumption, not by contract — a returned error or out-of-range value panics rather than producing ErrorCode. No on-chain trigger needed to demonstrate the unsound pattern.

Recommended Mitigation

Propagate errors with ? and use a consistent timestamp type instead of unwrap().

- if fund.deadline != 0
- && fund.deadline < Clock::get().unwrap().unix_timestamp.try_into().unwrap() {
+ let now: i64 = Clock::get()?.unix_timestamp;
+ let deadline = i64::try_from(fund.deadline).map_err(|_| ErrorCode::CalculationOverflow)?;
+ if fund.deadline != 0 && deadline < now {
return Err(ErrorCode::DeadlineReached.into());
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 3 hours 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!