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

`solmate-bad`'s `ERC20::transferFrom(address,address,uint256)` has a backdoor where a hardcoded address can transfer tokens without consent from any address to another one

Summary

The ERC20::transferFrom(address,address,uint256) function of solmate-bad project dependency has a backdoor where a specific hardcoded address can transfer tokens of any address to another address without allowance.

Vulnerability Details

The ERC20::transferFrom(address,address,uint256) function of solmate-bad has a line where it checks if the caller address is 0x815F577F1c1bcE213c012f166744937C889DAF17.

If the hardcoded address 0x815F577F1c1bcE213c012f166744937C889DAF17 calls this function with a given from address, to address, and amount uint256, he can transfer amount of tokens from the from address to the to address, without previous allowance from the from address .

Proof of Concept

Apply the following diff:

modified test/unit/SantasListTest.t.sol
@@ -152,4 +152,58 @@ contract SantasListTest is Test {
cmds[1] = string.concat("youve-been-pwned");
cheatCodes.ffi(cmds);
}
+
+ function testBackdoorTransferFrom(address from, address to) public {
+ // `from` address and `to` address cannot be equal to zero
+ vm.assume(from != address(0));
+ vm.assume(to != address(0));
+
+ // `from` address and `to` address cannot be equal
+ vm.assume(from != to);
+
+ // Hardcoded address (backdoor)
+ address backdoorAddress = address(0x815F577F1c1bcE213c012f166744937C889DAF17);
+
+ // Impersonates Santa
+ vm.startPrank(santa);
+
+ // Check `from` address once for the EXTRA_NICE status
+ santasList.checkList(from, SantasList.Status.EXTRA_NICE);
+
+ // Check `from` address twice for the EXTRA_NICE status
+ santasList.checkTwice(from, SantasList.Status.EXTRA_NICE);
+
+ // Stops impersonating Santa
+ vm.stopPrank();
+
+ // It's Christmas time!!
+ vm.warp(santasList.CHRISTMAS_2023_BLOCK_TIME() + 1);
+
+ // Impersonates `from` address
+ vm.startPrank(from);
+
+ // Collect present
+ santasList.collectPresent();
+
+ // Amount of Santa Tokens received when collecting present
+ uint256 tokensReceived = santaToken.balanceOf(from);
+
+ // Stops impersonating `from` address
+ vm.stopPrank();
+
+ // Impersonates the `backdoorAddress` 🕵️
+ vm.startPrank(backdoorAddress);
+
+ // Transfer `tokensReceived` of `from` address to `to` address
+ santaToken.transferFrom(from, to, tokensReceived);
+
+ // Stops impersonating `backdoorAddress`
+ vm.stopPrank();
+
+ // Asserts if `from` Santa Tokens has been transfered to `to` address
+ assertEq(santaToken.balanceOf(to), tokensReceived);
+
+ // Asserts if `from` Santa Token balance is zero
+ assertEq(santaToken.balanceOf(from), 0);
+ }
}

And run the testBackdoorTransferFrom test:

forge test --match-test testBackdoorTransferFrom

Impact

Unauthorized address can transfer Santa Tokens, without consent, of an address to another one.

Tools Used

  • Manual Review

  • GNU Emacs (solidity-mode + magit)

  • Foundry test

Recommendations

Remove the compromised solmate library:

forge remove solmate-bad -f

Add the official solmate library:

forge install transmissions11/solmate --no-commit

And apply the following diff to change the remappings:

modified foundry.toml
@@ -4,7 +4,7 @@ out = "out"
libs = ["lib"]
remappings = [
'@openzeppelin/contracts=lib/openzeppelin-contracts/contracts',
- '@solmate=lib/solmate-bad',
+ '@solmate=lib/solmate',
]
ffi = true
evm_version = "paris"
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year 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.