AeternumAeternum
Back to App

Key Actors

The roles of the vault owner, the backup address, and the permissionless keeper network that executes recovery.


Three actors participate in the Aeternum protocol. Understanding each one's capabilities and limits is the foundation for trusting the system.


The Vault Owner (You)

The vault owner is the Ethereum address that called register(). This is the only address that can:

  • Deposit ETH into the vault
  • Send ETH from the vault to any address
  • Withdraw the full balance
  • Ping the timer
  • Update the backup address or inactivity period
  • Cancel the vault and withdraw funds

Every write function that touches your vault is protected by the onlyRegistered modifier, which checks that the caller is the registered owner:

modifier onlyRegistered() {
    if (!s_configs[msg.sender].isActive && !s_configs[msg.sender].isAbandoned) {
        revert AeternumVault__NotRegistered();
    }
    _;
}

No other address — not the backup address, not the contract deployer, not anyone — can call these functions on your behalf.


The Backup Address

The backup address is the destination for your ETH if recovery triggers. You choose it at registration and can update it at any time while your vault is active.

What the backup address can do: receive ETH when recovery executes.

What the backup address cannot do: nothing else. It cannot initiate transfers, read your vault config, or interact with your vault in any way while you are active. It is purely a recipient.

The backup address can be:

  • A wallet controlled by your chosen heir or primary beneficiary
  • A multisig wallet shared among your heirs or estate trustees
  • A backup wallet you control — a separate hardware wallet, cold storage, or a secondary EOA

Test your backup address before you rely on it

If your backup address is a smart contract (like a multisig), make sure it is configured to accept plain ETH transfers. A contract that reverts on receive() will cause recovery to fail. After three failures, the vault is abandoned. Test the full cycle on Sepolia before setting up on mainnet.

Blocked backup addresses: If recovery has failed three consecutive times against a backup address, that address is permanently blocked from being used in any new registration. This prevents accidental or repeated use of a broken address.


The Keeper Network — and Anyone Else

Unlike the vault owner and the backup address, this "actor" isn't a single fixed address. It's whoever calls triggerRecovery() on your behalf once your vault becomes eligible — and the contract places no restriction at all on who that can be.

In practice, this is almost always the Aeternum keeper bot, run by Aeternum Labs as a public good. Each cycle runs in three stages:

Scan. The bot queries its own off-chain database — populated in real time from on-chain events by an indexer — for wallets that look due for recovery. This costs nothing on-chain; it's a plain database query, not a contract call.

Validate. Every candidate from the scan is re-checked directly against the contract in a single batched on-chain read, to catch anything the database missed — a ping you sent moments ago, for instance. Only wallets confirmed due on-chain move forward.

Execute. Confirmed wallets are batched together and submitted as triggerRecovery() transactions on-chain, with the bot paying the ETH gas itself as an operating cost. A failure on one wallet in a batch — a backup address that rejects ETH, say — doesn't affect any other wallet in the same batch.

Cycles repeat roughly every 12 seconds, though the actual gap can stretch a little longer if a given cycle has a lot of recoveries to work through. The full technical pipeline — batching, gas estimation, and everything in between — is covered in Keeper Network.

What if the keeper bot goes down?

If the Aeternum Labs keeper bot were ever unavailable, your ETH would simply remain in your vault, unrecovered, until service resumed — or until someone else calls triggerRecovery() on your behalf, since the function has no access restriction. Gelato Network is planned as an independent backup keeper (Phase 2). Chainlink CRE joins in Phase 3 as a multi-chain orchestrator — a single off-chain service running one independent workflow per chain, each calling triggerRecovery() on that chain's own deployment, with no messaging between chains. All three are just additional, independently-operated callers of the same permissionless function. The worst-case outcome of any keeper outage is a delay in recovery, not loss of funds.

The contract also exposes getTriggerableVaultsBatch(startIndex, batchSize) — a free, permissionless on-chain view function that returns wallets due for recovery within a given slice of the registry. The Aeternum Labs bot doesn't currently use it; its own indexed database serves the same purpose. The function exists on the contract as a general-purpose tool available to anyone — other keeper operators, researchers, or tooling — who wants to query due wallets directly from chain state rather than run their own indexer.

Why no forwarder or access gate is needed. You might reasonably wonder what stops an arbitrary caller from doing something harmful with triggerRecovery() if literally anyone can call it. The answer isn't a permission check on the caller — there isn't one — it's that the function gives the caller no leverage to begin with. _executeRecovery() re-validates every condition from your on-chain configuration before moving a single wei: whether your vault is active, whether the timer has actually elapsed, and where the funds go. The caller supplies only a wallet address; they cannot redirect funds, force an early recovery, or influence the outcome in any way. Removing the single designated caller doesn't weaken this — it removes a dependency on any one party remaining available, without weakening what the contract itself enforces.

This is also why competing keepers are safe to run simultaneously. If two callers submit triggerRecovery() for the same wallet in the same block window, the first to land executes recovery normally; the second finds the vault already inactive and its balance already zero, and silently returns without reverting or double-spending.