Skip to content

IB20: add from/to/amount/nonce to Memo event#38

Closed
eric-ships wants to merge 1 commit into
mainfrom
eric/memo-event-nonce
Closed

IB20: add from/to/amount/nonce to Memo event#38
eric-ships wants to merge 1 commit into
mainfrom
eric/memo-event-nonce

Conversation

@eric-ships
Copy link
Copy Markdown
Collaborator

Motivation

The previous Memo(bytes32 indexed memo) event required indexers to correlate it to the preceding Transfer log via logIndex - 1. This coupling is fragile: any log interleaved between Transfer and Memo breaks the join silently. Even with from/to added, the identity is not unique — the same sender can pay the same recipient the same amount with the same memo multiple times (retries, repeated invoices).

The new signature is fully self-contained and unconditionally unique:

Memo(address indexed from, address indexed to, uint256 amount, bytes32 indexed memo, uint256 nonce)

nonce is a per-token monotonic counter that increments on every *WithMemo call, guaranteeing uniqueness even when (from, to, amount, memo) repeats. No join to Transfer is needed; indexers can consume Memo alone.

What changed

  • IB20.sol: Memo event gains from, to, amount, nonce; natspec updated
  • MockB20Storage: memoNonce uint256 appended at MEMO_NONCE_OFFSET = 15
  • MockB20: all four *WithMemo functions read-increment-emit the nonce
  • Memo test files: vm.expectEmit updated to assert the full new signature

What was tried / considered

Adding only from/to was considered but rejected: (from, to, memo) is still not unique if the same invoice is retried. Adding amount was also considered but (from, to, amount, memo) is similarly non-unique. A contract-level nonce is the only mechanism that gives unconditional uniqueness without relying on log position.

No ERC is broken: Transfer (ERC-20) is unchanged. Memo is a custom extension not defined by any standard.

The previous Memo(bytes32 memo) required indexers to join to the
preceding Transfer log via logIndex - 1, which breaks if any log is
interleaved. The new signature is fully self-contained:

  Memo(address indexed from, address indexed to, uint256 amount,
       bytes32 indexed memo, uint256 nonce)

nonce is a per-token monotonic counter (stored in MockB20Storage at
MEMO_NONCE_OFFSET = 15) that increments on every *WithMemo call,
guaranteeing uniqueness even when (from, to, amount, memo) repeats.

No ERC is broken: Transfer (ERC-20) is unchanged; Memo is a custom
extension not defined by any standard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants