State Management
Asset state in OIP is not free-form. Every transition is governed by a deterministic matrix, every multi-step regulatory action follows an enforced sequence, and every concurrent modification is mediated by a preemptive lock. This page specifies the rules that an OIP-compliant implementation MUST follow when changing the state of an asset.
The state management layer sits between the routing layer (which decides where a message goes) and the cross-chain protocol (which decides how a state change propagates). It answers a different question: given a well-formed message that has reached its destination, is the requested state change permissible, and what invariants must hold after it.
The MUST/SHOULD/MAY requirements implied by the rules below are aggregated on the Conformance page; this page is the normative source for the rule content.
State Transition Rules
An asset’s PrimaryLockState evolves through a fixed transition graph. Five states (AVAILABLE, RESERVED, RESTRICTED, SEIZED, TERMINATED) and eight actions (six regulatory actions plus RESERVE and RELEASE) define the entire space of permissible transitions. Any transition not explicitly listed is rejected with INVALID_STATE_TRANSITION or, where the violation is sequence-related, with an Escalation Chain error code.
The graph below shows the full transition space. TERMINATED is an absorbing state: once an asset reaches it (through CONFISCATE or LIQUIDATE), no further actions apply. The dashed transition SEIZED → AVAILABLE represents the RECOVER action, used when assets are returned to a fraud victim.
Figure 1: PrimaryLockState Transition Graph
The graph is the canonical reference, but implementations validating individual messages need a tabular form indexed by action with explicit error codes. The matrix below is the complete normative reference. Cells with → indicate the resulting state. Cells with ✗ reject the action with the named error code. Cells marked N/A indicate the action is semantically undefined for that state and is expected not to be issued.
| Action | AVAILABLE | RESERVED | RESTRICTED | SEIZED | TERMINATED |
|---|---|---|---|---|---|
FREEZE |
→ RESTRICTED | → RESTRICTED | ✗INVALID_STATE_TRANSITION |
✗INVALID_STATE_TRANSITION |
✗INVALID_STATE_TRANSITION |
SEIZE |
✗FREEZE_REQUIRED_BEFORE_SEIZE |
✗FREEZE_REQUIRED_BEFORE_SEIZE |
→ SEIZED | ✗INVALID_STATE_TRANSITION |
✗INVALID_STATE_TRANSITION |
CONFISCATE |
✗SEIZE_REQUIRED_BEFORE_CONFISCATE |
✗SEIZE_REQUIRED_BEFORE_CONFISCATE |
✗SEIZE_REQUIRED_BEFORE_CONFISCATE |
→ TERMINATED | ✗INVALID_STATE_TRANSITION |
LIQUIDATE |
→ TERMINATED | ✗INVALID_STATE_TRANSITION |
→ TERMINATED | → TERMINATED | ✗INVALID_STATE_TRANSITION |
RESTRICT |
→ RESTRICTED | ✗INVALID_STATE_TRANSITION |
✗INVALID_STATE_TRANSITION |
✗INVALID_STATE_TRANSITION |
✗INVALID_STATE_TRANSITION |
RECOVER |
N/A | N/A | → AVAILABLE | → AVAILABLE † | ✗INVALID_STATE_TRANSITION |
RESERVE |
→ RESERVED | N/A | ✗INVALID_STATE_TRANSITION |
✗INVALID_STATE_TRANSITION |
✗INVALID_STATE_TRANSITION |
RELEASE |
N/A | → AVAILABLE | N/A | N/A | ✗INVALID_STATE_TRANSITION |
† SEIZED → AVAILABLE via RECOVER handles the case where assets are returned to a fraud victim under a recovery basis. Full error code definitions are in Error Reference.
Precondition and Postcondition Formalization
Each transition has a formal contract: a set of preconditions that MUST hold before it executes, and a set of postconditions that MUST hold after. The contracts are expressed below as TypeScript-like predicate types, suitable for direct translation into runtime assertions or unit tests. The four transitions below cover the main regulatory escalation path; the rest of the matrix follows the same pattern.
AVAILABLE → RESTRICTED via FREEZE
interface FreezePrecondition {
// asset state must be AVAILABLE or RESERVED
primaryState: "AVAILABLE" | "RESERVED";
// authority holds FREEZE permission for the asset's jurisdiction
authorityHasFreezePermission: true;
// legal basis is valid and not expired
legalBasisValid: true;
legalBasisExpired: false;
// no conflicting FREEZE in progress
conflictingFreezeInProgress: false;
}
interface FreezePostcondition {
primaryState: "RESTRICTED";
secondaryState: "UNDER_REVIEW"; // or as specified by action
regulatoryContextPopulated: true;
crossChainCoherenceStatus: "SYNCING";
lockManagementMessageEmitted: true;
primaryFinalityRecordCreated: true;
}
RESTRICTED → SEIZED via SEIZE
interface SeizePrecondition {
primaryState: "RESTRICTED";
// prior FREEZE action exists in escalation chain
priorFreezeInEscalationChain: true;
authorityHasSeizePermission: true;
legalBasisValid: true;
// asset is not in cooling-down state
coolingDown: false;
}
interface SeizePostcondition {
primaryState: "SEIZED";
secondaryState: "AWAITING_CLEARANCE";
custodyAddressRecorded: true;
ownershipRetained: true; // unlike CONFISCATE
accessRestrictionsEnforced: true;
}
SEIZED → TERMINATED via CONFISCATE
interface ConfiscatePrecondition {
primaryState: "SEIZED";
// prior SEIZE action exists in escalation chain
priorSeizeInEscalationChain: true;
authorityHasConfiscatePermission: true;
// appeal deadline has passed
appealDeadlinePassed: true;
destinationAddress: string; // required, non-empty
}
interface ConfiscatePostcondition {
primaryState: "TERMINATED";
ownershipTransferredTo: string; // destinationAddress
permanentlyRemovedFromCirculation: true;
// optional compensation mechanism may apply
compensationMechanismApplied?: boolean;
}
The appealDeadlinePassed: true precondition is normative. CONFISCATE MUST NOT execute before the appeal deadline has elapsed; messages issued before that point are rejected. The deadline is recorded in ConfiscateParameters.appealDeadline when the action is initiated and verified at execution time. This is the single hardest gate in the regulatory action set, because CONFISCATE permanently removes ownership and cannot be undone by the protocol once it succeeds.
SEIZED → AVAILABLE via RECOVER
interface RecoverPrecondition {
primaryState: "SEIZED";
originalOwnerOwnershipProofValid: true;
fraudulentHolderFraudProofValid: true;
recoveryBasisLegalDocumentValid: true;
}
interface RecoverPostcondition {
primaryState: "AVAILABLE";
ownershipTransferredTo: string; // originalOwner address
auditLogRecoveryEventRecorded: true;
}
SecondaryLockState Recommended Mapping
The Postcondition contracts above reference secondaryState values such as UNDER_REVIEW and AWAITING_CLEARANCE. SecondaryLockState is OPTIONAL in the data model, and the table below records the recommended mapping for each PrimaryLockState transition. Implementations MAY use a different value or omit the field entirely.
| Primary Transition | Recommended Secondary | Note |
|---|---|---|
→ RESERVED | PROCESSING_TRANSFER | Transaction in progress |
→ RESTRICTED (via FREEZE) | UNDER_REVIEW | Under review |
→ RESTRICTED (via RESTRICT) | AWAITING_CLEARANCE | Conditional transactions allowed |
→ SEIZED | AWAITING_CLEARANCE | After custodian designation |
RESTRICTED → AVAILABLE (via RECOVER) | COOLING_DOWN | Brief monitoring after recovery |
| New asset registration | PENDING_VERIFICATION | Awaiting initial verification |
Escalation Chain Enforcement
Regulatory actions follow a graduated severity path. OIP v0.5 enforces the Escalation Chain at the protocol level: severe actions cannot skip ahead of milder ones. The canonical chain is FREEZE → SEIZE → CONFISCATE.
The enforcement rules are normative. SEIZE applies only when the target asset’s PrimaryLockState is RESTRICTED (i.e., a prior FREEZE exists). CONFISCATE applies only when the target’s state is SEIZED (a prior SEIZE exists). Messages that violate this order are rejected with FREEZE_REQUIRED_BEFORE_SEIZE or SEIZE_REQUIRED_BEFORE_CONFISCATE.
Figure 2: Escalation Chain with Forward and Reverse Rollback Paths
Three actions sit outside the canonical chain. LIQUIDATE applies from AVAILABLE, RESTRICTED, or SEIZED, given proper authority and legal basis. RESTRICT is a milder form of FREEZE applied directly to AVAILABLE; it does not satisfy SEIZE‘s precondition. RECOVER is the recovery action used to return assets to a fraud victim, applicable from RESTRICTED or SEIZED.
The chain’s authority hierarchy is mirrored on rollback: a CONFISCATE rollback restores the asset to SEIZED, a SEIZE rollback restores it to RESTRICTED, and a FREEZE rollback restores it to AVAILABLE. The graduated step structure is what allows the corresponding formal verification property to establish soundness of the rollback hierarchy.
ContractStatus and Regulatory Action Coupling
ContractStatus and PrimaryLockState are orthogonal dimensions. The data model defines this independence; the state management layer formalizes the transition rules and the points where the two dimensions interact. The ContractStatus transition table below is normative.
| Current | Trigger | Next |
|---|---|---|
PENDING | Activation: all participants’ OCID verified, initial state registered | ACTIVE |
ACTIVE | Normal completion | COMPLETED |
ACTIVE | Mutual cancellation by participants | CANCELLED |
ACTIVE | Dispute raised (governance message) | DISPUTED |
ACTIVE | CONFISCATE with appealable=true | DISPUTED |
DISPUTED | Dispute resolved (governance or external trigger) | ACTIVE | COMPLETED | CANCELLED |
COMPLETED / CANCELLED | (none) | (terminal) |
Three coupling rules govern the interaction between contract and asset state. ContractStatus transitions do not automatically trigger PrimaryLockState transitions: a contract reaching COMPLETED does not by itself terminate the asset. However, when ContractStatus reaches a terminal state (COMPLETED or CANCELLED), PrimaryLockState is typically transitioned to TERMINATED in the same operation, since contract closure usually implies asset wind-down. While ContractStatus is DISPUTED, transactional actions (RESERVE, RELEASE) are rejected, but regulatory actions (FREEZE, SEIZE, etc.) are permitted regardless of dispute status.
The compatibility matrix below records which PrimaryLockState values are permissible while a contract holds each ContractStatus. Pairs outside this matrix are rejected with CONTRACT_STATE_INCOMPATIBLE.
| ContractStatus | Permitted PrimaryLockState | Note |
|---|---|---|
PENDING | AVAILABLE | Initial registration; lock changes restricted |
ACTIVE | All five states | Normal operation |
DISPUTED | RESTRICTED, SEIZED (most common); AVAILABLE, RESERVED permitted | Dispute in progress; new transactional actions rejected |
COMPLETED | TERMINATED (concurrent transition) | Normal termination |
CANCELLED | TERMINATED (concurrent transition) | Mutual cancellation |
Actions rejected while ContractStatus = DISPUTED: RESERVE and RELEASE (transactional). Regulatory actions (FREEZE, SEIZE, CONFISCATE, LIQUIDATE, RESTRICT, RECOVER) are permitted regardless of dispute status.
When an asset becomes the subject of a regulatory action, the action’s messageId is recorded in OIPContract.regulatoryAction. This serves both audit trail and duplicate-action prevention purposes.
Preemptive Lock Protocol
The Preemptive Lock is the mechanism that prevents concurrent state modifications from racing. Every state transition that mutates an asset MUST hold a lock for the duration of the change. The lock manager’s obligations are normative; the underlying data structure is not.
Lock Acquisition Modes
| Mode | Issued When | Owner |
|---|---|---|
LOCK_ACQUIRE (voluntary) | Sender requests via LOCK_MANAGEMENT (operation = LOCK_ACQUIRE) | Originating node |
LOCK_ACQUIRE (preemptive) | Automatically acquired during STATE_SYNC or REGULATORY_ACTION processing | Processing node |
LOCK_ESCALATE | Authorized sender requests stronger lock (e.g., normal → regulatory) | Authorized sender |
Lock Hold Time
Default TTL follows the Bind-Verify-Commit pattern: T_lock = max(T_finality^Di) + T_margin, the maximum finality time across all participating domains plus a safety margin. Senders MAY specify a custom duration through LockManagementPayload.durationSeconds, capped at 600 seconds (regulatory actions excepted).
One requirement on Lock TTL is non-obvious and MUST be respected by implementations. Lock TTL MUST exceed the worst-case retry window of the message holding it: Lock TTL >= message TTL + (max_retries × max_backoff). If the lock expires while retries are still in flight, another transaction can interleave and corrupt the state machine. The longest retry windows in the v0.5 retry policy are STATE_SYNC at 60 seconds × 5 retries = 300 seconds and GOVERNANCE EXECUTE at 60 seconds × 7 retries = 420 seconds; lock TTLs MUST cover these.
Lock Expiration
- On TTL expiration, the lock is released automatically (this is the lock timeout safety guarantee).
- The
primaryFinalityRecordis preserved beyond lock expiration (durability across the pre-trading and settlement finality boundary). RELEASEorEXTENDmessages targeting an already-expired lock are silently ignored (idempotent handling).
Conflict Policy
When a lock acquisition collides with an existing lock, the conflictPolicy field on the request determines the outcome.
| Policy | Behavior | Authorized for |
|---|---|---|
FAIL | Reject immediately; sender must retry | All messages |
WAIT | Block until existing lock expires | All messages |
PREEMPT | Force-release existing lock and acquire | CRITICAL priority + verified authority only |
Figure 3: Preemptive Lock Lifecycle
Lock Manager Invariants
The lock manager MUST satisfy four invariants. The corresponding formal verification property establishes their joint soundness.
- Deadlock freedom: Lock request cycles do not occur. This is achieved by acquiring locks in a deterministic order (typically asset ID lexicographic ordering).
- Lock timeout safety: Every lock is released in finite time, enforced by TTL.
- No lost updates: Concurrent updates against a held lock are blocked, not silently overwritten.
- Lock granularity correctness: Asset-level locking prevents partial-update conflicts on the same asset.
Cross-chain Coherence
The same asset may exist on multiple chains, and consistency between those chain-local states is tracked through the CrossChainCoherence.status field. OIP v0.5 defines four CoherenceState values.
| State | Meaning | New Transactions |
|---|---|---|
SYNCED | All participating chains hold identical state | Processed normally |
SYNCING | Some chains still applying (PREPARE / COMMIT / FINALIZE in flight) | Lock held; new transactions rejected |
DIVERGED | Inter-chain state inconsistency detected; reconciliation required | Rejected; reconciliation triggered |
ROLLBACK_INCOMPLETE | Intentional rollback in progress (after ALL_OR_NOTHING failure) | Rejected; awaits governance resolution |
DIVERGED and Reconciliation
DIVERGED arises when a GUARANTEED atomicity message permanently fails on a subset of chains, or when external events corrupt chain-local state outside the protocol’s control. The reconciliation procedure has four steps. The asset starts rejecting new transactions on divergence detection. The primaryFinalityRecord serves as source of truth, leveraging the durability guarantees of primary finality. All participating chains are force-synchronized to the recorded primary finality state through system-issued STATE_SYNC messages. On completion, the asset returns to SYNCED.
ROLLBACK_INCOMPLETE Entry Conditions
ROLLBACK_INCOMPLETE arises from a different cause than DIVERGED. Two conditions MUST both hold for an asset to enter this state:
- An
ALL_OR_NOTHINGatomicity message succeeds on some chains’ COMMIT phase, then fails on other chains’ COMMIT phase, triggering a rollback. - The rollback message is dispatched with
BEST_EFFORTcoordination but does not complete on all participating chains withinmaxRollbackWindow.
Resolution requires governance. Three resolution options are available: force the rollback to completion through the governance rollback authority, recognize the partial state as a new SYNCED baseline (rare and deliberate), or force re-synchronization to the primary finality record (identical handling to DIVERGED). The asset returns to SYNCED when all participating chains hold identical state and that state matches the primary finality record, or when governance explicitly declares the new state synchronized.
Figure 4: DIVERGED vs ROLLBACK_INCOMPLETE Comparison
Governance Resolution Exception
Assets in ROLLBACK_INCOMPLETE reject new transactions with ROLLBACK_INCOMPLETE_REJECT. This creates a deadlock risk: the very governance message needed to resolve the state would itself be rejected. One explicit exception unblocks resolution: a GOVERNANCE message satisfying all four conditions below is processed normally even on a ROLLBACK_INCOMPLETE asset.
messageTypeisGOVERNANCE.payload.governanceTypeisEXECUTEorPARAMETER_CHANGE(resolution decisions).payload.executionDetails.rollbackResolutionTargetexplicitly names the asset.- Sender holds governance authority (verified through Authority Registry).
Messages meeting these conditions pass the validation pipeline normally, transition the asset’s PrimaryLockState back to a normal state (SYNCED or another specified target), and apply one of the three resolution options. GOVERNANCE messages without an explicit rollbackResolutionTarget, or with a target naming a different asset, follow the standard rejection policy.
Pending Sync Queue Invariants
After OSS issues primary finality, external propagation (settlement finality across chains) may still be in flight. A pending sync queue tracks which messages have been applied where. OIP v0.5 does not specify the queue’s data structure or scheduling algorithm; it specifies four invariants that any compliant implementation MUST satisfy.
Figure 5: Pending Sync Queue Invariants
The queue’s exact data structure, algorithm, retry scheduling, sharding, and compaction strategy are implementation choices outside the OIP normative scope. Implementations may use a RocksDB persistent queue, an in-memory queue with backup, a distributed queue, FIFO ordering, priority-based ordering, or deadline-based ordering, as long as the four invariants above hold. The concrete operational strategy for INV-3 (compression algorithm, hot/cold tiering, archival infrastructure, distributed storage quorum) is recorded as a v0.5 deferred item; see Open Issues for the resolution timeline.
Force Inclusion (the path that lets users post transactions to L3 through Base L2 even if D-quencer consensus is unavailable) interacts with this layer. Force-included transactions bypass OIP validation but are still admitted to primary finality only after passing RWA Registry self-defense checks, so the OIP path and the Force Inclusion path land in the pending sync queue with the same safety guarantees. The detailed self-defense interface is normative content of the validation layer, specified in Validation.
Related Pages
- Data Model defines
PrimaryLockState,SecondaryLockState,ContractStatus,HierarchicalLockStatus,RegulatoryContext, andCrossChainCoherence. - Message Protocol defines
STATE_SYNC,REGULATORY_ACTION,LOCK_MANAGEMENT, andGOVERNANCEmessage payloads. - Routing covers atomicity-driven coordination and how routing decisions interact with the lock acquisition path.
- Validation specifies the processing pipeline, RWA Registry self-defense, and the CRITICAL priority authority system.
- Regulatory Actions details parameter structures for each of the six regulatory actions, including the
appealDeadlinefield that governs CONFISCATE execution. - Cross-chain Protocol details PREPARE, COMMIT, and FINALIZE for staged execution.
- Conformance aggregates the MUST/SHOULD/MAY requirements that state management implementations must satisfy.
- Open Issues records v0.5 deferred items referenced from this page (long-term primary finality storage strategy).
