Skip to content

Margin and liquidation ​

Each market holds its own collateral. Margin in the MON market does not support a position in the ETH market. The two markets use the same test risk constants.

Source: contracts/src/Market.sol, especially _exposure, _margin, accountState, withdraw, and liquidate.

Test constants

The margin constants, the return cap, and the seven-day horizon are test inputs. They are not approved launch parameters. They need separate calibration for each asset before use with real funds.

Account values ​

accountState(address) returns these values. The API returns the same fields in GET /account.

FieldMeaning
cashDeposits, minus withdrawals, plus realized profit, plus funding, minus fees
positionThe book position in contracts. Positive is long.
entryThe average entry price of the book position
fundedPositionThe funding position. See delayed funding activation.
funding, realized, feesCumulative totals of the account
equitycash + position * 100 * (mark - entry)
initialMargin, maintenanceMarginThe two requirements below
freeCollateralThe smaller of cash and equity - initialMargin, or zero
liquidatingTrue while a liquidation of the account is not complete

An account read includes the funding that is not yet stored. The contract stores it in cash when the account is next used.

Exposure ​

Margin uses the worst exposure of the account, not only the book position.

text
long exposure  = max(position + resting buys, funding position, 0)
short exposure = max(resting sells - position, -funding position, 0)
exposure       = max(long exposure, short exposure)

Resting buys and resting sells include real orders, live ladder levels, and queued requests. A closed book position does not remove its funding position from this calculation.

Maintenance margin uses the book position and the funding position only. It does not include resting orders.

The margin formula ​

Margin has two parts: a reserve for a change of the mark, and a buffer for funding.

text
mark reserve   = exposure * 100 * (0.25 + 0.5 * mark)

long loss      = charge * gap limit / 31536000
funding loss   = max(long exposure * long loss, short exposure * 0.0025)
funding buffer = funding loss * 100 * (365 / 7) * B
RequirementMark reserveBuffer observations B
Initial margin100% of the mark reserve3
Maintenance margin60% of the mark reserve1

A long reserves the fixed charge for the largest permitted gap. A short reserves the capped return. The gap limit is three observation intervals. Margin calculations round up.

Example ​

Take 41 contracts, a mark and a charge of 1.573, and a 60-second market. The gap limit is 180 seconds.

ValueLong 41Short 41
Mark reserve4,249.654,249.65
Funding buffer, initial5.761,603.39
Initial margin4,255.415,853.04
Funding buffer, maintenance1.92534.46
Maintenance margin2,551.713,084.25

Values are in USDC before integer rounding. The short needs more margin, because one capped observation can cost the short much more than one interval of charge costs the long.

Checks at an order ​

MomentCheck
Before matchingThe full order size is added to the exposure. The exposure must be within the position limit, and the equity must cover initial margin. An order that only reduces the position skips the margin check.
At each fill, for the maker and the takerThe account after the fill must cover initial margin at the mark. During a mark freeze, it must also cover it at the execution price.
Before the remainder restsThe account must cover initial margin with the resting remainder. If not, the contract cancels the remainder.

The position limit is 1,000 contracts for each account and direction. A session has its own lower limit. See Wallet and sessions.

Withdrawal ​

A withdrawal needs all of these conditions:

  • The oracle is not halted, and no observation is due.
  • The mark is valid after an update in the same call.
  • The account is not in liquidation.
  • The cash covers the amount.
  • The equity after the withdrawal covers initial margin.

A positive freeCollateral value does not bypass the oracle gate or the mark gate. A closed book position can keep a funding position for one more observation. Its margin becomes free after that observation.

Liquidation ​

Any address can call liquidate(account, maxMatches).

  1. The call waits if the oracle is halted, an observation is due, or the mark is not valid. It then emits LiquidationAttempt with waiting set.
  2. An account with a book position must have equity below maintenance margin, or a liquidating flag from an earlier call. If not, the call reverts with HEALTHY.
  3. The contract sets the liquidating flag, cancels the resting orders of the account, and takes its ladders out of the book.
  4. The contract sends an IOC order that closes the book position against real book depth. The price limit is 25% from the current mark.
  5. A forced fill can only reduce the position. A full close clears the liquidating flag.

Liquidation can fill a part of the position, or it can find no liquidity. Call it again when depth is available. While the flag is set, the account cannot place orders or withdraw.

Liquidation reduces the book position. It cannot remove the funding position that the account keeps until the next observation.

No insurance fund

A deficit stays visible. LiquidationAttempt reports negative equity as a deficit. The build has no insurance fund and no rule that allocates bad debt. Positive equity in a market with deficits has no guarantee of payment.

The keeper command liquidate checks an account, simulates the call, and sends it. See Scripts and keeper commands.

Fees ​

The trade fee is 0.05% of size * 100 * execution price for each side of a fill. The contract records fees in the market. It has no fee withdrawal function.

Deployed on Monad testnet.