Skip to content

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

@gasperbr

Description

@gasperbr
// 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);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions