Quantstamp reviewed OnRe (OnRe EVM) on 22 Sep 2026: 11 findings, 0 critical; 3 marked fixed, 8 acknowledged.
Report hosted on certificate.quantstamp.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 0 | 2 | 1 |
| Low | 0 | 6 | 2 |
The Prop AMM tracks net sell volume across discrete time windows of length`epochDurationSeconds` to adjust dynamic wall liquidity and apply redemption haircuts. However, epoch boundaries are not aligned with absolute time (e.g., using `block.timestamp % epochDuration`). Instead, epochs are event-driven and updated lazily on trade execution by setting `state.epochStart = uint64(currentTime)`. Because the decay calculation evaluates time elapsed relative to this stateful `epochStart` timestamp, historical volume does not decay smoothly across real time during low-activity periods. This introduces two primary vulnerabilities: 1. **Frozen & Prolonged Decay:** If trading halts after a high-volume sell-off, the historical volume penalty remains frozen at high severity. When a trade finally occurs long after the epoch should have ended, the protocol treats the elapsed time as a fresh epoch rollover (`elapsed >= epochDuration`), applying the full historical penalty to the new trade and re-anchoring `epochStart` to the current block timestamp. This extends the penalty's decay window far beyond its intended duration. 2. **Incentivized Market Freeze:** If a user trades between `1.0 * epochDuration` and `1.99 * epochDuration` after a spike in sell volume, they absorb 100% of the historical penalty and restart the full decay clock for everyone else. However, if all users wait past the `2 * epochDuration` threshold, the contract evaluates `elapsed >= epochDuration * 2` and completely wipes `previousNet` to 0. This creates an unaligned incentive where rational users are forced to freeze trading until the `2.0 * epochDuration` threshold passes to avoid absorbing an unfair haircut.
The protocol uses an emergency killswitch that is described to prohibit minting and redeeming tokens while allowing token transfers, quotes, and other view functions. We highlight the following locations where the killswitch may depart from the specification: - `LibOnReVault._withdrawConfigurableVault()`: `isKilled` is checked before processing any withdrawal. This blocks fee, proceeds, liquidity, and buffer-reserve transfers to their configured destinations. - `LibOnReOffer._previewExecution()`: This function routes previews through `_requireExecutableOfferConfig`, which reverts when killed. This freezes all quotes. - `LibOnReBuffer.setBufferGrossApr()` and `LibOnReBuffer.setBufferFeeConfig()`: Buffer configuration changes can still result in a mint. Both functions settle accrued returns through `_accrue()` and a potential downstream call to `IManagedToken.mintBuffer()` without checking the killswitch. - `ManagedToken.mintBuffer()`: Direct token supply changes remain possible for authorized minters / burners.
The token contract exposes the `burnFrom` function to facilitate burns using allowances. However, since this function forces a call to `_spendAllowance()`, it will revert if the caller attempts to burn from their own balance (`account = msg.sender`). This may cause unexpected reverts for integrating protocols and thus composability issues.
The report names a repository or files. Open the report to see its scope.
236 projects reviewed · 332 reports · latest Oct 2026
See Quantstamp’s auditsSomething wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us