Lines of code
<https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/RNSourceBase.sol#L17-L20>
Integer overflow on finalizeDraw() function.
Failing tests:
Encountered 1 failing test in test/LotteryInvariantChecks.t.sol:LotteryInvariantChecksTest
[FAIL. Reason: Arithmetic over/underflow Counterexample: calldata=0xbbbd8cb8000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000, args=[[0], [0x0000000000000000000000000000000000000000], 115792089237316195423570985008687907853269984665640564039457584007913129639935]] testBuyClaimFinalize(uint256[],address[],uint256) (runs: 298, μ: 2549628, ~: 571280)
# POC Code> test/LotteryInvariantChecks.t.sol:
function testBuyClaimFinalize(uint256[] memory tickets, address[] memory users, uint256 randomNumber) public {
vm.assume(tickets.length > 0);
vm.assume(users.length > 0);
buyRandomTickets(tickets, users);
claimRewards();
finalizeDraw(randomNumber+1); // oxtr3 added integer overfloe
}
# Vulnerable Lines Of Code:
https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/Lottery.sol#L203-L214
https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/RNSourceBase.sol#L17-L20
# Command Line:
forge test -vvvv --match-path "test/LotteryInvariantChecks.t.sol" --match-test "testBuyClaimFinalize"
# Log:
oxtr3 2023-03-wenwin % forge test -vvvv --match-path "test/LotteryInvariantChecks.t.sol" --match-test "testBuyClaimFinalize"
[⠒] Compiling...
No files changed, compilation skipped
Running 1 test for test/LotteryInvariantChecks.t.sol:LotteryInvariantChecksTest
[FAIL. Reason: Arithmetic over/underflow Counterexample: calldata=0xbbbd8cb8000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000, args=[[0], [0x0000000000000000000000000000000000000000], 115792089237316195423570985008687907853269984665640564039457584007913129639935]] testBuyClaimFinalize(uint256[],address[],uint256) (runs: 298, μ: 2549628, ~: 571280)
Logs:
Bound Result 1
Traces:
[11618533] LotteryInvariantChecksTest::setUp()
├─ [523854] → new TestToken@0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f
│ └─ ← 2391 bytes of code
├─ [8226018] → new Lottery@0x2e234DAe75C793f67A35089C9d99245E1C58470b
│ ├─ emit OwnershipTransferred(previousOwner: 0x0000000000000000000000000000000000000000, newOwner: LotteryInvariantChecksTest: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496])
│ ├─ [607209] → new LotteryToken@0xffD4505B3452Dc22f8473616d50503bA9E1710Ac
│ │ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], value: 1000000000000000000000000000)
│ │ └─ ← 2576 bytes of code
│ ├─ [266] TestToken::decimals() [staticcall]
│ │ └─ ← 18
│ ├─ [266] TestToken::decimals() [staticcall]
│ │ └─ ← 18
│ ├─ emit LotteryDeployed(token: TestToken: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f], drawSchedule: 0x7c951a6396053543c7db9b57f82a1e88f32937b4a0c345d31d367e7074703ab3, ticketPrice: 5000000000000000000, selectionSize: 4, selectionMax: 10, expectedPayout: 380000000000000000, fixedRewards: [0, 5000000000000000000, 10000000000000000000, 15000000000000000000])
│ ├─ [1177729] → new Staking@0x8d2C17FAd02B7bb64139109c6533b7C2b9CADb81
│ │ └─ ← 5649 bytes of code
│ ├─ [240] LotteryToken::INITIAL_SUPPLY() [staticcall]
│ │ └─ ← 1000000000000000000000000000
│ ├─ [20013] LotteryToken::transfer(LotteryInvariantChecksTest: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496], 1000000000000000000000000000)
│ │ ├─ emit Transfer(from: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], to: LotteryInvariantChecksTest: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496], value: 1000000000000000000000000000)
│ │ └─ ← true
│ └─ ← 19401 bytes of code
├─ [327] Lottery::nativeToken() [staticcall]
│ └─ ← LotteryToken: [0xffD4505B3452Dc22f8473616d50503bA9E1710Ac]
├─ [46544] TestToken::mint(1000000000000000000000000)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: LotteryInvariantChecksTest: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496], value: 1000000000000000000000000)
│ └─ ← ()
├─ [20031] TestToken::transfer(Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], 1000000000000000000000000)
│ ├─ emit Transfer(from: LotteryInvariantChecksTest: [0x7FA9385bE102ac3EAc297483Dd6233D62b3e1496], to: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], value: 1000000000000000000000000)
│ └─ ← true
├─ [263] Lottery::initialPotDeadline() [staticcall]
│ └─ ← 172801
├─ [0] VM::warp(172802)
│ └─ ← ()
├─ [24520] Lottery::finalizeInitialPotRaise()
│ ├─ [540] TestToken::balanceOf(Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b]) [staticcall]
│ │ └─ ← 1000000000000000000000000
│ ├─ emit InitialPotPeriodFinalized(amountRaised: 1000000000000000000000000)
│ └─ ← ()
├─ [24075] Lottery::initSource(0x00000000000000000000000000000000499602D2)
│ ├─ emit SourceSet(source: 0x00000000000000000000000000000000499602D2)
│ └─ ← ()
├─ [0] VM::mockCall(0x00000000000000000000000000000000499602D2, 0x8678a7b2, 0x0000000000000000000000000000000000000000000000000000000000000000)
│ └─ ← ()
└─ ← ()
[315057] LotteryInvariantChecksTest::testBuyClaimFinalize([0], [0x0000000000000000000000000000000000000000], 115792089237316195423570985008687907853269984665640564039457584007913129639935)
├─ [0] VM::assume(true) [staticcall]
│ └─ ← ()
├─ [0] VM::assume(true) [staticcall]
│ └─ ← ()
├─ [0] console::log(Bound Result, 1) [staticcall]
│ └─ ← ()
├─ [0] VM::startPrank(0x0000000000000000000000000000000000000001)
│ └─ ← ()
├─ [29444] TestToken::mint(5000000000000000000)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x0000000000000000000000000000000000000001, value: 5000000000000000000)
│ └─ ← ()
├─ [24628] TestToken::approve(Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], 5000000000000000000)
│ ├─ emit Approval(owner: 0x0000000000000000000000000000000000000001, spender: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], value: 5000000000000000000)
│ └─ ← true
├─ [2504] Lottery::currentDraw() [staticcall]
│ └─ ← 0
├─ [162734] Lottery::buyTickets([0], [15], 0x00000000000000000000000000000000000001bc, 0x0000000000000000000000000000000000000000)
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x0000000000000000000000000000000000000001, tokenId: 0)
│ ├─ emit NewTicket(currentDraw: 0, ticketId: 0, drawId: 0, user: 0x0000000000000000000000000000000000000001, combination: 15, frontend: 0x00000000000000000000000000000000000001bc, referrer: 0x0000000000000000000000000000000000000000)
│ ├─ [8498] TestToken::transferFrom(0x0000000000000000000000000000000000000001, Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], 5000000000000000000)
│ │ ├─ emit Approval(owner: 0x0000000000000000000000000000000000000001, spender: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], value: 0)
│ │ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000001, to: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], value: 5000000000000000000)
│ │ └─ ← true
│ └─ ← [0]
├─ [0] VM::stopPrank()
│ └─ ← ()
├─ [51959] Lottery::claimRewards(1)
│ ├─ emit ClaimedRewards(rewardRecipient: Staking: [0x8d2C17FAd02B7bb64139109c6533b7C2b9CADb81], amount: 1000000000000000000, rewardType: 1)
│ ├─ [25038] TestToken::transfer(Staking: [0x8d2C17FAd02B7bb64139109c6533b7C2b9CADb81], 1000000000000000000)
│ │ ├─ emit Transfer(from: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], to: Staking: [0x8d2C17FAd02B7bb64139109c6533b7C2b9CADb81], value: 1000000000000000000)
│ │ └─ ← true
│ └─ ← 1000000000000000000
├─ [0] VM::prank(0x00000000000000000000000000000000000001bc)
│ └─ ← ()
├─ [23874] Lottery::claimRewards(0)
│ ├─ emit ClaimedRewards(rewardRecipient: 0x00000000000000000000000000000000000001bc, amount: 500000000000000000, rewardType: 0)
│ ├─ [25038] TestToken::transfer(0x00000000000000000000000000000000000001bc, 500000000000000000)
│ │ ├─ emit Transfer(from: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], to: 0x00000000000000000000000000000000000001bc, value: 500000000000000000)
│ │ └─ ← true
│ └─ ← 500000000000000000
├─ [1238] Lottery::unclaimedRewards(1) [staticcall]
│ └─ ← 0
├─ [0] VM::prank(0x00000000000000000000000000000000000001bc)
│ └─ ← ()
├─ [1107] Lottery::unclaimedRewards(0) [staticcall]
│ └─ ← 0
└─ ← "Arithmetic over/underflow"
Test result: FAILED. 0 passed; 1 failed; finished in 1.97s
Failing tests:
Encountered 1 failing test in test/LotteryInvariantChecks.t.sol:LotteryInvariantChecksTest
[FAIL. Reason: Arithmetic over/underflow Counterexample: calldata=0xbbbd8cb8000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000, args=[[0], [0x0000000000000000000000000000000000000000], 115792089237316195423570985008687907853269984665640564039457584007913129639935]] testBuyClaimFinalize(uint256[],address[],uint256) (runs: 298, μ: 2549628, ~: 571280)
Encountered a total of 1 failing tests, 0 tests succeeded
oxtr3 2023-03-wenwin %
Foundry + VS Code
use safe math
The text was updated successfully, but these errors were encountered:
All reactions