The contribute
function suffers from three major vulnerabilities:
**Timestamp Handling is Unsafe: **
Clock::get().unwrap().unix_timestamp.try_into().unwrap()
can panic, freezing the contract.
This affects both fund withdrawals and refund processing.
Deadline is Optional (Zero):
If deadline == 0
, contributors can never get refunds, and creators can’t withdraw.
If the goal is met, but the deadline is missing, funds can never be withdrawn.
Timestamp Failure Can Cause Refund/Withdraw Failures:
If Clock::get()
fails, refunds and withdrawals break simultaneously.
Even if the campaign met its goal, funds can remain frozen due to a broken timestamp.
Clock::get()
can Panic and Halt Crowdfunding:The function currently unwraps the timestamp unsafely which can cause a panic if:
Clock::get()
fails to fetch the blockchain timestamp.
unix_timestamp.try_into()
fails due to an overflow, especially in edge cases when handling large timestamps.
deadline == 0
Means No End Condition:The contract only checks if fund.deadline
is reached and doesn't check if deadline == 0
:
If goal is met, creator can’t withdraw.
If goal isn’t met, contributors can’t get refunds.
This means the funds will be permanently stuck.
Complete Crowdfunding Failure:
No transactions work if Clock::get()
fails.
Contributors can’t get refunds if goal isn't met.
Creators can’t withdraw even if goal is met.
Permanent Fund Locking:
If deadline == 0, neither refunds nor withdrawals work.
Contributors can't retrieve their deposits, creators can’t use funds.
Worst-case scenario: contract becomes unusable forever.
Trust Violation & Security Exploit:
Malicious campaigns can intentionally set deadline == 0
to lock funds forever.
Users will lose confidence in the platform if funds become unrecoverable.
Anchor Tests: To simulate and catch unwrap failures under various conditions.
The transaction should fail safely with a "Calculation overflow"
error, preventing unexpected panics.
Safe Timestamp Retrieval with Error Handling
Explicitly rejecting contributions if deadline isn't set
It is very unlikely `Clock::get` to fail, therefore I think it is safe to use `unwrap` here. Consider this issue as informational.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.