If user's reward is great than contract balance user call 'claimSingleReward' function will cause fail.
Contract use random to open mystery box,so contract balance may be less than user's reward.User claim reward will fail.
Proof of concepts
forge test --match-test testClaimSingleRewardInsufficient -vvv
[⠊] Compiling...
[⠰] Compiling 2 files with Solc 0.8.21
[⠔] Solc 0.8.21 finished in 1.39s
Compiler run successful with warnings:
Warning (2018): Function state mutability can be restricted to view
--> test/TestMysteryBox.t.sol:295:5:
|
295 | function Attack() public {
| ^ (Relevant source part starts here and spans across multiple lines).
Ran 1 test for test/TestMysteryBox.t.sol:MysteryBoxTest
[FAIL. Reason: revert: Transfer failed] testClaimSingleRewardInsufficient() (gas: 163296)
Logs:
Reward Pool Length: 4
User Buy box
User Open box
User rewards name: Silver Coin
User rewards value: 500000000000000000
Contract balance 200000000000000000
User reward balance is greater than contract balance: true
Traces:
[163296] MysteryBoxTest::testClaimSingleRewardInsufficient()
├─ [0] VM::deal(ECRecover: [0x0000000000000000000000000000000000000001], 1000000000000000000 [1e18])
│ └─ ← [Return]
├─ [0] VM::startPrank(ECRecover: [0x0000000000000000000000000000000000000001])
│ └─ ← [Return]
├─ [24580] MysteryBox::buyBox{value: 100000000000000000}()
│ └─ ← [Stop]
├─ [0] VM::stopPrank()
│ └─ ← [Return]
├─ [0] VM::deal(Identity: [0x0000000000000000000000000000000000000004], 1000000000000000000 [1e18])
│ └─ ← [Return]
├─ [0] VM::startPrank(Identity: [0x0000000000000000000000000000000000000004])
│ └─ ← [Return]
├─ [22580] MysteryBox::buyBox{value: 100000000000000000}()
│ └─ ← [Stop]
├─ [0] console::log("User Buy box") [staticcall]
│ └─ ← [Stop]
├─ [68092] MysteryBox::openBox()
│ └─ ← [Stop]
├─ [0] console::log("User Open box") [staticcall]
│ └─ ← [Stop]
├─ [608] MysteryBox::boxesOwned(Identity: [0x0000000000000000000000000000000000000004]) [staticcall]
│ └─ ← [Return] 0
├─ [0] VM::assertEq(0, 0) [staticcall]
│ └─ ← [Return]
├─ [2130] MysteryBox::getRewards() [staticcall]
│ └─ ← [Return] [Reward({ name: "Silver Coin", value: 500000000000000000 [5e17] })]
├─ [0] console::log("User rewards name:", "Silver Coin") [staticcall]
│ └─ ← [Stop]
├─ [0] console::log("User rewards value:", 500000000000000000 [5e17]) [staticcall]
│ └─ ← [Stop]
├─ [0] console::log("Contract balance ", 200000000000000000 [2e17]) [staticcall]
│ └─ ← [Stop]
├─ [0] console::log("User reward balance is greater than contract balance:", true) [staticcall]
│ └─ ← [Stop]
├─ [7951] MysteryBox::claimSingleReward(0)
│ ├─ [0] PRECOMPILES::identity{value: 500000000000000000}(0x)
│ │ └─ ← [OutOfFunds]
│ └─ ← [Revert] revert: Transfer failed
└─ ← [Revert] revert: Transfer failed
Suite result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 9.71ms (1.52ms CPU time)
Ran 1 test suite in 194.06ms (9.71ms CPU time): 0 tests passed, 1 failed, 0 skipped (1 total tests)
Failing tests:
Encountered 1 failing test in test/TestMysteryBox.t.sol:MysteryBoxTest
[FAIL. Reason: revert: Transfer failed] testClaimSingleRewardInsufficient() (gas: 163296)
Encountered a total of 1 failing tests, 0 tests succeeded
Manual review.
If user's reward is greater than contract balance,user can claim all contract balance.
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.