Skip to content

Undelegate accepted before the base delegation materializes permanently locks the ATA on the ER #138

Description

@GabrielePicco

Problem

A private-send recipient can call UndelegateEphemeralAta on the ER before the deferred base materialization of the eATA delegation has landed. Nothing in the API/SDK/program flow prevents this ordering, and it permanently locks the recipient's ATA on the ER:

  1. A private send delivers ER-side first (MergeShuttleIntoEphemeralAta); the base materialization (init + delegate eATA) is deferred.
  2. The recipient sends UndelegateEphemeralAta → the ER schedules a commit-and-undelegate intent and runs mark_account_as_undelegated on the ATA (owner→delegation program, undelegating=true, delegated=false).
  3. The base settlement of that intent can never succeed: the eATA has no delegation record on base yet. The intent dies; the ER-side lock is never rolled back.
  4. The deferred materialization then lands on base. The ER's post-delegation actions fail with PostAct IllegalOwner against the locked ATA.
  5. Every subsequent undelegate fails with ReadonlyDataModified ("account … is required to be writable and delegated") until an operator intervenes with ModifyAccounts. Funds are not at risk (the base eATA state holds the amount, backed by the vault), but the user's exit path is dead.

Observed on mainnet with a real payment; recovery required manual ops intervention.

Validator-side hardening is addressed separately (startup recovery sweep + slot-aware refresh guard for stale undelegating marks). This issue tracks preventing the flow from e-token's side.

Suggested prevention

  • API/SDK: refuse (or defer) undelegate while the eATA's base delegation record does not exist yet — delegation status is already available via the router (getDelegationStatus), and the balance endpoints return eATA delegation state since feat: return eATA delegation state from balance endpoints #135.
  • Optionally program/flow-side: don't expose a spendable ER balance until the base delegation record is confirmed, or gate ix 5 on a materialization marker.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions