transmissions11 / solmate

Modern, opinionated, and gas optimized building blocks for smart contract development.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

safeTransferFrom fails when casting the 'to' address down from a value greater than max(uint160)

gasperbr opened this issue · comments

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Test.sol";
import "solmate/utils/SafeTransferLib.sol";
import "solmate/tokens/ERC20.sol";

contract ContractTest is Test {

    Token token = new Token();
    Router router = new Router();

    function setUp() public {
        token.approve(address(router), 1);
    }
    function testSafeTransferOk() public {
        router.safeTransferSucceeds(address(token)); // Ok.
    }
    function testSafeTransferNok() public {
        router.safeTransferFails(address(token)); // This fails.
    }
}

contract Router {
    function safeTransferSucceeds(address token) public {
        address to = address(uint160(uint256(0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff))); // type(uint160).max
        SafeTransferLib.safeTransferFrom(ERC20(token), msg.sender, to, 1);
    }
    function safeTransferFails(address token) public {
        address to = address(uint160(uint256(0x0000000000000000000000010000000000000000000000000000000000000000))); // type(uint160).max + 1
        SafeTransferLib.safeTransferFrom(ERC20(token), msg.sender, to, 1);
    }
}

contract Token is ERC20("", "", 18) {
    constructor() {
        _mint(msg.sender, 1);
    }
}

Encountered the same issue. This is also true for "from". A temporary fix is to mask the address:

address(uint160(uint256(0x0000000000000000000000010000000000000000000000000000000000000000)) & type(uint160).max)