October 22, 2026

On 17 October 2026, one Ethereum transaction repeatedly moved USDT into and out of BiFi's USDT market, exchanged most of the resulting surplus for WETH, and paid ETH to the transaction sender and a block fee recipient. This investigation asks two separate questions: how much USDT left the handler on a net basis, and how far the proceeds can be followed without assigning unrelated activity to the incident.
The checked route is BiFi USDT handler → execution helper → Uniswap pool → WETH unwrap → ETH payouts. A same-transaction flash loan supplies temporary funding and is fully repaid. The asset path is supported by explorer event records and displayed internal transfers; it stops at the payouts, not at a confirmed exchange deposit or recovery.
The handler is the contract that holds the market's USDT. The execution helper is another contract, called by the wallet that submitted and paid for the transaction. These are different roles: the wallet submits instructions, while the handler is the address whose token balance decreases. The role names below describe recorded activity, not the identity or intent of a person.
USDT is a stablecoin token designed to track the US dollar, but the quantities here are tokens, not a historical dollar valuation. WETH is a token form of ETH that can be handled by contracts using the common ERC-20 token interface; unwrapping WETH releases ETH rather than creating a second asset gain. A flash loan is temporary funding that must be returned within the same transaction; otherwise the entire transaction is reversed. Its principal is not the amount lost by BiFi. An exchange pool swaps one token for another; its presence does not establish that the pool or its operator participated in an attack.
Role | How it is used here |
|---|---|
BiFi USDT handler | Sends and receives USDT during the repeated market interactions. |
Execution helper | Borrows temporarily, interacts with the handler, swaps USDT and distributes ETH. |
Transaction sender | Submits Anchor A and receives its main ETH payout. |
Block fee recipient | Receives a direct ETH payment inside Anchor A, separate from the transaction gas fee. |
Earlier deployer | Creates a different contract one block before Anchor A; its relationship to the profitable execution remains unproven. |
Scope item | Boundary |
|---|---|
Incident anchors | 17 October 2026, 05:42:59 and 05:43:11 UTC; Ethereum mainnet. |
Accounting scope | Anchor A only: 142 displayed ERC-20 transfer rows; 141 USDT events independently cross-checked against decoded integer values and addresses. |
Follow-up window | 17 October 05:43:11–22 October 03:15:00 UTC; incomplete provider coverage, not a complete address history. |
Verification date | 22 October 2026; explorer and public-source reads may be later than the follow-up cutoff. |
Counting convention | Token quantities, no historical USD price estimate. Gas and direct builder payment reported separately. |
First, the handler's net outflow in Anchor A is 165,575.149730 USDT, not the much larger volume of repeated transfers. Second, the swap, residual USDT and ETH payouts can be reconciled without counting the same value twice. Third, the checked proceeds reach the transaction sender, but the reviewed records do not allocate the incident's ETH to a later cash-out or establish a completed refund.
Anchor B creates a contract from a different wallet in block 26,210,255. Twelve seconds later, Anchor A executes in the next block using a different helper. Both successful statuses, times and addresses were read directly in Etherscan. Deployment record · Execution record.
The public DeFiHackLabs reconstruction describes the earlier wallet as the original exploiter and the later sender as a front-runner, meaning a participant that executes an opportunity ahead of someone else. We retain those descriptions as external claims. A twelve-second gap is not proof of copying, shared control or mempool observation. Establishing that relationship would require the relevant bytecode and execution comparison, and evidence of how the later transaction was selected or ordered.
UTC / block | Observed event |
|---|---|
17 October 05:42:59 / 26,210,255 | Anchor B: 0x15b47e2c0daf723dec64c75b435079d3a1f8a6058b21b9a64dda4844e877a034. Deployer 0x7c78a049fff71609990017b58a959e926e6ec4c6 creates 0x8c0d729d03cb8ecbc79a62a68cdd67ccfa6a7b92. |
17 October 05:43:11 / 26,210,256 | Anchor A: 0x756c68055af7a0630aa0b56891ba4de14c56c39cbebe99e47eeb4728f4d6ad14. Sender 0xc0ffeebabe5d496b2dde509f9fa189c25cf29671 calls helper 0xe08d97e151473a848c3d9ca3f323cb720472d015. |
How much of the transfer volume represents money leaving the market? The helper receives 40,499,999.999997 USDT from the Morpho-labelled contract, then repeatedly sends USDT to and receives USDT from the BiFi handler. The flash-loan event records 40,499,999,999,997 base units; the final repayment returns the same principal. Anchor A events.
Within this transaction, 54 transfer events run from the helper to the handler and 83 run back. These counts include zero-value events. The incoming and outgoing sums are large because the same capital is reused. Subtracting one direction from the other answers the narrower question of the handler's token movement. Think of this as reconciling one account: a large amount repeatedly entering and leaving is not the same thing as the final amount that left it. The table counts the recorded token movements, not the market's internal deposit claims.
Handler ledger in Anchor A | USDT |
|---|---|
Incoming: 54 events | 141,270,327.667580 |
Outgoing: 83 events | 141,435,902.817310 |
Outgoing minus incoming | 165,575.149730 |
Start Figure 1 at the temporary loan, move through the two-way market interaction, then read the swap stage. Solid arrows connect ordered accounting stages, not additional losses or equal time intervals.

