Reproduced Exploit
Ammplify — H-5: Borrow fee uses APY as per-second rate (extreme overcharge)
1. Smooth rate curve returns an annual rate (APY) in Q64.64. 2. chargeTrueFeeRate does takerRateX64 = timeDiff * calculateRateX64(util) with no / 365 days. 3. Even 1 second of borrow accrues ~22% of principal at the PoC rate; intended fee is dust. 4. Closing a taker position drains collateral via c…
Chain
Other
Category
untagged
Date
Sep 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: 63171-h-5-borrow-fee-uses-apy-as-per-second-rate-causing-extreme-o. Standalone Foundry PoC and full write-up: 63171-h-5-borrow-fee-uses-apy-as-per-second-rate-causing-extreme-o_exp in the
evm-hack-registrymirror.
Vulnerability classes: fee-calculation · wrong-state · fee-accounting · timestamp-dependence
Reproduction: a self-contained Foundry PoC that compiles & runs in an isolated project with only
forge-std— no fork, no RPC, noanvil_state. Full trace: output.txt. PoC: test/63171-h-5-borrow-fee-uses-apy-as-per-second-rate-causing-extreme-o_exp.sol.
AuditVault taxonomy: severity/high · sector/dex · sector/lending · platform/sherlock · fee-calculation · wrong-state · fee-accounting · integer-bounds · timestamp-dependence
Key info#
| Impact | HIGH — borrowers overcharged ~31,536,000× (APY treated as per-second) |
| Protocol | Ammplify (itos-finance) |
| Vulnerable code | FeeWalker.chargeTrueFeeRate multiplies annual rate by timeDiff without / 365 days |
| Bug class | Unit mismatch (annual rate × seconds) |
| Finding | Sherlock 2025-09-ammplify · #63171 / issue 379 · reporters ARMoh, SOPROBRO, blockace |
| Report | sherlock-audit/2025-09-ammplify-judging |
| Source | AuditVault |
| Status | Audit finding — fixed in itos-finance/Ammplify PR #40. Reproduced as a standalone local PoC. |
| Compiler | ^0.8.24 (PoC) |
TL;DR#
- Smooth rate curve returns an annual rate (APY) in Q64.64.
chargeTrueFeeRatedoestakerRateX64 = timeDiff * calculateRateX64(util)with no/ 365 days.- Even 1 second of borrow accrues ~22% of principal at the PoC rate; intended fee is dust.
- Closing a taker position drains collateral via catastrophic fees.
The vulnerable code#
uint256 timeDiff = uint128(block.timestamp) - data.timestamp;
uint256 takerRateX64 = timeDiff * data.fees.rateConfig.calculateRateX64(
uint64((totalTLiq << 64) / totalMLiq)
); // @> VULN: APY used as per-second — missing / 365 days
// FIX: FullMath.mulDiv(timeDiff, calculateRateX64(...), 365 days)
Root cause#
Annual rate applied as if it were already a per-second rate. Library docs (SmoothRateCurveLib) define SPR = APR / 31_536_000; the walker never applies that conversion.
Preconditions#
- Non-zero taker liquidity / borrow so fees are charged.
- Any positive elapsed time between open and charge (even 1 second).
Attack walkthrough#
- Open borrow with 50e18 principal at ~50% util.
chargeTrueFeeRatemultiplies APY by elapsed seconds.- Fee = principal × inflated rate ≫ annualized intent.
- Borrower pays orders-of-magnitude more than designed.
Diagrams#
Impact#
Catastrophic borrower overcharging for any non-zero hold time; potential total loss of collateral on brief borrows.
Sources#
- AuditVault finding #63171
- Sherlock 2025-09-ammplify judging #379
- Reduced source: sherlock-audit/2025-09-ammplify —
src/walkers/Fee.solchargeTrueFeeRate(fix: itos-finance/Ammplify PR #40)
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 63171-h-5-borrow-fee-uses-apy-as-per-second-rate-causing-extreme-o_exp (evm-hack-registry mirror).
- AuditVault finding: 63171-h-5-borrow-fee-uses-apy-as-per-second-rate-causing-extreme-o.
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.