# Borrow fee uses APY as per-second rate, causing extreme overcharging

Bug Deep Dive #19 · 15 December 2025

Bug Deep Dives · [The Contest Academy](https://0xsimao.com/the-contest-academy) · 0xSimao

---

| Title | Borrow fee uses APY as per-second rate, causing extreme overcharging |
| Reward | $1196, 3 dups |
| Contest | Ammplify - 2 Sep 2025 on Sherlock |
| Author | blockace |
| Context | APY logic |

The borrow fee rate returned by the smooth rate curve is an annual percentage yield (APY), but the implementation multiplies it directly by elapsed seconds without annualizing. This treats an annual rate as a per-second rate, inflating fees by roughly \$31{,}536{,}000\times$ the intended amount. Borrowers are charged massive, unjustified fees even over short time intervals.

The function `chargeTrueFeeRate` in `src/walkers/Fee.sol` treats the APY returned by `calculateRateX64` as a per-second rate, multiplying it by the elapsed seconds `timeDiff` without dividing by the number of seconds in a year. The rate returned by the curve is annualised. The library documents a seconds-per-year factor of 31,536,000 and distinguishes APR from SPR:

```solidity
// src/walkers/Fee.sol
// ... inside FeeWalker.chargeTrueFeeRate( ... )
uint256 timeDiff = uint128(block.timestamp) - data.timestamp; // Convert to 256 for next mult
uint256 takerRateX64 = timeDiff * data.fees.rateConfig.calculateRateX64(
    uint64((totalTLiq << 64) / totalMLiq)
);

// lib/Commons/src/Math/SmoothRateCurveLib.sol
// ...
// SPR factor 31536000 = 365 * 24 * 60 * 60
// APR of 0.001% = 0.00001
// as a SPR = 0.00001 / 31536000 =  ...
```

The correct computation must divide by 365 days to convert the annual rate into a per-second rate before applying `timeDiff`.\
\
**Alpha:** the code would have been correct but for the comment stating what the variable holds — the return value could have been a per-second rate. Read those comments carefully.

**Conclusion**

This finding would earn you **\$4432**, and it is genuinely tricky: you have to establish whether `calculateRateX64` returns a per-second or an annual rate.

[**Full Report**](https://audits.sherlock.xyz/contests/1054/report)\
[**Codebase**](https://github.com/itos-finance/AmmplifyPublic/tree/beb942cfbd54990fc9434fbfa99a1fc251d73689)

---

Newer: [User can lose all funds when creating or increasing compounded Maker position due to share inflation](https://0xsimao.com/the-contest-academy/bug-deep-dive-20) · Older: [Takers pay significantly higher fees than expected due to borrow amounts being split across segments](https://0xsimao.com/the-contest-academy/bug-deep-dive-18)
