Reproduced Exploit
Hanji: nominal credit takes 100 from the honest balance
receiveTokens does not measure the balance increase after transferFrom. The fee token keeps 100, the book receives 900, and the credit increases by 1000. Withdrawing the credit pulls 100 of the honest trader's tokens.
Chain
Other
Category
logic
Date
Apr 2025
Source
AuditVault
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.
Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 55171-incorrect-handling-of-fee-on-transfer-tokens-mixbytes-none-h. Standalone Foundry PoC and full write-up: 55171-incorrect-handling-of-fee-on-transfer-tokens-mixbytes-none-h_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/logic/fee-calculation · vuln/input-validation/missing
Key info#
| Protocol | Hanji |
| Finding | MixBytes, AuditVault 55171 |
| Vulnerable code | LOB.receiveTokens |
| Harm | A 1000 deposit of a 10 percent fee-on-transfer token delivers 900 and is credited as 1000. The attacker withdraws 1000 and is up 100. The book has 900 left against the honest trader's 1000 credit. The fixed path credits 900 and the attacker is flat. |
| Chain | local synthetic |
TL;DR#
receiveTokens does not measure the balance increase after transferFrom. The fee token keeps 100, the book receives 900, and the credit increases by 1000. Withdrawing the credit pulls 100 of the honest trader's tokens.
The vulnerable code#
// @> VULN: credit increases by `amount`, not by the tokens that arrived
credit[from] += amount;
Root cause#
The credit uses the requested amount. A fee-on-transfer token delivers less than that amount.
Preconditions#
The book already holds 1000 backing an honest credit of 1000. The attacker's token takes a 10 percent fee on transferFrom and pays that fee to the attacker.
Attack walkthrough#
- Approve a 1000 pull. See output.txt.
receiveTokenspulls 1000. The book receives 900.- Credit increases by 1000.
- The attacker withdraws 1000.
- Attacker profit is 100.
- The honest credit of 1000 is backed by 900. The fixed path credits 900 and profit is 0.
Diagrams#
Impact#
The honest trader's 1000 credit is backed by 900. The attacker nets 100. Crediting the measured balance delta removes the profit.
Remediation#
Credit balanceAfter - balanceBefore from the transferFrom, and revert if that delta is not the expected amount.
How to reproduce#
cd 55171-incorrect-handling-of-fee-on-transfer-tokens-mixbytes-none-h_exp
forge test -vv
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 55171-incorrect-handling-of-fee-on-transfer-tokens-mixbytes-none-h_exp (evm-hack-registry mirror).
- AuditVault finding: 55171-incorrect-handling-of-fee-on-transfer-tokens-mixbytes-none-h.
Alerts & third-party analyses
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.