WETH-11

Idea

Function execute() allows us to do arbitrary call on behalf of the WETH11 contract:

    function execute(address receiver, uint256 amount, bytes calldata data) external nonReentrant {
        uint256 prevBalance = address(this).balance;
        Address.functionCallWithValue(receiver, data, amount);

        require(address(this).balance >= prevBalance, "flash loan not returned");
    }

This is RCE.

The WETH contract has 10 WETH at the beginning:

    function setUp() public {
        weth = new WETH11();
        bob = makeAddr("bob");

        vm.deal(address(bob), 10 ether);
        vm.startPrank(bob);
        weth.deposit{value: 10 ether}();
        weth.transfer(address(weth), 10 ether);
        vm.stopPrank();
    }

We can call transfer() to collect all the WETH from this contract and call withdrawAll() to burn everything and get ETH back.

PoC

Last updated