Skip to content

Deposit Lifecycle

The deposit lifecycle begins before the transaction. It includes vault provisioning, admission intent creation, source-backed readiness checks, deposit execution, and evidence archival.

1. Provision The Validator Vault

The factory owner calls CenturionVaultFactory.deployVault(...) for a 48-byte validator pubkey. The factory:

  • derives sha256(pubkey);
  • deploys a CenturionBeaconProxy using the configured vault beacon;
  • records vaultByValidatorPubkeyHash[pubkeyHash];
  • marks isVault[vault] = true;
  • calls CenturionEconomicController.initializeSeat(...).

The deposit contract later relies on this mapping and vault metadata. If either is wrong, the deposit reverts.

2. Establish Governance And Baseline Coherence

At deposit initialization, the source stores baseline references for factory, controller, claim gatekeeper, exit-request contract, upgrade governor, and vault beacon. On every deposit it rechecks:

  • factory and controller metadata hashes;
  • address-derivation version;
  • exit-request contract address and code hash;
  • vault beacon address and authority;
  • governor policy assertions for every baseline component.

There is no deposit-local freeze step in the current source. Coherence is checked live.

3. Prepare The Admission Intent

The allowlist admin creates an intent with addAllowedDepositFor for the exact tuple:

  • pubkey;
  • withdrawal_credentials;
  • amountGwei;
  • authorizedDepositor;
  • current allowlistEpoch.

Default addAllowedDeposit is acceptable only when allowlistAdmin itself will submit the deposit for the default 32 CTN amount.

4. Verify Withdrawal Credentials

Withdrawal credentials must be canonical execution credentials:

  • 32 bytes total;
  • first byte 0x01;
  • bytes 1 through 11 all zero;
  • final 20 bytes equal the factory-registered vault address.

The deposit contract extracts the vault address from the credentials and verifies factory registration, pubkey binding, vault runtime code hash, live beacon, and controller readiness.

5. Submit Deposit

deposit(pubkey, withdrawal_credentials, signature, deposit_data_root) must be called by the authorized depositor and send exactly 32 CTN in Phase 1. The function rejects malformed pubkey, signature, credentials, non-gwei values, bad root, duplicate pubkey activation, missing intent, stale readiness, unsafe readiness, or policy drift.

6. Consume Intent And Append Merkle Leaf

After custody checks pass, the function consumes the active intent, emits consumption events, validates the deposit-data root, emits DepositEvent, increments depositCount, and inserts the deposit leaf into the merkle tree.

7. Archive Evidence

Archive:

  • allowlist transaction and DepositIntentAllowedFor;
  • caller address and allowlistEpoch;
  • factory vault mapping and vault metadata;
  • controller depositReadiness response;
  • governor policy assertions for deposit, controller, factory, gatekeeper, and beacon;
  • deposit transaction, DepositIntentConsumedFor, DepositEvent, and post-deposit depositCount.

Failure Modes

Failure Likely layer Operator response
DepositIntentNotAllowlisted Permissioning Recompute intent using caller, amount, and current allowlistEpoch.
DepositIntentAlreadyConsumed Replay protection Stop; do not try to reuse the same tuple. Create a new valid tuple only if source policy allows it.
Phase1DepositMustBeExactly32CTN Amount policy Correct value; Phase 1 does not admit partial validator deposits.
NonCanonicalWithdrawalCredentials Custody route Rebuild credentials from the factory-previewed vault address.
VaultReadinessUnproven Economic safety Refresh controller readiness inputs and reserve proof.
VaultReadinessReserveProofStale Economic safety Update reserve proof before retrying.
ImplementationNotApproved or metadata mismatch Governance Treat as governance incident until the live target and policy registry are reconciled.
## Four-Layer Completion Checklist
Layer Question Deposit evidence
Upgrade governance Which code is official? Governor assertions for deposit, factory, controller, claim gatekeeper, and beacon.
Deposit permissioning Who may deposit? Active intent hash for pubkey, credentials, amount, caller, and allowlistEpoch.
Custody/readiness Is the deposit route safe? Factory registration, vault metadata, beacon authority, router bootstrap closed, controller readiness.
Economic/claim safety Can funds later leave safely? Reserve coverage, safe risk state, trigger armed, beneficiary initialized, schema/policy match.

A deposit is not operationally ready until all four rows have current evidence. If one row is missing, write Evidence required and stop the procedure.

Operator Timing Notes

Intent creation should happen late enough that the allowlistEpoch, caller, amount, and withdrawal credentials are still current, but early enough that the authorized depositor can review the full evidence packet before submitting value. If the allowlist admin rotates, old intent preimages stop matching because the source increments allowlistEpoch on acceptAllowlistAdmin.

Do not consume the intent as a readiness test. The deposit path clears allowedDeposits and marks consumedIntents only during the real deposit call. Dry runs should use read-only hash recomputation, factory/vault/controller reads, and governor assertion calls rather than a live deposit attempt.