share_received_time[msg.sender] is written the first time anyone interacts with fund_investor. The timestamp is never cleared on exit and, because of VULN-01, it is even set when no shares are minted. Subsequent deposits reuse the stale value, letting attackers bypass the 30-day lockup.
withdraw_shares resets the share balance but leaves the timestamp untouched:
Likelihood: Any user can intentionally send a dust transaction to stamp a timestamp, making the bug broadly exploitable. No special permissions are required.
The early withdrawal penalty is trivially bypassed, breaking the intended economic guarantees.
Attackers can pre-farm timestamps across many addresses and execute instant exit trades, disadvantaging honest investors.
Lockup metrics become meaningless for compliance or treasury management.
Send < INITIAL_SHARE_PRICE to fund_cyfrin(1); zero shares mint but share_received_time records the current block.
Wait until the timestamp ages past 30 days (or simply fork forward in tests).
Deposit a real amount to mint shares.
Immediately call withdraw_shares; time_held treats the old timestamp as current and skips the penalty.
Unit-test outline:
Set share_received_time only when new_shares > 0 (paired with VULN-01 mitigation).
Clear share_received_time[msg.sender] inside withdraw_shares.
When a holder adds to their position, refresh the timestamp or compute a weighted-average holding period so every share tranche observes the lockup.
Suggested adjustments:
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.
The contest is complete and the rewards are being distributed.