Result of MusdClient.previewOpen: an explicit verdict plus every raw number.

interface OpenPreview {
    bindingConstraint: null | OpenBlockReason;
    entireDebt: bigint;
    fee: bigint;
    feeExempt: boolean;
    icr: bigint;
    icrThreshold: bigint;
    isRecoveryMode: boolean;
    liquidationPrice: bigint;
    meetsMinimum: boolean;
    netDebt: bigint;
    reasons: OpenBlockReason[];
    resultingTcr: bigint;
    troveStatus: undefined | number;
    viable: boolean;
}

Properties

bindingConstraint: null | OpenBlockReason

The constraint that binds first, or null when viable.

entireDebt: bigint

netDebt + 200 gas reserve.

fee: bigint

The fee the contract will ACTUALLY charge: zero in Recovery Mode or when exempt.

feeExempt: boolean

Whether the account is fee exempt. false when no account was supplied.

icr: bigint

computeICR(collateral, entireDebt, price).

icrThreshold: bigint

The threshold icr is measured against: CCR in Recovery Mode, MCR in normal mode.

isRecoveryMode: boolean

checkRecoveryMode(price), always surfaced.

liquidationPrice: bigint

Price at which the opened position would hit MCR.

meetsMinimum: boolean

netDebt >= minNetDebt(), the debt floor.

netDebt: bigint

debt + fee, the quantity the minNetDebt floor is checked against.

reasons: OpenBlockReason[]

Every reason it is not viable, in a fixed order. Empty when viable.

resultingTcr: bigint

The resulting system TCR if this open went through.

troveStatus: undefined | number

TroveManager.getTroveStatus(account) for the account this preview was run for, or undefined when no account was supplied (MK-047).

undefined is not "no Trove", it is "not asked". Without an account there is nobody to ask about, so the TROVE_ALREADY_ACTIVE gate cannot be evaluated and is not reported, exactly as feeExempt reports the same absence for the fee gate. Pass account whenever you have it; a preview rendered from a wallet always has it.

viable: boolean

True only when every condition _openTrove enforces is satisfied.

The four gates, in the order the contract runs them: the Trove is not already active (:633), the debt floor (:645), the mode correct individual ratio (:655 or :657), and in normal mode the resulting system ratio (:665).

This docstring used to make that claim while the code checked three of the four (MK-047). _requireTroveisNotActive was missing, so an owner who already held a Trove got viable: true and the contract refused with BorrowerOps: Trove is active. The claim and the code now agree, and open-gates.test.ts pins the count so they cannot drift apart silently again.

viable REPLACES meetsRecoveryRequirement, which was true for every open in normal mode and therefore could never warn about anything (MK-005).