The MarketCreator
contract calculates depositor rewards based on the current total deposits. Because this total decreases with each redemption, later redeemers may receive disproportionately high rewards—potentially up to the entire reward pool—regardless of their original share. This order-dependent calculation can lead to reward inflation and even failed transfers if the contract’s token balance is insufficient.
This is how the reward is calculated:
Here, market.reward
is the total reward pool, and market.totalDeposits
is the dynamic total of all deposits.
Initial Scenario: When all depositors redeem simultaneously (e.g., 100 tokens total with a 200-token reward pool), a depositor with 20 tokens would expect:
`(20 * 200) / 100 = 40 tokens`
After Early Redemptions: If one depositor withdraws early, reducing market.totalDeposits
, later redeemers see a lower denominator. For example, if a 40-token depositor redeems first, the remaining total drops to 60, and a 20-token depositor then gets:
`(20 * 200) / 60 ≈ 66.67 tokens`
In extreme cases, the last redeemer—if they’re the only one left—could receive the full reward pool:
`(amount * 200) / totalDeposits = 200 tokens`
Unfair Reward Distribution: Later redeemers benefit disproportionately compared to earlier redeemers.
Potential Exploitation: Users might time their withdrawals to maximize rewards, undermining the fairness of the system.
Manual review
Capture and store each depositor’s share based on a snapshot of market.totalDeposits
at deposit time. This locks in their reward share regardless of subsequent redemptions.
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.