Lockup Time Not Reset After Full Withdrawal
The protocol mandates a LOCKUP_PERIOD to encourage long-term holding by applying a 10% penalty for early withdrawals.
Normal Behavior: The timestamp of the first share acquisition (share_received_time) is used to calculate time_held and determine if the penalty applies. This timestamp should logically be cleared when a user holds zero shares.
Issue: When an investor performs a full withdrawal via withdraw_shares(), the function successfully sets self.shares[msg.sender] = 0. However, it fails to clear the historical timestamp: self.share_received_time[msg.sender] retains its old, non-zero value.
When the same investor re-invests later, the logic in fund_investor() fails to set a new timestamp because the condition if self.share_received_time[msg.sender] == 0: evaluates to False.
Consequently, the new investment is tied to the old, distant timestamp. Upon immediate withdrawal of the new shares, the time_held check passes (time_held > LOCKUP_PERIOD), and the investor successfully bypasses the  early withdrawal penalty.
Likelihood: High
This mechanism is easily discovered and exploited by any investor after their initial lockup period expires once.
Impact: High
Economic Loss: The company permanently loses the penalty fee on all future "fresh" investments from returning users. This degrades the long-term holding incentive of the protocol.
The test confirms that after a user withdraws all shares (after the lockup expires), the remaining non-zero timestamp allows a subsequent re-investment to be withdrawn immediately without penalty.
Verified Test Output:
The lockup timestamp must be reset whenever a user's share balance drops to zero.
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.