OpenZeppelin / OpenZeppelin/compact-contracts
L-02: Memo Growth Through Inefficient Allowance Revocation
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 55
- Forks
- 29
- Avg merge
- 5d 7h
- Merged PRs (30d)
- 25
Description
L-02 Memo Growth Through Inefficient Allowance Revocation
Severity: Low
Source: Midnight Foundation #02 — OpenZeppelin Compact Contracts Audit, Release 0.3.0-alpha.1 (2026-08-18)
Every credit appends an entry to the recipient's memo list, and the module records this as accepted residual griefing, stating that an attacker can spam dust credits to grow that list without bound, that only the recipient can clear it, that rejecting zero valued transfers would not help because dust at value one defeats it, and that a real fix is architectural and deferred. The behaviour is therefore known and accepted, and the reachability is as described, since the per- operation check bounds a value from above only and a debit of zero satisfies its balance comparison, so any registered account can call transfer repeatedly at zero or one and append a memo to the target's list each time. Two aspects sit outside what that note covers.
The first concerns the remedy. The disclosure counts the victim's costs as storage, scanning and the gas to clear, which presents pruning as an expense. Pruning is more than an expense, because the circuit that performs it warns that clearing is destructive and can lock funds, the memo list being the only record of amounts that the balance ciphertext does not yield directly. An attacker who inflates a memo list is therefore not only imposing a cost but pressing the victim toward an operation the module itself describes as dangerous, and the more effective the spam the stronger that pressure becomes.
The second concerns revocation. Setting an allowance to zero is the conventional way to withdraw a spender's authority, but approve refunds and removes any prior escrow and then writes a fresh entry encrypting the new value, so a zero valued approval leaves an entry in place rather than none. The requires only that an entry exist with a sufficient recorded amount, a condition zero meets against zero, so the spender retains a working route into the credit path and can continue appending memos with zero value to any target after the owner believes their authority has ended.
Consider having a zero valued approval remove the escrow entry rather than store an empty one, so that withdrawing authority leaves no callable path behind. Consider also recording alongside the griefing note that the recipient's only available response is destructive and can render funds unspendable, so that the cost of the accepted limitation is stated in full while the architectural fix remains outstanding.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in contracts/src/token/ConfidentialFungibleToken.compact, reading approve around lines 893-925 and the allowance check around lines 1070-1086. Trace the zero-approval path and the memo-growth note around lines 192-198 and 981-987; done means zero approval leaves no callable allowance entry and the note records the destructive clearing consequence.
Written by the indexing model from the issue text.
Assessment
- Domain
- blockchain, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100