Figure 1. The flash loan nets to zero. The handler net outflow equals swap input plus helper residual. Colors group stages only; line width is not amount. Source: Anchor A decoded Transfer events and FlashLoan event.
The net outflow is a transaction-level quantity, not a complete statement of protocol insolvency, affected depositors or unreimbursed user losses. The next step is to account for where that surplus went.
The helper sends 165,574.514633 USDT to the Uniswap pool and receives 68.057203111718789216 WETH. The remaining 0.635097 USDT is the helper's net token change within Anchor A, not a current balance query. These two USDT quantities add to the handler's net outflow exactly.
Reconciliation | Quantity |
|---|---|
USDT swap input | 165,574.514633 USDT |
Helper USDT net increase | 0.635097 USDT |
Sum / handler net outflow | 165,575.149730 USDT |
Swap output | 68.057203111718789216 WETH |
USDT and WETH are not added together as separate losses. They are different forms of value passing through the same execution. Likewise, the following WETH unwrap is not a new theft of ETH on top of the swap. Full transaction and event record.
Where does the unwrapped ETH go? The WETH contract sends 68.057203111718789216 ETH to the helper. The helper also receives 145 wei with the submitted transaction. A wei is one quintillionth of an ETH; this tiny input matters when checking the payout to its final digit.
Start Figure 2 at the WETH contract, then follow the helper's two payout branches. The gray box below the sender marks an allocation limit and has no onward transfer arrow. Both payout branches belong to the same transaction; their side-by-side placement is not a time axis.

Figure 2. Solid arrows are ETH transfers in Anchor A. The dashed gray box is an evidence boundary, not an observed destination. Gas is not a helper payout. Sources: Etherscan internal transfers and the provider call trace.
ETH accounting | Exact amount |
|---|---|
WETH unwrap into helper | 68.057203111718789216 ETH |
Transaction value into helper | 0.000000000000000145 ETH |
Direct payment to block fee recipient | 0.986829445119922310 ETH |
Gross payout to transaction sender | 67.070373666598867051 ETH |
Transaction gas fee, paid separately by sender | 0.000845755321487776 ETH |
Unwrap plus transaction value equals the two helper payouts exactly. The sender's receipt is a gross payout, not automatically its final profit. Even subtracting transaction value and this gas fee would describe only a transaction-specific ETH change; it would not establish wider trading costs, earlier capital or the operator's incident-wide profit. A direct payment to a block fee recipient also does not establish its knowledge or involvement. Internal transfers and transaction fee.
A lending market records interest by updating accounting values over time. The DeFiHackLabs reconstruction proposes that an old interval without market activity was reused while the participant changed utilization—the proportion of deposits currently borrowed. In that explanation, repeatedly crediting interest at changing rates lets the participant withdraw more than it supplied. This is an external reconstruction, not a replay we independently executed. Reconstruction and assertions.
Direct source inspection provides a narrower check. In Etherscan's currently published TokenHandler source, _checkFirstAction calculates the current block minus the last updated block, then calls setBlocks and syncActionEXR when the difference is positive. In the published interest-model source, _getInterestAmount reads the stored inactive interval and action accounting rates. _calcInterestAmount reads deposit/borrow totals and calculates rates from them; _getNewGlobalEXR multiplies a rate by the interval. TokenHandler source · Interest-model source.
Those code relationships help explain the proposed mechanism. They do not establish the exact historical storage values or independently reproduce the exploit. The provider trace reports that the handler delegated calls to this logic address in Anchor A; delegatecall means code at another address runs using the caller's storage context. The inspected source is a present explorer publication, while the trace is provider-reported incident execution. Neither replaces a complete historical-state replay.
The reconstruction also uses distinct block contexts: its comments refer to a 264,059-block interval at the deployment block, while its test rolls to the following execution block and asserts 264,060 blocks. We do not silently merge those values or present either as a historical value independently read by this investigation. The missing evidence is the incident-time storage snapshot, decoded full execution and a reproducible replay at the correct parent state.
The bounded provider follow-up reviewed activity from 17 October 05:43:11 through 22 October 03:15:00 UTC, with limits of two outward hops and ten material transfers. Its source coverage is incomplete. The sender appears in repeated helper executions, so later balances and payments mix multiple activities. A later outgoing payment cannot simply be labelled the same 67.07 ETH because the address received it earlier.
The observation window is a requested time boundary, not proof that every transaction up to that time was retrieved. No incident-specific exchange receipt or directly anchored refund was established in that review. This is not a finding that neither exists: unobserved records and unresolved allocation remain. We exclude surrounding tokens, look-alike addresses and unrelated service labels from the incident route rather than drawing a larger network that the evidence does not support.
For the market's maintainers, the concrete technical check is how an idle interval and changing utilization interact across repeated actions in one block. Historical storage, active implementation and the before/after interest accounting should be compared before a patch or root-cause statement is treated as validated. The source relationship suggests a targeted test, not a claim that every other market shares the defect.
For fund-flow review, the priority is an anchored return transaction or a defensible allocation method at the mixed sender. A screenshot of its balance, a generic exchange label or an unrelated large payment would not answer that question. Full bytecode and execution records for the earlier deployment are separately needed to assess the claimed front-running relationship.
The evidence supports one reconciled path: net USDT leaves the BiFi handler, most is swapped for WETH, WETH becomes ETH, and the helper distributes ETH. The accounting is substantially firmer than the attribution and historical root cause. Those differences are the conclusion of this investigation, not details to smooth away.
Role | Ethereum address |
|---|---|
handler | |
helper | |
sender | |
builder | |
deployer | |
created | |
morpho | |
pool | |
usdt | |
weth | |
logic | |
model | |
storage |
Anchor / scope | Transaction |
|---|---|
B: deployment; block 26,210,255; 17 October 05:42:59 UTC | 0x15b47e2c0daf723dec64c75b435079d3a1f8a6058b21b9a64dda4844e877a034 |
A: execution; block 26,210,256; 17 October 05:43:11 UTC | 0x756c68055af7a0630aa0b56891ba4de14c56c39cbebe99e47eeb4728f4d6ad14 |
The tables below preserve all 142 explorer-displayed ERC-20 transfer rows in event order. They are not 142 separate transactions. USDT uses six decimal places and WETH eighteen in this inventory; the integer USDT event data were checked against every corresponding displayed amount and address. The separate WETH Withdrawal event records the subsequent unwrap; it is not an additional Transfer row. All these events share Anchor A's block and UTC time above.
Event / asset | From → to | Amount |
|---|---|---|
12 / USDT | 40,499,999.999997 | |
14 / USDT | 121,257.485029 | |
16 / USDT | 484,544.910179 | |
18 / USDT | 1,795,238.892215 | |
20 / USDT | 7,238,802.155389 | |
22 / USDT | 30,860,156.557185 | |
24 / USDT | 0 | |
26 / USDT | 1,498,500 | |
28 / USDT | 1,498,500 | |
30 / USDT | 1,498,500 | |
32 / USDT | 1,498,500 | |
34 / USDT | 1,498,500 | |
36 / USDT | 1,498,500 | |
38 / USDT | 1,498,500 | |
40 / USDT | 1,498,500 | |
42 / USDT | 1,498,500 | |
44 / USDT | 1,498,500 | |
46 / USDT | 1,498,500 |
Event / asset | From → to | Amount |
|---|---|---|
48 / USDT | 1,498,500 | |
50 / USDT | 1,498,500 | |
52 / USDT | 1,498,500 | |
54 / USDT | 1,498,500 | |
56 / USDT | 1,498,500 | |
58 / USDT | 1,498,500 | |
60 / USDT | 1,498,500 | |
62 / USDT | 1,498,500 | |
64 / USDT | 1,498,500 | |
66 / USDT | 1,498,500 | |
68 / USDT | 2,025,000 | |
70 / USDT | 1,498,500 | |
72 / USDT | 2,025,000 | |
74 / USDT | 1,498,500 | |
76 / USDT | 2,025,000 | |
78 / USDT | 1,498,500 | |
80 / USDT | 2,025,000 | |
82 / USDT | 1,498,500 |
Event / asset | From → to | Amount |
|---|---|---|
84 / USDT | 2,025,000 | |
86 / USDT | 1,498,500 | |
88 / USDT | 2,025,000 | |
90 / USDT | 1,498,500 | |
92 / USDT | 2,025,000 | |
94 / USDT | 1,498,500 | |
96 / USDT | 2,025,000 | |
98 / USDT | 1,498,500 | |
100 / USDT | 2,025,000 | |
102 / USDT | 1,498,500 | |
104 / USDT | 2,025,000 | |
106 / USDT | 1,498,500 | |
108 / USDT | 2,025,000 | |
110 / USDT | 1,498,500 | |
112 / USDT | 2,025,000 | |
114 / USDT | 1,498,500 | |
116 / USDT | 2,025,000 | |
118 / USDT | 1,498,500 |
Event / asset | From → to | Amount |
|---|---|---|
120 / USDT | 2,025,000 | |
122 / USDT | 1,498,500 | |
124 / USDT | 2,025,000 | |
126 / USDT | 1,498,500 | |
128 / USDT | 2,025,000 | |
130 / USDT | 1,498,500 | |
132 / USDT | 2,025,000 | |
134 / USDT | 1,498,500 | |
136 / USDT | 2,025,000 | |
138 / USDT | 1,498,500 | |
140 / USDT | 2,025,000 | |
142 / USDT | 1,498,500 | |
144 / USDT | 2,025,000 | |
146 / USDT | 165,163.833793 | |
148 / USDT | 247,951.408655 | |
150 / USDT | 121,257.485029 | |
152 / USDT | 484,544.910179 | |
154 / USDT | 1,795,238.892215 |
Event / asset | From → to | Amount |
|---|---|---|
156 / USDT | 7,238,802.155389 | |
158 / USDT | 30,860,156.557185 | |
160 / USDT | 0 | |
162 / USDT | 1,498,500 | |
164 / USDT | 1,498,500 | |
166 / USDT | 1,498,500 | |
168 / USDT | 1,498,500 | |
170 / USDT | 1,498,500 | |
172 / USDT | 1,498,500 | |
174 / USDT | 1,498,500 | |
176 / USDT | 1,498,500 | |
178 / USDT | 1,498,500 | |
180 / USDT | 1,498,500 | |
182 / USDT | 1,498,500 | |
184 / USDT | 1,498,500 | |
186 / USDT | 1,498,500 | |
188 / USDT | 1,498,500 | |
190 / USDT | 1,498,500 |
Event / asset | From → to | Amount |
|---|---|---|
192 / USDT | 1,498,500 | |
194 / USDT | 1,498,500 | |
196 / USDT | 1,498,500 | |
198 / USDT | 1,498,500 | |
200 / USDT | 1,498,500 | |
202 / USDT | 1,498,500 | |
204 / USDT | 2,025,000 | |
206 / USDT | 1,498,500 | |
208 / USDT | 2,025,000 | |
210 / USDT | 1,498,500 | |
212 / USDT | 2,025,000 | |
214 / USDT | 1,498,500 | |
216 / USDT | 2,025,000 | |
218 / USDT | 1,498,500 | |
220 / USDT | 2,025,000 | |
222 / USDT | 1,498,500 | |
224 / USDT | 2,025,000 | |
226 / USDT | 1,498,500 |
Event / asset | From → to | Amount |
|---|---|---|
228 / USDT | 2,025,000 | |
230 / USDT | 1,498,500 | |
232 / USDT | 2,025,000 | |
234 / USDT | 1,498,500 | |
236 / USDT | 2,025,000 | |
238 / USDT | 1,498,500 | |
240 / USDT | 2,025,000 | |
242 / USDT | 1,498,500 | |
244 / USDT | 2,025,000 | |
246 / USDT | 1,498,500 | |
248 / USDT | 2,025,000 | |
250 / USDT | 1,498,500 | |
252 / USDT | 2,025,000 | |
254 / USDT | 1,498,500 | |
256 / USDT | 2,025,000 | |
258 / USDT | 1,498,500 | |
260 / USDT | 2,025,000 | |
262 / USDT | 1,498,500 |
Event / asset | From → to | Amount |
|---|---|---|
264 / USDT | 2,025,000 | |
266 / USDT | 1,498,500 | |
268 / USDT | 2,025,000 | |
270 / USDT | 1,498,500 | |
272 / USDT | 2,025,000 | |
274 / USDT | 1,498,500 | |
276 / USDT | 2,025,000 | |
278 / USDT | 1,498,500 | |
280 / USDT | 2,025,000 | |
282 / USDT | 165,163.833793 | |
284 / USDT | 247,951.408655 | |
286 / USDT | 0 | |
288 / USDT | 0.000068 | |
289 / WETH | 68.057203111718789216 | |
290 / USDT | 165,574.514633 | |
292 / USDT | 40,499,999.999997 |
Claim | Basis / limitation |
|---|---|
USDT totals, status and UTC times | Direct explorer overview and decoded event reads; integer calculations reproducible from the preserved inventory. Not an independent node consensus check. |
ETH payouts | Direct explorer internal-transfer display, corroborated by provider trace. |
Incident-time delegate target | Provider call-trace report; not independently replayed. |
Idle-interest exploit mechanism / front-running | External reconstruction plus limited direct source inspection; historical state, exact replay and ordering causality unconfirmed. |
Later cash-out / recovery | Not established; follow-up coverage and allocation incomplete. |
Sources are linked beside the claims and in the exact records above. Explorer labels are descriptive leads, not proof of human identity or culpability.
4 reads