Skip to content

EVM: cancelExpired is permissionless but unincentivized — document the keeper model or who is expected to call it #175

Description

@Nexha-dev

Context

cancelExpired(intentHash) on the escrow is permissionless and refunds the locked funds to the user once deadline + confirmationGrace has passed. The caller pays gas and receives nothing; the beneficiary is always l.user.

Problem

As with the Soroban cancel path, there is no incentive for a third party to call cancelExpired, so in practice only the user (or someone acting for them) will. That is more workable than the Stellar side because the user is on this chain and motivated to recover their own funds — but it still assumes the user is watching, holds gas, and knows to call the function. A non-technical user who bridged through a front-end may not realize they must self-trigger a refund after a failed bridge. The "permissionless refund" is only a guarantee if someone reliably calls it, and the repo does not document who that someone is or provide tooling for it.

Proposed direction

Document the expected caller (the user, via the SDK/front-end) and provide an SDK helper plus front-end guidance that detects an expired, still-locked intent and offers a one-click cancelExpired. Consider a modest keeper reward funded from a protocol fee so refunds happen even when the user is absent. At minimum, the SDK's waitForSettlement/status surface should make it obvious when an intent is refundable and how to recover it. Coordinate with the Soroban keeper-incentive issue and the SDK status-transition work.

Acceptance criteria

The expected caller of cancelExpired is documented, the SDK/front-end can detect a refundable intent and trigger recovery, and either a keeper incentive exists or the user-self-serve path is robust and clearly surfaced; the refund-liveness assumption is stated in the docs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions