OAK — OnChain Attack Knowledge

Worked example · 2023-20

Fee-on-Transfer Token Accounting Exploit Cohort — multi-chain (EVM, BNB Chain, Polygon, Arbitrum) — 2023–2025

Loss
no consolidated figure. The earlier draft's per-incident figures for 2023–2025 ($1.2M, $3.8M, $2.1M, $4.5M, a $15M cumulative total) could not be traced to any source and were removed. Sourced examples of the class: Balancer, June 2020, roughly $450K–$500K via the deflationary STA token ([coindeskbalancer]); Zabu Finance (Avalanche), 2021-09-12, about $3.2M in ZABU via the deflationary SPORE token ([halbornzabu]).
Recovery
not asserted; the earlier draft's $800K white-hat recovery claim was unsourced and removed.
OAK Techniques observed
OAK-T1.005 (Hidden Fee-on-Transfer — the load-bearing token-contract primitive: the deposited token's transfer function deducts a fee during transfer / transferFrom, reducing the actual token amount received by the protocol contract relative to the amount the protocol's accounting logic records). OAK-T5.003 (Hidden Mint / Balance-Inflation Exploit — structurally adjacent: the protocol's internal accounting records a deposit amount that exceeds the actual tokens received, creating an artificial balance inflation that functions as an "internal mint" — the attacker can withdraw against the inflated balance, extracting more tokens than they deposited, with the delta funded by other depositors' assets). OAK-T9.004 (Access-Control / Accounting Misconfiguration — the protocol's deposit function does not validate that the amount received matches the amount recorded; the accounting mismatch is a logic error that exists because the protocol's accounting model assumes a standard ERC-20 transfer semantic that the deposited token does not honour).
Attribution
pseudonymous Individual exploiters across the cohort are distinct pseudonymous addresses; no evidence of a shared operator cluster across incidents has been publicly documented. The exploitation pattern — deposit fee-on-transfer tokens, exploit the accounting mismatch, withdraw against the inflated balance — is templable (a single transaction shape) and has been replicated by multiple independent actors. The attribution pattern is structurally similar to T10.002 "mob attack" cases (Nomad) where the underlying flaw is templable and exploitation fragments across multiple independent actors.
Key teaching point
Any protocol that accepts arbitrary ERC-20 token deposits must validate the actual token amount received after transfer — not the amount the user requested to deposit — and must reject tokens whose post-transfer balance delta differs from the pre-transfer accounting record. The standard ERC-20 transfer and transferFrom functions return a boolean success value, not the actual amount transferred; a token whose transfer function deducts a fee will return true (the transfer succeeded) but will deliver fewer tokens than the amount parameter specified. A protocol that records the amount parameter as the user's deposit — without checking the protocol's actual token balance before and after the transfer — creates an accounting mismatch that is exploitable by construction. The structural OAK lesson is that the protocol's accounting model must be invariant under the token's actual transfer semantics — not under the standard ERC-20 transfer semantic that the token may not honour.
Corrected 2026-10-11
removed four unsourced 2023–2025 incidents and their dollar figures; the class is real and now anchored on Balancer (2020) and Zabu Finance (2021), so the '2023' start date is wrong.

Summary

Fee-on-transfer tokens are ERC-20 tokens whose transfer and transferFrom functions deduct a fee from the transferred amount before crediting the recipient. The standard ERC-20 specification does not require that the recipient receive exactly the amount parameter — the specification only requires that the transfer function update balances, emit a Transfer event, and return true on success. A token that deducts a 2% fee on every transfer will, when transfer(recipient, 100) is called, credit the recipient with 98 tokens and emit a Transfer(sender, recipient, 100) event — the event reports the pre-fee amount, not the post-fee amount received. This is a deliberate design choice in fee-on-transfer token implementations (used for "reflection" tokens, auto-LP tokens, and charitable-donation tokens where the fee funds a protocol treasury or a burn address), but it creates an accounting mismatch in any receiving contract that assumes the amount parameter equals the tokens received.

Multiple DeFi protocols have been exploited through this accounting mismatch since at least 2020 (Balancer, [coindeskbalancer]; Zabu Finance, [halbornzabu]). The exploitation pattern is structurally identical across the cohort:

  1. The attacker identifies a protocol that accepts arbitrary ERC-20 token deposits and whose deposit function records the user-supplied amount parameter without validating the actual tokens received.
  2. The attacker acquires a fee-on-transfer token — either by deploying one or by identifying an existing token with a non-zero transfer fee.
  3. The attacker calls the protocol's deposit function with amount = X. The protocol records a deposit of X tokens. The token's transfer function deducts a fee (e.g., 2%), delivering 0.98X tokens to the protocol. The protocol's accounting now records a balance of X for the attacker, but the protocol's actual token balance has increased by only 0.98X.
  4. The attacker calls the protocol's withdraw function, withdrawing against the recorded balance of X tokens. The protocol transfers X tokens to the attacker, drawing from the pool of other depositors' tokens to cover the 0.02X shortfall.
  5. The attacker repeats the deposit-withdraw cycle, each time extracting the fee delta (the difference between the recorded deposit amount and the actual tokens received), until the protocol's token balance is drained or the exploit is detected.

