DepositContractCTN¶
Source: DepositContractCTN.sol in /Users/marcos/Desktop/centurion_phase1_upgradeable_refactor.
DepositContractCTN is the Phase-1 validator deposit entrypoint. It preserves the deposit-contract interface shape (deposit, get_deposit_root, get_deposit_count, supportsInterface) while adding Centurion-specific admission and custody checks before a validator can enter the system.
Current refactor correction
The current source has no baselineVaultFactoryFrozen, no freezeBaselineVaultFactory, no setBaselineVaultFactory, no setBaselineVaultRuntimeCodehash, no phase1CustodyChecksEnabled, no pubkeyAllowlistEnabled, no pubkeyAllowlistDisabledForever, and no ownerOnlyDepositorEnabled. Older handbook text that treated those as live controls was stale.
Implementation Metadata¶
| Item | Source value |
|---|---|
| Contract kind | CENTURION_KIND_DEPOSIT |
| Implementation version | DepositContractCTNUpgradeableV2 |
| Economic policy hash label | EFFECTIVE_BALANCE_COVERAGE_HYBRID |
| Upgrade shape | Transparent proxy implementation using CenturionInitializable |
Control Planes¶
The deposit path has four separate safety layers:
- Upgrade governance decides which implementation code is official. The live deposit proxy, factory proxy, controller proxy, claim-gatekeeper proxy, and vault beacon must satisfy
CenturionUpgradeGovernorpolicy assertions. - Deposit permissioning decides who may submit a deposit. The current source always requires an allowlisted intent keyed to the caller.
- Custody and route safety prove the withdrawal credentials route to a factory-registered Centurion vault with the expected beacon, controller, exit-request contract, and metadata.
- Economic and claim safety proves the target vault is deposit-ready through controller readiness data, reserve coverage, schema versions, risk state, trigger state, and claim-gatekeeper coherence.
Do not merge these into one operational question. A deposit can be permissioned but unsafe, or governance-approved but not permissioned for a specific depositor.
| Required phrase | Source-grounded boundary |
|---|---|
| Upgrade governance | Governor policy assertions decide whether code and beacon targets match the expected policy. |
| Deposit permissioning | allowlistAdmin and intent maps decide whether this sender may attempt this deposit. |
| Custody/readiness | Baseline route checks decide whether this validator vault path is safe enough to accept funds. |
| Economic/claim safety | Readiness and accounting checks decide whether the later claim and settlement assumptions are safe. |
Key State¶
| State | Meaning | Operational implication |
|---|---|---|
depositCount | Number of accepted deposits. | Must increment exactly once after successful merkle insertion. |
branch, zeroHashes | Deposit tree state. | Supports deposit-root compatibility checks. |
allowlistAdmin | Only account that can add/remove admission intents. | Should be a hardened admission Safe, not an EOA. |
pendingAllowlistAdmin | Two-step allowlist-admin transfer target. | Requires explicit acceptance; old intents are invalidated on acceptance. |
allowlistEpoch | Monotonic epoch included in intent hashes. | Changes on allowlist-admin transfer, invalidating stale intents. |
allowedDeposits | Active intent map. | Must contain the exact hash for pubkey, credentials, amount, caller, and epoch. |
consumedIntents | One-way replay-prevention map. | A consumed intent cannot be re-allowlisted. |
baselineVaultFactory and metadata hashes | Factory and static configuration captured during initialization. | Every deposit rechecks live factory/controller metadata against these values. |
baselineUpgradeGovernor, baselineVaultBeacon | Governance and beacon anchors. | Every deposit rechecks live policy registry and beacon authority. |
phase1ValidatorActivated | One-time latch per validator pubkey hash. | Prevents duplicate Phase-1 activation for the same pubkey. |
Public Entry Points¶
| Function | Caller | Effect |
|---|---|---|
initialize(...) | Deployment initializer | Sets allowlist admin and stores validated baseline references. |
deposit(...) | Authorized depositor from intent hash | Performs format, amount, custody, readiness, intent, root, and merkle checks. |
addAllowedDeposit, addAllowedDeposits | allowlistAdmin | Adds default 32 CTN intents for the current admin as depositor. |
addAllowedDepositFor, addAllowedDepositsFor | allowlistAdmin | Adds explicit amount/depositor intents. |
removeAllowedDeposit, removeAllowedDepositFor | allowlistAdmin | Clears active intents without marking them consumed. |
isAllowedDepositIntent, isAllowedDepositIntentFor | Anyone | Reads active intent status. |
transferAllowlistAdmin, acceptAllowlistAdmin, cancelAllowlistAdminTransfer | Current or pending allowlist admin | Two-step admission-admin rotation; acceptance increments allowlistEpoch. |
get_deposit_root, get_deposit_count, supportsInterface | Anyone | Deposit-contract compatibility views. |
Deposit Path¶
- Validate pubkey length (
48), withdrawal-credentials length (32), and signature length (96). - Require
msg.value >= 1 ether, exact gwei granularity, and amount that fitsuint64. - Run
_enforcePhase1CustodyBaseline; current Phase-1 source requires exactly32_000_000_000gwei. - Reject a pubkey hash already latched in
phase1ValidatorActivated, then latch it. - Compute intent hash as
keccak256(abi.encode(pubkey, withdrawal_credentials, amountGwei, msg.sender, allowlistEpoch)). - Require
allowedDeposits[intentHash] == true. - Clear
allowedDeposits[intentHash], setconsumedIntents[intentHash] = true, and emit consumption events. - Recompute the deposit data root and reject mismatches.
- Emit
DepositEvent, incrementdepositCount, and insert the leaf into the merkle tree.
Replay and sender binding
The authorized depositor is part of the intent hash. A relayer, operator, or Safe module cannot substitute itself for the intended caller unless the allowlist admin created an intent for that exact address.
Custody Baseline Checks¶
_enforcePhase1CustodyBaseline proves all of the following before a deposit is accepted:
- baseline factory is configured;
- amount is exactly 32 CTN in gwei;
- withdrawal credentials are canonical execution credentials (
0x01plus zero padding and the vault address); - factory metadata matches stored
factoryConfigHash,moduleSetHash,immutableConfigHash, address-derivation version, controller, and exit-request contract; - upgrade governor and vault beacon match stored baseline addresses;
- vault beacon authority is the upgrade governor;
- governor policy assertions pass for deposit, factory, controller, claim gatekeeper, and withdrawal-vault beacon;
- treasury router bootstrap is closed;
- vault is factory-registered and has the expected beacon-proxy runtime code hash;
- vault metadata matches pubkey hash, withdrawal credentials, config hash, derivation version, exit-request contract, and controller;
- controller readiness is well-formed, current enough, policy/schema matched, reserve-backed, beneficiary-initialized, trigger-armed, and in a safe running risk/claim state.
Removed False-Freeze Model¶
The current refactor deliberately removed the old deposit-side false-freeze surface. CenturionUpgradeGovernor.finalFreeze still exists as optional emergency machinery for registered beacons, but deposits no longer require finalFrozen and no deposit function reads it as a precondition. The safety boundary is now honest upgradeability plus live registry assertions, not a deposit-local claim that the baseline is frozen.
Operational Monitoring¶
Monitor:
DepositIntentAllowedFor,DepositIntentRemovedFor,DepositIntentConsumedFor;AllowlistAdminTransferStarted,AllowlistAdminTransferred,AllowlistAdminTransferCancelled;BaselineConfigured,BaselineMetadataConfigured;DepositEvent;- governor events for registered target changes, queued upgrades, executed upgrades, and final freeze.
Evidence To Archive¶
For every production deposit, archive the pubkey, withdrawal credentials, authorized depositor, amount, allowlistEpoch, intent transaction, deposit transaction, DepositEvent, factory vault mapping, controller readiness response, and governor policy assertion outputs for all baseline components.