ERC-8474: ERC-20 Delayed Unlock

I would like feedback on ERC-8474, an opt-in ERC-20 extension for holder-controlled outgoing transfer locks with a block-based unlock delay and an independent locking guardian.

Proposal and specification: Add ERC: ERC-20 Delayed Unlock by shargon · Pull Request #2129 · ethereum/ERCs · GitHub

Motivation

Cold storage protects keys at rest, but a compromised signing interface can still induce an unwanted, valid signature. The goal is to provide an on-chain response interval before protected tokens can leave an account.

Proposed behavior

  • A holder enrolls with a nonzero cooldown and a separate guardian, immediately locking positive outgoing movements.
  • Only the holder can request an unlock. Transfers remain blocked until the request block plus the cooldown.
  • The holder or guardian can relock immediately, cancelling the countdown. The guardian cannot unlock or transfer funds by virtue of its role.
  • Enrollment, cooldown and guardian are immutable in this minimal interface.
  • Enforcement covers transfer, transferFrom, burns, self-transfers and other positive debit paths, including spending through existing approvals. Incoming transfers remain possible.
  • The proposal standardizes the interface, events and state transitions; it does not mandate a particular implementation.

Tradeoffs and feedback requested

This requires token-side support and cannot retrofit existing immutable tokens. It does not reverse transfers or guarantee that a guardian transaction wins ordering at the unlock deadline. A compromised guardian can deny service, and immutable parameters create recovery tradeoffs.

I would especially welcome feedback on the interoperability value of the interface, the immutable enrollment model, guardian recovery tradeoffs, and integration with wallets and custodians.

Author: Fernando Díaz Toledano (@shargon).

The part I’d look at is the Unlocked state. It never expires, and U is public from the moment requestUnlock lands, so every allowance the holder still has becomes usable in block U. Someone who opens the account for one payment also reopens every old max approval, and a drainer only has to watch UnlockRequested and land its transferFrom in block U, next to the holder’s own transfer. An optional relock window fixed at enrollment (Unlocked only while U <= b < U + N, then Locked again without a transaction) keeps maturity automatic and only ever restricts, so it doesn’t weaken the immutability argument.

On guardian recovery, BIP-345 (OP_VAULT) uses the same trigger and delay shape and adds a recovery path that sweeps to an address fixed when the vault is created. Here that would be an immutable recoveryAddress set at enrollment and a guardian call that can only move the balance there. The guardian still can’t send funds anywhere else, and a compromised holder key stops being a standoff. Today the attacker and the real owner hold the same key, so every time the guardian lets a countdown finish both can transfer at U and the faster one wins. The cost is that the recovery address becomes the thing to protect, so the disclosure before enrollment would need to say it.