Closed code423n4 closed 1 year ago
https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/Lottery.sol#L110-L131
# Using Foundry: Arithmetic overflow has caused the owner account to reduce to 0 and the attack user account to increase by the balance transferred from the owner.
# Vulnerable Code> Lottery.sol: function buyTickets( uint128[] calldata drawIds, uint120[] calldata tickets, address frontend, address referrer ) external override requireJackpotInitialized returns (uint256[] memory ticketIds) { if (drawIds.length != tickets.length) { revert DrawsAndTicketsLenMismatch(drawIds.length, tickets.length); } ticketIds = new uint256[](tickets.length); for (uint256 i = 0; i < drawIds.length; ++i) { ticketIds[i] = registerTicket(drawIds[i], tickets[i], frontend, referrer); } referralRegisterTickets(currentDraw, referrer, msg.sender, tickets.length); frontendDueTicketSales[frontend] += tickets.length; rewardToken.safeTransferFrom(msg.sender, address(this), ticketPrice * tickets.length); }
# Command Line: forge test -vvv --match-path "test/Lottery.t.sol" --match-test "testBuyInvalidTicket" # Foundry> Payload> Lottery.t.sol: function testBuyInvalidTicket() public { uint128 currentDraw = lottery.currentDraw(); vm.startPrank(USER); rewardToken.mint(TICKET_PRICE+1); rewardToken.approve(address(lottery), TICKET_PRICE); vm.expectRevert(InvalidTicket.selector); buyTicket(currentDraw, uint120(0x0E)+1, address(0)); // Cannot buy 10000000111 vm.expectRevert(InvalidTicket.selector); buyTicket(currentDraw, uint120(0x407)+1, address(0)); // Can buy 1000000111 buyTicket(currentDraw, uint120(0x207)+1, address(0)); }
# Log: username@name-MacBook-Pro 2023-03-wenwin % forge test -vvv --match-path "test/Lottery.t.sol" --match-test "testBuyInvalidTicket" [⠢] Compiling... No files changed, compilation skipped Running 1 test for test/Lottery.t.sol:LotteryTest [FAIL. Reason: Call did not revert as expected] testBuyInvalidTicket() (gas: 274887) Traces: [274887] LotteryTest::testBuyInvalidTicket() ├─ [2504] Lottery::currentDraw() [staticcall] │ └─ ← 0 ├─ [0] VM::startPrank(0x000000000000000000000000000000000000007B) │ └─ ← () ├─ [29444] TestToken::mint(5000000000000000001) │ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x000000000000000000000000000000000000007B, value: 5000000000000000001) │ └─ ← () ├─ [24628] TestToken::approve(Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], 5000000000000000000) │ ├─ emit Approval(owner: 0x000000000000000000000000000000000000007B, spender: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], value: 5000000000000000000) │ └─ ← true ├─ [0] VM::expectRevert(InvalidTicket()) │ └─ ← () ├─ [182634] Lottery::buyTickets([0], [15], 0x00000000000000000000000000000000000001bc, 0x0000000000000000000000000000000000000000) │ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: 0x000000000000000000000000000000000000007B, tokenId: 0) │ ├─ emit NewTicket(currentDraw: 0, ticketId: 0, drawId: 0, user: 0x000000000000000000000000000000000000007B, combination: 15, frontend: 0x00000000000000000000000000000000000001bc, referrer: 0x0000000000000000000000000000000000000000) │ ├─ [8498] TestToken::transferFrom(0x000000000000000000000000000000000000007B, Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], 5000000000000000000) │ │ ├─ emit Approval(owner: 0x000000000000000000000000000000000000007B, spender: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], value: 0) │ │ ├─ emit Transfer(from: 0x000000000000000000000000000000000000007B, to: Lottery: [0x2e234DAe75C793f67A35089C9d99245E1C58470b], value: 5000000000000000000) │ │ └─ ← true │ └─ ← [0] └─ ← "Call did not revert as expected" Test result: FAILED. 0 passed; 1 failed; finished in 5.03ms Failing tests: Encountered 1 failing test in test/Lottery.t.sol:LotteryTest [FAIL. Reason: Call did not revert as expected] testBuyInvalidTicket() (gas: 274887) Encountered a total of 1 failing tests, 0 tests succeeded
Foundry + VS Code
It is recommended to use vetted safe math libraries for arithmetic operations consistently throughout the smart contract system.
thereksfour marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/Lottery.sol#L110-L131
Vulnerability details
Impact
Proof of Concept
Tools Used
Recommended Mitigation Steps