Core
CRX.sol is the singleton the rest of the protocol hangs off: factory, registry, collateral vault, roles, and oracle bindings in one contract. This page lists its identifiers, entry points, views, events, and errors.
Code
CRX.sol is the core CRX contract: the factory, registry, collateral vault, role system, and oracle registry in one singleton. It deploys one lightweight NDF instrument clone per relationship (via AcaCloneFactory.sol), holds all collateral in its own vault keyed by relationship, and trades one instrument: the non-deliverable forward (NDF).
State is mappings only. There are no on-chain lists; sets are passed as calldata and validated by count and membership, which is why the margin and close-out functions below take the position and token sets as arguments. Much of the surface (collateral movement, variation margin, settlement, the close-out paths) lives in CRXCascade.sol / CRXCascade2.sol, delegatecalled engines sharing the core's CRXStorage layout.
WarningAlways call the core. Call every function on the core address, never on the engines directly, and index every event from the core address.
Identifiers and parameters
Account Control Agreement id
The Account Control Agreement (ACA) id is a bytes32 keccak256 hash of (party1, party2, number, csa). It identifies one per-relationship netting set: the on-chain agreement between exactly two parties.
type Id is bytes32;To get the id from the parameters, call the computeAcaId view function, or read it from the AccountControlAgreementOpened event at creation.
AccountControlAgreement struct
The per-relationship netting set record. csa is chosen at creation; clone is the deployed NDF instrument clone; defaulted flips true when the cascade burns it. cureWindow1 / cureWindow2 are the per-party grace seconds before an SCA-local close-out (0 = instant).
struct AccountControlAgreement {
address party1;
address party2;
uint256 number;
address csa;
address clone;
bool defaulted;
uint32 cureWindow1;
uint32 cureWindow2;
}Terms struct
The economic terms both counterparties sign (EIP-712) at bind. The ACA already names its two parties. Terms carries no addresses; longIsParty1 picks the side. Initial margin is asymmetric: imLongBps / imShortBps, both sides posting.
struct Terms {
bytes32 acaId;
bytes32 pair;
bool longIsParty1;
uint256 notional;
int256 lockedRate;
uint16 imLongBps;
uint16 imShortBps;
uint16 thresholdBps;
uint16 mtaBps;
uint16 tolBps;
uint64 deliveryTime;
bytes32 calendarId;
uint64 sigDeadline;
bytes32 quoteRef;
uint256 nonce;
}Position struct
Live position state, stored in the core keyed by positionId. The immutable terms are flattened in; the live fields (vmPosted, the marks, the VM call deadline) update as the position runs.
struct Position {
uint256 notional;
int256 lockedRate;
int256 vmPosted;
int256 lastVmRate;
int256 closeRate;
bytes32 acaId;
bytes32 pair;
bytes32 quoteRef;
address longAcct;
address shortAcct;
uint64 callDeadline;
uint64 openedAt;
uint64 deliveryTime;
uint16 imLongBps;
uint16 imShortBps;
uint16 thresholdBps;
uint16 mtaBps;
uint16 tolBps;
State state;
bytes32 calendarId;
}State is one of NONE, OPEN, SETTLED, CLOSED, BURNED, where BURNED is the close-out state: the agreement is terminated and valued by the cascade.
Collateral accounts
Collateral lives in two places, both held in the core vault:
- Safe (
generalBalance[party][token]): a party's free, global margin, the shared backstop across all its ACAs. Variation margin lands here. - SCA (Segregated Collateral Account,
sca[acaId][party][token]): one party's segregated collateral inside one ACA. Initial margin only, never accumulated P&L, non-rehypothecable.
Functions
register
function register() external;Starts onboarding for msg.sender, permissionlessly. Emits Registered and grants the VALIDATION role, the applicant state the operator clears before approving a desk.
approveMaker
function approveMaker(address a) external;Grants the MAKER role to a. Operator-only (DAO role). After this, a may be the sell-side of an Account Control Agreement.
Parameters:
| Name | Type | Description |
|---|---|---|
a | address | The address to approve as maker. |
approveTaker
function approveTaker(address a) external;Grants the TAKER role to a. Operator-only (DAO role).
Parameters:
| Name | Type | Description |
|---|---|---|
a | address | The address to approve as taker. |
deposit
function deposit(address token, uint256 amount) external;Pulls amount of token from msg.sender into its safe. Emits Deposited.
Parameters:
| Name | Type | Description |
|---|---|---|
token | address | The collateral token. |
amount | uint256 | The amount to deposit. |
withdraw
function withdraw(address token, uint256 amount) external;Pulls amount of token from msg.sender's safe back to its wallet. Emits Withdrawn. Reverts if the balance is short or the party is suspended.
Parameters:
| Name | Type | Description |
|---|---|---|
token | address | The collateral token. |
amount | uint256 | The amount to withdraw. |
allocate
function allocate(bytes32 acaId, address token, uint256 amount) external;Moves amount of token from the caller's safe into its SCA inside the agreement acaId. This is how initial margin is posted. Emits Allocated. Reverts Ineligible if the agreement's CSA marks token ineligible.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA to allocate into. |
token | address | The collateral token. |
amount | uint256 | The amount to move from general to SCA. |
computeDeallocation
function computeDeallocation(bytes32 acaId, address[] calldata scaTokens, uint256[] calldata scaAmounts)
external
returns (uint256 freeMargin);First phase of a two-phase deallocation. Snapshots free margin (an O(1) check against the IM aggregate) for the proposed SCA reduction. The matching deallocate must follow within the compute window. Emits DeallocationComputed.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
scaTokens | address[] | The SCA tokens being reduced. |
scaAmounts | uint256[] | The amount of each token to remove. |
Return Values:
| Name | Type | Description |
|---|---|---|
freeMargin | uint256 | The free margin after the reduction. |
deallocate
function deallocate(bytes32 acaId, address token, uint256 amount) external;Second phase: moves amount of token from the caller's SCA back to its safe, only if a fresh computeDeallocation cleared it. Emits Deallocated.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
token | address | The collateral token. |
amount | uint256 | The amount to move from SCA to general. |
openAccountControlAgreement
function openAccountControlAgreement(
address party1,
address party2,
uint256 number,
address csa,
uint32 cureWindow1,
uint32 cureWindow2,
uint64 deadline,
bytes calldata sig1,
bytes calldata sig2
) external returns (bytes32 acaId);Opens an Account Control Agreement. Both parties sign (EIP-712); one must hold MAKER and the other TAKER. Selects the CSA, deploys the NDF instrument clone, writes the per-party cure windows, and sets acaId. Emits AccountControlAgreementOpened.
Parameters:
| Name | Type | Description |
|---|---|---|
party1 | address | One counterparty. |
party2 | address | The other counterparty. |
number | uint256 | Disambiguates multiple ACAs between the same pair. |
csa | address | The per-ACA Credit Support Annex pricing contract. |
cureWindow1 | uint32 | Grace seconds for party1 when in breach (0 = instant). |
cureWindow2 | uint32 | Grace seconds for party2 when in breach (0 = instant). |
deadline | uint64 | Signature freshness deadline. |
sig1 | bytes | party1's signature. |
sig2 | bytes | party2's signature. |
Return Values:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The id of the opened agreement. |
bind
function bind(Terms calldata terms, bytes calldata sig1, bytes calldata sig2) external returns (bytes32 id);Opens one NDF position inside an existing Account Control Agreement. Both parties sign the Terms (EIP-712). Adds each side's initial margin to its IM aggregate and emits Bound. This is the keystone: a position binds only when both signatures verify.
Parameters:
| Name | Type | Description |
|---|---|---|
terms | Terms | The signed economic terms. |
sig1 | bytes | First counterparty's sig. |
sig2 | bytes | Second counterparty's sig. |
Return Values:
| Name | Type | Description |
|---|---|---|
id | bytes32 | The new position id. |
openAndBind
function openAndBind(
address party1,
address party2,
uint256 number,
address csa,
Terms calldata terms,
bytes calldata sig1,
bytes calldata sig2
) external returns (bytes32 id);Opens an Account Control Agreement (with cure windows preset to 0) and binds its first position in one transaction. Combines openAccountControlAgreement and bind.
Return Values:
| Name | Type | Description |
|---|---|---|
id | bytes32 | The new position id. |
settle
function settle(bytes32 id) external;
function settleMulti(bytes32 id, address[] calldata scaTokens) external;Settles position id at or after its delivery time, cash-settling the rate difference in USDC. The fixing is the contract's own read of the per-pair Pyth EMA (a smoothed ~1-hour average) at the delivery date. There is no caller-submitted price and no tolerance band. The read is pure EMA with no spot fallback: settlement reverts if the EMA is unhealthy. Emits Settled. Reverts NotAtSettlement before the delivery time, FixingTooEarly if the EMA predates the delivery time.
settleMulti is the same settlement for a position whose SCA holds more than one collateral token; scaTokens passes that token set as calldata. The remaining initial margin is returned across all of them.
Parameters:
| Name | Type | Description |
|---|---|---|
id | bytes32 | The position to settle. |
scaTokens | address[] | (settleMulti) The SCA's collateral tokens to return. |
closeOnChain
function closeOnChain(
bytes32 id,
int256 rate,
uint256 nonce,
uint64 deadline,
bytes calldata sig1,
bytes calldata sig2
) external;Both parties cooperatively close position id early at an agreed rate, no operator involved. rate is checked against the oracle within tolerance. Emits ClosedOnChain.
Parameters:
| Name | Type | Description |
|---|---|---|
id | bytes32 | The position to close. |
rate | int256 | The agreed close rate (within tolerance). |
nonce | uint256 | Replay guard. |
deadline | uint64 | Signature freshness deadline. |
sig1 | bytes | First counterparty's signature. |
sig2 | bytes | Second counterparty's signature. |
callVM
function callVM(bytes32 acaId, bytes32[] calldata positionIds) external;Permissionless crank. Settles variation margin for the given positions in agreement acaId against a fresh oracle mark: the loser pays from its SCA, the winner receives into its safe. Emits VmSettled. Convenience wrapper over the two-phase computeVM / applyVM.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
positionIds | bytes32[] | The positions to settle VM on. |
computeVM
function computeVM(bytes32 acaId, bytes32[] calldata positionIds) external returns (int256 markRate);First phase of variation margin. Snapshots the mark for positionIds. The matching applyVM must follow within the compute window. Emits VmComputed.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
positionIds | bytes32[] | The positions to mark. |
Return Values:
| Name | Type | Description |
|---|---|---|
markRate | int256 | The snapshotted mark rate. |
applyVM
function applyVM(bytes32 acaId, bytes32[] calldata positionIds) external;Second phase: settles the variation margin computed by computeVM, and re-trues each SCA toward its IM target at most once per day. Emits VmSettled and, on a rebalance, ImRebalanced.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
positionIds | bytes32[] | The positions to settle VM on. |
fill
function fill(bytes32 acaId, bytes32[] calldata positionIds) external;Tops up an SCA from the party's safe up to its IM target for the given positions. Emits Filled.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
positionIds | bytes32[] | The positions to top up. |
Multi-asset variants
A party may post collateral other than the settlement token (USDC, sUSDS, EURC, USDT). The settlement-token-only paths above each have a multi-asset twin that moves value across a declared, ascending-distinct token set, priced by the ACA's CSA at fair value. The keeper passes the live scaTokens set; an empty set falls back to the settlement-token-only par draw.
| Function | Twin of |
|---|---|
callVMMulti(bytes32 acaId, bytes32[] positionIds, address[] scaTokens) | callVM |
applyVMMulti(bytes32 acaId, bytes32[] positionIds, address[] scaTokens) | applyVM |
fillMulti(bytes32 acaId, bytes32[] positionIds, address[] scaTokens) | fill |
settleMulti(bytes32 id, address[] scaTokens) | settle |
forceCloseMulti(bytes32 acaId, bytes32[] positionIds, address[] scaTokens, bytes instruction) | forceClose |
flagBreach
The close-out is a two-tier ladder. Tier-1 (flagBreach / clearBreach / liquidateLocal) works inside one ACA: it stamps a breach clock, lets it cure, and on lapse seizes only the breached party's SCA in that one ACA. Tier-2 (assertLiquidation / resolveCascade) is the whole-book cascade when the SCA cannot cover what the party owes. The two are mutually exclusive: Tier-1 refuses to run while a Tier-2 assertion sits on the party.
function flagBreach(bytes32 acaId, address party, bytes32[] calldata positionIds) external;Permissionless Tier-1 crank. Re-marks party's positions at a fresh oracle epoch; if its settlement-token SCA no longer covers required IM plus what it owes, stamps the breach clock and emits MarginCall. Idempotent while flagged. Reverts SessionClosed while the FX session is shut: it never stamps off a frozen weekend mark.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
party | address | The party to test for breach. |
positionIds | bytes32[] | The party's positions in the ACA. |
clearBreach
function clearBreach(bytes32 acaId, address party, bytes32[] calldata positionIds) external;Symmetric, permissionless cure crank. Re-marks at a fresh epoch; if the SCA is back at or above its IM-plus-owed target, observes the cure under the anti-flicker dwell: the flag clears only once the cure has held CURE_DWELL. Emits MarginCallCleared on clear. Reverts BreachNotFlagged if no clock is running, NotUnderIM cannot be cleared into, SessionClosed while FX is shut.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
party | address | The flagged party. |
positionIds | bytes32[] | The party's positions in the ACA. |
liquidateLocal
function liquidateLocal(bytes32 acaId, address party, bytes32[] calldata positionIds) external;Tier-1 SCA-local seizure once the cure window has lapsed. Re-marks at a fresh epoch and, only if the party is strictly under water (owed exposure exceeds its settlement-token SCA), moves the whole settlement-token SCA to the owed counterparty as a pull-claim. No safe balance moves. Emits LiquidatedLocal. In manual mode only the owed counterparty may call it (LiquidateUnauthorized otherwise); in auto mode any keeper may. Reverts WindowOpen before the deadline, BreachNotFlagged if not flagged, NotUnderIM if the fresh mark shows the SCA covers, AssertionActive if a Tier-2 cascade is in flight, SessionClosed while FX is shut.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
party | address | The breached party to seize from. |
positionIds | bytes32[] | The party's positions in the ACA. |
setLiquidationMode
function setLiquidationMode(bool manual) external;Sets the caller's Tier-1 close-out profile: true = manual (only the owed counterparty may seize the caller), false = auto (any keeper may, once the window lapses). Emits LiquidationModeSet.
Parameters:
| Name | Type | Description |
|---|---|---|
manual | bool | true = manual seizure, false = auto. |
assertLiquidation
function assertLiquidation(address party, bytes32 acaDefaulted, uint256 bond) external;Opens a close-out proof window against party, posting bond. The window must then be resolved by resolveCascade. Emits LiquidationAsserted. A false assertion forfeits the bond.
Parameters:
| Name | Type | Description |
|---|---|---|
party | address | The party alleged to be unable to cover what it owes. |
acaDefaulted | bytes32 | The agreement whose VM call could not be met. |
bond | uint256 | The bond posted to open the window. |
resolveCascade
function resolveCascade(
address party,
bytes32 acaDefaulted,
bytes32[] calldata acaSet,
bytes32[][] calldata positionSets,
address[][] calldata scaTokenSets,
address[] calldata generalTokens
) external;Runs the close-out cascade for party against the asserted window. Force-VMs the party's whole book at one fresh price, tests global solvency by sweeping every SCA, and, if still short, waterfalls the party's own estate (SCA then safe) pro-rata to its creditors, burns the agreements, and terminates the party. Any residual beyond the estate is left unpaid to the direct counterparty: there is no pool or operator capital behind the book. The caller supplies the party's full set of agreements, positions, SCA tokens, and the tokens in its safe as calldata; the contract validates the sets by count and membership. Emits the Cascade* series and, on completion, Defaulted.
Parameters:
| Name | Type | Description |
|---|---|---|
party | address | The party being closed out. |
acaDefaulted | bytes32 | The asserted agreement. |
acaSet | bytes32[] | Every ACA the party is in. |
positionSets | bytes32[][] | Each agreement's positions. |
scaTokenSets | address[][] | Each agreement's SCA tokens. |
generalTokens | address[] | The tokens in the party's safe. |
forceClose
function forceClose(bytes32 acaId, bytes32[] calldata positionIds, bytes calldata instruction) external;Operator-only, on a legal order. Closes the given positions at a validated fair price and routes their collateral per instruction. Emits ForceClosed.
Parameters:
| Name | Type | Description |
|---|---|---|
acaId | bytes32 | The ACA. |
positionIds | bytes32[] | The positions to close. |
instruction | bytes | The validated routing instruction. |
withdrawClaim
function withdrawClaim(address token) external;Pulls collateral credited to msg.sender during a wind-down (the pull side of the close-out and force-close paths). Emits ClaimWithdrawn.
Parameters:
| Name | Type | Description |
|---|---|---|
token | address | The token to claim. |
anchor
function anchor(bytes32 rfqId, bytes32 quoteHash) external;Anchors a matched RFQ (rfqId, quoteHash) on-chain for audit provenance: the relayer ties a firm quote to its request before the taker binds. RELAYER-only. Emits RfqAnchored. Stores nothing, gates nothing.
Parameters:
| Name | Type | Description |
|---|---|---|
rfqId | bytes32 | The RFQ request id. |
quoteHash | bytes32 | The hash of the firm quote. |
multicall
function multicall(bytes[] calldata calls) external;Batches several calls against the core in one transaction, each a delegatecall into self. An inner failure bubbles and reverts the whole batch.
Parameters:
| Name | Type | Description |
|---|---|---|
calls | bytes[] | The encoded calls to run. |
Registry setters
Operator-only (DAO role), set once at configuration time:
| Function | Effect |
|---|---|
setPair(bytes32 pair, bool allowed) | Enables or disables a currency pair for trading. |
setOracle(bytes32 pair, address oracle) | Binds the FX oracle the core marks pair against. |
setCollateralOracle(address token, address oracle) | Binds a collateral token to its global USD price oracle. |
setSettlementToken(address token) | Sets the cash-settlement token VM and settlement pay in. |
setGlobalCSA(address csa) | Sets the standing Credit Support Annex. |
setCascadeEngine(address engine) | Wires the delegatecalled CRXCascade engine. |
setCascadeEngine2(address engine) | Wires the second delegatecalled engine (CRXCascade2). |
setTokenScale(address token, uint256) | Registers a token's 18-dp normalisation scale. |
ban(address) / reinstate(address) | Suspends or reinstates a party (reversible). |
terminateParty(address, string reason) | Terminally winds a party down: wind-down only, no new risk. |
Views Functions
computeAcaId
function computeAcaId(address party1, address party2, uint256 number, address csa) external view returns (bytes32);The Account Control Agreement id for the given parameters: keccak256(party1, party2, number, csa).
acaExists
function acaExists(bytes32 acaId) external view returns (bool);Whether the agreement acaId has been opened.
accountControlAgreements
function accountControlAgreements(bytes32 acaId) external view returns (AccountControlAgreement memory);The full AccountControlAgreement record for acaId.
csaOf
function csaOf(bytes32 acaId) external view returns (address);The Credit Support Annex bound to agreement acaId.
position
function position(bytes32 id) external view returns (Position memory);The full Position record for id.
generalBalance
function generalBalance(address party, address token) external view returns (uint256);A party's free, global margin in token.
sca
function sca(bytes32 acaId, address party, address token) external view returns (uint256);A party's segregated collateral in token inside agreement acaId.
imAggregate
function imAggregate(bytes32 acaId, address party) external view returns (uint256);The running sum of a party's required initial margin in acaId, for the O(1) free-margin check.
claimable
function claimable(address party, address token) external view returns (uint256);The amount of token credited to party and waiting to be pulled by withdrawClaim.
cureWindowOf
function cureWindowOf(bytes32 acaId, address party) external view returns (uint32);The grace seconds party receives in acaId when it is the breached side (0 = instant).
breachAtOf
function breachAtOf(bytes32 acaId, address party) external view returns (uint40);When the party's Tier-1 breach clock started in acaId (0 = not flagged).
curedSinceOf
function curedSinceOf(bytes32 acaId, address party) external view returns (uint40);When the party's anti-flicker cure dwell started in acaId (0 = not curing).
liquidationModeOf
function liquidationModeOf(address party) external view returns (bool);The party's Tier-1 close-out profile (true = manual, false = auto).
domainSeparator
function domainSeparator() external view returns (bytes32);The EIP-712 domain separator, exposed to let an off-chain signer reproduce the exact digest bind, openAccountControlAgreement, and closeOnChain verify against.
Events
The full list of events is declared in the EventsLib library; the core emits them unchanged. A log's topic is the keccak of its signature. An indexer keys on these directly.
| Event | Emitted when |
|---|---|
Registered | A party starts onboarding via register. |
MakerApproved | The operator approves a maker. |
TakerApproved | The operator approves a taker. |
Deposited | Collateral lands in a party's safe. |
Withdrawn | Collateral leaves a party's safe. |
Allocated | Collateral moves general → SCA. |
Deallocated | Collateral moves SCA → general. |
DeallocationComputed | A deallocation is snapshotted (phase one). |
AccountControlAgreementOpened | An Account Control Agreement is opened and its NDF clone deployed. |
Bound | A position binds inside an agreement. |
VmComputed | A variation-margin mark is snapshotted (phase one). |
VmSettled | Variation margin settles, loser to winner. |
ImRebalanced | An SCA is re-trued toward its IM target. |
Filled | An SCA is topped up from the safe. |
Settled | A position cash-settles at its fixing. |
ClosedOnChain | Two parties cooperatively close a position. |
OracleSet | A pair's FX oracle is bound. |
CollateralOracleSet | A collateral token's price oracle is bound. |
TokenScaleSet | A token's 18-dp normalisation scale is set. |
LiquidationAsserted | A close-out proof window opens against a party. |
MarginCall | A party's SCA fell under its IM in one ACA: the breach clock started. |
MarginCallCleared | A breach was cured (SCA back at/above IM) before its window lapsed. |
LiquidatedLocal | A Tier-1 SCA-local seizure moved value from a breached party to its creditor. |
LiquidationModeSet | A party set its Tier-1 close-out profile (manual or auto). |
CascadeAccumulated / CascadeDecided / CascadeExecuted / CascadeReverted / CascadeWaterfall / CascadeAborted | The close-out cascade progresses. |
ShortfallSkipped | A cascade payout cannot be credited (recipient's CSA marks it ineligible). |
ClaimCredited / ClaimWithdrawn | Wind-down collateral is credited and pulled. |
ForceClosed | The operator force-closes positions on a legal order. |
PartySuspendedEvent / PartyReinstated / PartyTerminated | A party's status changes. |
Defaulted | A party's cascade completes; it is closed out. |
RfqAnchored | The relayer anchors a matched RFQ for audit. |
PairWhitelisted | A currency pair is enabled or disabled for trading. |
Errors
The full list of custom errors is declared on the ICRX interface; the core reverts them unchanged. A 4-byte selector has one home. A selection:
| Error | Thrown when |
|---|---|
NotParty | The caller is not a party to the agreement. |
NotWhitelistedPair | The pair is not enabled for trading. |
PartySuspended | A suspended party attempts new risk. |
AlreadyTerminated | A terminated party attempts to enter or take on new risk. |
BadSigners | A Terms or agreement signature does not verify. |
NonceUsed | A signed message's nonce has already been consumed. |
NotAtSettlement | settle is called before the delivery time. |
FixingTooEarly | The fixing mark predates the position's delivery time. |
OutOfTolerance | A cooperative close rate is outside the tolerance band. |
StaleMark | The oracle mark is older than MAX_MARK_AGE. |
NoOracle | No oracle is bound for the pair or token. |
Ineligible | A token the resolving CSA marks ineligible is allocated. |
InsufficientBalance | A balance is short for the requested move. |
DeallocateUnauthorized | deallocate runs without a fresh computeDeallocation. |
StaleComputation / NoComputation | A two-phase action's snapshot is stale or absent. |
WrongCascadePhase / CascadeWindowOpen / CascadeWindowClosed | The cascade is driven out of order. |
WindowOpen | liquidateLocal runs before the cure deadline. |
BreachNotFlagged | A Tier-1 cure or seizure runs with no breach clock set. |
NotUnderIM | A breach path runs while the SCA covers IM at the fresh mark. |
SessionClosed | A Tier-1 path runs while the FX session is shut. |
LiquidateUnauthorized | A manual-mode seizure is called by someone other than the owed party. |
AssertionActive | A Tier-1 seizure runs while a Tier-2 cascade is in flight. |