MarginClearinghouse
Inherits: Ownable2Step
Title: MarginClearinghouse
USDC-only cross-margin account manager for Plether.
Holds settlement balances and locked margin for CFD accounts.
Note: security-contact: contact@plether.com
Constants
settlementAsset
address public immutable settlementAsset
State Variables
settlementBalances
mapping(bytes32 => uint256) internal settlementBalances
positionMarginUsdc
mapping(bytes32 => uint256) internal positionMarginUsdc
committedOrderMarginUsdc
mapping(bytes32 => uint256) internal committedOrderMarginUsdc
reservedSettlementUsdc
mapping(bytes32 => uint256) internal reservedSettlementUsdc
orderReservations
mapping(uint64 => IMarginClearinghouse.OrderReservation) internal orderReservations
reservationIdsByAccount
mapping(bytes32 => uint64[]) internal reservationIdsByAccount
reservationHeadIndexByAccount
mapping(bytes32 => uint256) internal reservationHeadIndexByAccount
activeCommittedOrderReservationUsdc
mapping(bytes32 => uint256) internal activeCommittedOrderReservationUsdc
activeReservedSettlementReservationUsdc
mapping(bytes32 => uint256) internal activeReservedSettlementReservationUsdc
activeReservationCount
mapping(bytes32 => uint256) internal activeReservationCount
engine
address public engine
Functions
onlyOperator
modifier onlyOperator() ;
constructor
constructor(
address _settlementAsset
) Ownable(msg.sender);
Parameters
| Name | Type | Description |
|---|---|---|
_settlementAsset | address | USDC address used for PnL settlement and margin backing |
setEngine
Sets the CfdEngine address (one-time, reverts if already set).
function setEngine(
address _engine
) external onlyOwner;
deposit
Deposits settlement USDC into the specified margin account.
function deposit(
bytes32 accountId,
uint256 amount
) external;
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Deterministic account ID derived from msg.sender address |
amount | uint256 | Token amount to transfer in |
withdraw
Withdraws settlement USDC from a margin account.
function withdraw(
bytes32 accountId,
uint256 amount
) external;
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Deterministic account ID derived from msg.sender address |
amount | uint256 | USDC amount to withdraw |
getAccountEquityUsdc
Returns the total USD buying power of the account (6 decimals).
function getAccountEquityUsdc(
bytes32 accountId
) public view returns (uint256 totalEquityUsdc);
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Account to value |
Returns
| Name | Type | Description |
|---|---|---|
totalEquityUsdc | uint256 | Settlement balance in USDC (6 decimals) |
getFreeBuyingPowerUsdc
Returns strictly unencumbered purchasing power
function getFreeBuyingPowerUsdc(
bytes32 accountId
) public view returns (uint256);
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Account to query |
Returns
| Name | Type | Description |
|---|---|---|
<none> | uint256 | Equity minus locked margin, floored at zero (6 decimals) |
getAccountUsdcBuckets
Returns the explicit USDC bucket split after subtracting the clearinghouse’s typed locked-margin buckets.
function getAccountUsdcBuckets(
bytes32 accountId
) public view returns (IMarginClearinghouse.AccountUsdcBuckets memory buckets);
getFreeSettlementBalanceUsdc
function getFreeSettlementBalanceUsdc(
bytes32 accountId
) public view returns (uint256);
getTerminalReachableUsdc
Returns settlement balance reachable by a terminal settlement path.
function getTerminalReachableUsdc(
bytes32 accountId
) public view returns (uint256);
getSettlementReachableUsdc
Returns settlement balance reachable after protecting only an explicitly remaining margin bucket.
This is the canonical helper for terminal settlement paths: full closes and liquidations should pass zero protected margin, while partial closes should protect only the residual position margin that remains open after settlement.
function getSettlementReachableUsdc(
bytes32 accountId,
uint256 protectedLockedMarginUsdc
) public view returns (uint256);
lockPositionMargin
Locks margin to back a new CFD trade. Requires sufficient USDC to back settlement (non-USDC equity alone is insufficient).
function lockPositionMargin(
bytes32 accountId,
uint256 amountUsdc
) external onlyOperator;
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Account to lock margin on |
amountUsdc | uint256 | USDC amount to lock (6 decimals) |
unlockPositionMargin
Unlocks active position margin when a CFD trade closes
function unlockPositionMargin(
bytes32 accountId,
uint256 amountUsdc
) external onlyOperator;
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Account to unlock margin on |
amountUsdc | uint256 | USDC amount to unlock (6 decimals), clamped to current locked amount |
lockCommittedOrderMargin
Locks margin to back a pending order commitment.
function lockCommittedOrderMargin(
bytes32 accountId,
uint256 amountUsdc
) external onlyOperator;
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Account to lock margin on |
amountUsdc | uint256 | USDC amount to lock (6 decimals) |
reserveCommittedOrderMargin
function reserveCommittedOrderMargin(
bytes32 accountId,
uint64 orderId,
uint256 amountUsdc
) external onlyOperator;
unlockCommittedOrderMargin
Unlocks committed order margin when an order is cancelled or filled.
function unlockCommittedOrderMargin(
bytes32 accountId,
uint256 amountUsdc
) external onlyOperator;
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Account to unlock margin on |
amountUsdc | uint256 | USDC amount to unlock (6 decimals) |
releaseOrderReservation
function releaseOrderReservation(
uint64 orderId
) external onlyOperator returns (uint256 releasedUsdc);
releaseOrderReservationIfActive
function releaseOrderReservationIfActive(
uint64 orderId
) external onlyOperator returns (uint256 releasedUsdc);
consumeOrderReservation
function consumeOrderReservation(
uint64 orderId,
uint256 amountUsdc
) external onlyOperator returns (uint256 consumedUsdc);
consumeAccountOrderReservations
function consumeAccountOrderReservations(
bytes32 accountId,
uint256 amountUsdc
) external onlyOperator returns (uint256 consumedUsdc);
consumeOrderReservationsById
function consumeOrderReservationsById(
uint64[] calldata orderIds,
uint256 amountUsdc
) external onlyOperator returns (uint256 consumedUsdc);
_consumeOrderReservationsById
function _consumeOrderReservationsById(
uint64[] memory orderIds,
uint256 amountUsdc
) internal returns (uint256 consumedUsdc);
_consumeAccountOrderReservations
function _consumeAccountOrderReservations(
bytes32 accountId,
uint256 amountUsdc,
bool consumeBuckets
) internal returns (uint256 consumedUsdc);
_releaseReservation
function _releaseReservation(
IMarginClearinghouse.OrderReservation storage reservation,
bool consumeBuckets
) internal returns (uint256 releasedUsdc);
_consumeReservation
function _consumeReservation(
IMarginClearinghouse.OrderReservation storage reservation,
uint256 amountUsdc,
bool consumeBuckets,
IMarginClearinghouse.ReservationStatus terminalStatus
) internal;
_decreaseActiveReservation
function _decreaseActiveReservation(
bytes32 accountId,
IMarginClearinghouse.ReservationBucket bucket,
uint256 amountUsdc
) internal;
lockReservedSettlement
function lockReservedSettlement(
bytes32 accountId,
uint256 amountUsdc
) external onlyOperator;
unlockReservedSettlement
function unlockReservedSettlement(
bytes32 accountId,
uint256 amountUsdc
) external onlyOperator;
settleUsdc
Adjusts USDC balance to settle funding, PnL, and VPI rebates. Positive amounts credit the account; negative amounts debit it.
function settleUsdc(
bytes32 accountId,
int256 amount
) external onlyOperator;
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Account to settle |
amount | int256 | Signed USDC delta: positive credits, negative debits (6 decimals) |
creditSettlementAndLockMargin
Credits settlement USDC and locks the same amount as active margin.
function creditSettlementAndLockMargin(
bytes32 accountId,
uint256 amountUsdc
) external onlyOperator;
applyOpenCost
Applies an open/increase trade cost by debiting or crediting settlement and updating locked margin.
function applyOpenCost(
bytes32 accountId,
uint256 marginDeltaUsdc,
int256 tradeCostUsdc,
address recipient
) external onlyOperator returns (int256 netMarginChangeUsdc);
consumeFundingLoss
Consumes a funding loss from free settlement first, then from the active position margin bucket.
Unrelated locked margin remains protected.
function consumeFundingLoss(
bytes32 accountId,
uint256,
uint256 lossUsdc,
address recipient
)
external
onlyOperator
returns (uint256 marginConsumedUsdc, uint256 freeSettlementConsumedUsdc, uint256 uncoveredUsdc);
consumeCloseLoss
Consumes close-path losses from settlement buckets while preserving any explicitly protected remaining position margin.
function consumeCloseLoss(
bytes32 accountId,
uint64[] calldata reservationOrderIds,
uint256 lossUsdc,
uint256 protectedLockedMarginUsdc,
bool includeOtherLockedMargin,
address recipient
) external onlyOperator returns (uint256 seizedUsdc, uint256 shortfallUsdc);
applyLiquidationSettlementPlan
Applies a pre-planned liquidation settlement mutation.
Releases the active position margin bucket and covered committed margin exactly as planned.
function applyLiquidationSettlementPlan(
bytes32 accountId,
uint64[] calldata reservationOrderIds,
IMarginClearinghouse.LiquidationSettlementPlan calldata plan,
address recipient
) external onlyOperator returns (uint256 seizedUsdc);
_buildAccountUsdcBuckets
function _buildAccountUsdcBuckets(
bytes32 accountId
) internal view returns (IMarginClearinghouse.AccountUsdcBuckets memory buckets);
_planFundingLossConsumption
function _planFundingLossConsumption(
bytes32 accountId,
uint256 lossUsdc
) internal view returns (MarginClearinghouseAccountingLib.SettlementConsumption memory consumption);
_creditSettlementUsdc
function _creditSettlementUsdc(
bytes32 accountId,
uint256 amountUsdc
) internal;
_debitSettlementUsdc
function _debitSettlementUsdc(
bytes32 accountId,
uint256 amountUsdc
) internal;
_lockMargin
function _lockMargin(
bytes32 accountId,
IMarginClearinghouse.MarginBucket bucket,
uint256 amountUsdc
) internal;
_unlockMargin
function _unlockMargin(
bytes32 accountId,
IMarginClearinghouse.MarginBucket bucket,
uint256 amountUsdc
) internal;
_consumeOtherLockedMargin
Consumes non-position locked margin by priority: committed-order margin first, then reserved settlement. Queued order margin is released before reserved settlement because failed/cancelled order intents are softer obligations than explicitly reserved settlement buckets.
function _consumeOtherLockedMargin(
bytes32 accountId,
uint256 amountUsdc
) internal;
_consumeOtherLockedMarginViaReservations
function _consumeOtherLockedMarginViaReservations(
bytes32 accountId,
uint64[] calldata reservationOrderIds,
uint256 amountUsdc
) internal;
_consumeReservationBucket
function _consumeReservationBucket(
bytes32 accountId,
IMarginClearinghouse.ReservationBucket bucket,
uint256 amountUsdc
) internal;
_activeReservation
function _activeReservation(
uint64 orderId
) internal view returns (IMarginClearinghouse.OrderReservation storage reservation);
_closeReservation
function _closeReservation(
IMarginClearinghouse.OrderReservation storage reservation,
IMarginClearinghouse.ReservationStatus terminalStatus
) internal;
_advanceReservationHead
function _advanceReservationHead(
bytes32 accountId
) internal;
_consumeLockedMargin
function _consumeLockedMargin(
bytes32 accountId,
IMarginClearinghouse.MarginBucket bucket,
uint256 amountUsdc
) internal;
_bucketStorage
function _bucketStorage(
IMarginClearinghouse.MarginBucket bucket,
bytes32 accountId
) internal view returns (uint256 bucketValue);
_setBucketStorage
function _setBucketStorage(
IMarginClearinghouse.MarginBucket bucket,
bytes32 accountId,
uint256 amountUsdc
) internal;
_totalLockedMarginUsdc
function _totalLockedMarginUsdc(
bytes32 accountId
) internal view returns (uint256);
seizeUsdc
Transfers settlement USDC from an account to the calling operator.
The recipient must equal msg.sender, so operators can only pull seized funds into their own contract/account and must forward them explicitly afterward.
function seizeUsdc(
bytes32 accountId,
uint256 amount,
address recipient
) external onlyOperator;
Parameters
| Name | Type | Description |
|---|---|---|
accountId | bytes32 | Account to seize from |
amount | uint256 | USDC amount to seize |
recipient | address | Recipient of seized tokens (must equal msg.sender) |
seizePositionMarginUsdc
function seizePositionMarginUsdc(
bytes32 accountId,
uint256 amount,
address recipient
) external onlyOperator;
balanceUsdc
function balanceUsdc(
bytes32 accountId
) external view returns (uint256);
lockedMarginUsdc
function lockedMarginUsdc(
bytes32 accountId
) external view returns (uint256);
getLockedMarginBuckets
function getLockedMarginBuckets(
bytes32 accountId
) external view returns (IMarginClearinghouse.LockedMarginBuckets memory buckets);
getOrderReservation
function getOrderReservation(
uint64 orderId
) external view returns (IMarginClearinghouse.OrderReservation memory reservation);
getAccountReservationSummary
function getAccountReservationSummary(
bytes32 accountId
) external view returns (IMarginClearinghouse.AccountReservationSummary memory summary);
reservationHeadIndex
function reservationHeadIndex(
bytes32 accountId
) external view returns (uint256);
_toUint96
function _toUint96(
uint256 value
) internal pure returns (uint96);
Events
Deposit
event Deposit(bytes32 indexed accountId, address indexed asset, uint256 amount);
Withdraw
event Withdraw(bytes32 indexed accountId, address indexed asset, uint256 amount);
MarginLocked
event MarginLocked(bytes32 indexed accountId, IMarginClearinghouse.MarginBucket indexed bucket, uint256 amountUsdc);
MarginUnlocked
event MarginUnlocked(
bytes32 indexed accountId, IMarginClearinghouse.MarginBucket indexed bucket, uint256 amountUsdc
);
ReservationCreated
event ReservationCreated(
uint64 indexed orderId,
bytes32 indexed accountId,
IMarginClearinghouse.ReservationBucket indexed bucket,
uint256 amountUsdc
);
ReservationConsumed
event ReservationConsumed(
uint64 indexed orderId, bytes32 indexed accountId, uint256 amountUsdc, uint256 remainingAmountUsdc
);
ReservationReleased
event ReservationReleased(uint64 indexed orderId, bytes32 indexed accountId, uint256 amountUsdc);
AssetSeized
event AssetSeized(bytes32 indexed accountId, address indexed asset, uint256 amount, address recipient);
Errors
MarginClearinghouse__NotOperator
error MarginClearinghouse__NotOperator();
MarginClearinghouse__NotAccountOwner
error MarginClearinghouse__NotAccountOwner();
MarginClearinghouse__ZeroAmount
error MarginClearinghouse__ZeroAmount();
MarginClearinghouse__InsufficientBalance
error MarginClearinghouse__InsufficientBalance();
MarginClearinghouse__InsufficientFreeEquity
error MarginClearinghouse__InsufficientFreeEquity();
MarginClearinghouse__InsufficientUsdcForSettlement
error MarginClearinghouse__InsufficientUsdcForSettlement();
MarginClearinghouse__InsufficientAssetToSeize
error MarginClearinghouse__InsufficientAssetToSeize();
MarginClearinghouse__InvalidSeizeRecipient
error MarginClearinghouse__InvalidSeizeRecipient();
MarginClearinghouse__InvalidMarginBucket
error MarginClearinghouse__InvalidMarginBucket();
MarginClearinghouse__ReservationAlreadyExists
error MarginClearinghouse__ReservationAlreadyExists();
MarginClearinghouse__ReservationNotActive
error MarginClearinghouse__ReservationNotActive();
MarginClearinghouse__IncompleteReservationCoverage
error MarginClearinghouse__IncompleteReservationCoverage();
MarginClearinghouse__EngineAlreadySet
error MarginClearinghouse__EngineAlreadySet();
MarginClearinghouse__ZeroAddress
error MarginClearinghouse__ZeroAddress();
MarginClearinghouse__InsufficientBucketMargin
error MarginClearinghouse__InsufficientBucketMargin();
MarginClearinghouse__AmountOverflow
error MarginClearinghouse__AmountOverflow();