claimRewards()
allows users to claim loveTokens
based on both the time since their last claim and the amount of loveTokens
deposited. However, a vulnerability arises when users can deposit, claim rewards, and withdraw in a single transaction. This allows attackers to use flash loans to drain all the funds of the contract.
claimRewards()
calculates rewards based on the number of loveTokens
staked by the users and the time elapsed since their last claim (in weeks).
The vulnerability lies in the ability for an attacker to utilize a flash loan to deposit loveTokens into the contract, subsequently stealing all funds. The attack unfolds through the following steps:
Use mintSoulmateToken()
with one soulmate1 being an EOA, while the other, soulmate2, is a malicious contract.
Wait 1 week.
Acquire a flash loan of loveTokens
.
Execute the deposit()
to add loveTokens
to the contract.
Exploit the claimRewards()
to pilfer all funds from the contract.
Utilize the withdraw()
to retrieve previously deposited loveTokens
.
Repay the flash loan by returning the loveTokens
.
Steps 3 through 7 are executed within a single transaction orchestrated by a malicious contract.
Modify LoveToken.sol
by integrating the following lines to simulate a flash loan.
To execute thePOC, add the following code into SakingTest.sol
, then run forge test --match-test test_StealAllTheFundsWithFlashLoan
.
All funds can be stolen.
Manual review.
Incorporate the nonReentrant
modifier from OpenZeppelin Contracts ReentrancyGuard.sol
into deposit()
, withdraw()
, and claimRewards()
.
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.