The accounting mismatch is a balance-inflation primitive — the protocol's internal accounting records a larger balance than the actual tokens held, creating an artificial "internal mint" (T5.003) that the attacker can withdraw against. The load-bearing vulnerability is the protocol's failure to validate the actual token amount received after transfer (T9.004 — accounting misconfiguration). The fee-on-transfer token itself is the T1.005 primitive — the token's transfer fee is embedded in its immutable bytecode and is applied uniformly to all transfers, making it distinguishable from T1.001 (modifiable tax) where the fee can be changed post-deployment.

The cohort's structural feature is that the exploitation primitive is protocol-agnostic — any protocol whose deposit function records the user-supplied amount parameter without post-transfer balance validation is vulnerable, regardless of the protocol's other security properties (audit status, oracle architecture, access-control model). The mitigation — post-transfer balance-delta validation — is canonical and one-line: require(balanceAfter - balanceBefore == amount, "fee-on-transfer token"). The fact that this mitigation was not universally applied across DeFi protocols by 2023 reflects a defender-side gap in the standard smart-contract-development curriculum rather than a novel attack vector.

Timeline (cohort-scale)

When Event OAK ref
2020-06 Balancer pools drained of roughly $450K–$500K using flash loans and the fee-charging STA token, which broke pool balance accounting ([coindeskbalancer]) T1.005 + T5.003
2021-09-12 Zabu Finance farm drained of about $3.2M: the contract credited the pre-fee SPORE amount staked, not the amount received ([halbornzabu]) T1.005 + T9.004
2023–2025 Earlier drafts listed four further incidents (BNB Chain, Ethereum, Arbitrum, Polygon) with dollar figures; none could be sourced and they are removed (unverified, removed)

Realised extraction

Sourced losses: Balancer (June 2020) roughly $450K–$500K ([coindeskbalancer]); Zabu Finance (2021-09-12) about $3.2M ([halbornzabu]). No cohort-wide total is asserted. The mechanism is the same in both: the protocol credits the requested amount rather than the amount received, so other depositors' assets fund the shortfall.

References

  • Per-protocol post-mortems (2023–2025) — individual incident disclosures; the cohort's public record is fragmented across protocol-specific post-mortems rather than consolidated in a single industry survey.
  • Token Sniffer / GoPlus / RugCheck — per-token fee-on-transfer detection; these scanners surface the fee-on-transfer attribute at the token level but do not detect the protocol-level accounting-mismatch vulnerability.
  • Solidity security best-practices guidance — post-transfer balance-validation as a standard smart-contract-development recommendation; the balanceAfter - balanceBefore == amount check canonically documented in Consensys / OpenZeppelin / Trail of Bits smart-contract-security guidance.

Public references

Discussion

The fee-on-transfer accounting exploit cohort is structurally important to OAK because it demonstrates a T1.005 exploitation pattern that is protocol-level (the victim is the protocol and its depositors, not individual traders interacting with the token) and that chains downstream into T5.003 (balance-inflation mint) and T9.004 (accounting misconfiguration). The existing T1.005 examples (2020 Uniswap V2 honeypot wave, 2024 Q4 cross-chain honeypot cohort) anchor the token-level exploitation surface — traders buying a fee-on-transfer token whose fee is not visible in the DEX UI. This cohort anchors the protocol-level exploitation surface — protocols whose deposit accounting assumes a standard ERC-20 transfer semantic that the token does not honour.

The distinction matters because the defender surface is different at each level. Token-level T1.005 defence requires pre-trade simulation across a fee-predicate matrix (caller, counterparty, size, time conditions). Protocol-level T1.005 defence requires post-transfer balance-delta validation in every function that accepts an arbitrary ERC-20 token deposit — a one-line check that is protocol-agnostic and that any DeFi protocol accepting arbitrary tokens should implement by default. That protocols were exploited this way in both 2020 and 2021 despite a one-line mitigation is a recurring OAK observation: a known mitigation whose deployment lags its documentation is a standing vulnerability surface.

The cohort also demonstrates the T1.005 + T5.003 chain that recurs across the T1 Tactic. Fee-on-transfer tokens are a T1.005 primitive — the fee is embedded in immutable bytecode and is applied uniformly to all transfers (distinguishing it from T1.001's modifiable tax). The protocol's accounting mismatch creates an internal balance inflation — a T5.003 primitive where the protocol's internal ledger records more tokens than it actually holds. The chain from T1.005 (token-level fee) to T5.003 (protocol-level balance inflation) to T9.004 (accounting misconfiguration) is the canonical multi-Technique chain for this exploitation class, and contributors writing future T1.005 examples involving protocol-level exploitation should preserve this cross-classification.

The cohort is classified primarily under T1.005 rather than T5.003 or T9.004 because the load-bearing primitive is the fee-on-transfer token's transfer semantics — without the fee-on-transfer behaviour, the accounting mismatch does not exist. T5.003 (balance inflation) and T9.004 (accounting misconfiguration) are downstream consequences of the T1.005 primitive, not independently exploitable vulnerabilities. The structural OAK lesson — that a protocol's accounting model must be invariant under the token's actual transfer semantics — is a T1.005 lesson that applies regardless of whether the specific exploitation chain involves balance inflation (T5.003) or a different downstream extraction primitive.

Techniques demonstrated (3)