Skip to main content
Stockline is the immutable lending core. It holds every account’s collateral and scaled debt per book, accrues interest through a per-book borrow index, and enforces the action table from each book’s oracle regime. Risk parameters live in RiskRegistry, USDG liquidity lives in USDGPool, and liquidation sizing lives in LiquidationModule. The contract has no owner, no upgrade path, and no admin setters. Stockline lets you:
  • Supply stock tokens as collateral to a book, for themselves or for another account
  • Borrow USDG against cross-collateral positions while the regime is LIVE
  • Repay debt and add collateral in every regime, even when paused
  • Withdraw collateral while the position stays above the line
  • Deleverage by selling collateral through a callback and repaying in the same transaction
  • Liquidate positions below the liquidation threshold in LIVE or DARK
  • Grant operator rights to routers with a call or an EIP-712 signature
  • Read health, max borrow, liquidation price, and per-book debt
Addresses per network. Every address is also on Addresses. The source code is src/core/Stockline.sol on GitHub. The ABI is /abis/Stockline.json.

Write methods

pause

Turns on the pause. Only the guardian address can call it. Pause blocks borrow, withdrawCollateral, liquidate, and USDG withdrawal from the pool. It never blocks repay, supplyCollateral, or deleverage.
Guardian only. Reverts with NotGuardian otherwise.

unpause

Turns off the pause. Only the guardian address can call it.
Guardian only. Reverts with NotGuardian otherwise.

setOperator

Approves or revokes operator to act on the caller’s positions. An operator can borrow, withdraw collateral, and deleverage on the caller’s behalf. Reverts with ZeroAddress for the zero address.
An operator can borrow USDG to any receiver and withdraw collateral to any address. Approve only contracts you trust.
Input parameters

setOperatorWithSig

Sets an operator for account using an EIP-712 signature so an EOA can approve a router and act in one transaction. Reverts with Expired after deadline, InvalidSignature when the signer is not account, and ZeroAddress for zero addresses. Each successful call consumes the account’s current operatorNonce.
Domain: name “Stockline”, version “1”, the current chain id, and this contract’s address. Type: Operator(address account,address operator,bool approved,uint256 nonce,uint256 deadline).
Input parameters

supplyCollateral

Pulls amount of the book’s collateral token from the caller and credits it to onBehalfOf (or to the caller in the two-argument form). Always live: it works in every regime and while paused. Reverts with ZeroAmount on a zero amount, UnknownBook on an unknown book, and ZeroAddress when onBehalfOf is the zero address.
The caller must first approve Stockline to spend amount of the collateral token. Tokens are pulled from the caller, not from onBehalfOf.
If prices are available for every book the account holds, this call also refreshes liquidatableSince, which can end an open auction once the account is healthy again.
Input parameters

supplyCollateral

Pulls amount of the book’s collateral token from the caller and credits it to onBehalfOf (or to the caller in the two-argument form). Always live: it works in every regime and while paused. Reverts with ZeroAmount on a zero amount, UnknownBook on an unknown book, and ZeroAddress when onBehalfOf is the zero address.
The caller must first approve Stockline to spend amount of the collateral token. Tokens are pulled from the caller, not from onBehalfOf.
If prices are available for every book the account holds, this call also refreshes liquidatableSince, which can end an open auction once the account is healthy again.
Input parameters

withdrawCollateral

Moves amount of collateral out of a book and sends it to to (or to the caller in the two-argument form). Requires the book’s regime to be LIVE and the protocol to be unpaused. Reverts with Unhealthy when the remaining collateral, valued at the liquidation threshold, no longer covers total debt.
Blocked while paused (Paused) and in every regime other than LIVE (RegimeBlocked). The four-argument overload reverts with NotOperator unless the caller is onBehalfOf or an approved operator.
LIVE only. Blocked when paused. Health must hold after the pull.
Input parameters

withdrawCollateral

Moves amount of collateral out of a book and sends it to to (or to the caller in the two-argument form). Requires the book’s regime to be LIVE and the protocol to be unpaused. Reverts with Unhealthy when the remaining collateral, valued at the liquidation threshold, no longer covers total debt.
Blocked while paused (Paused) and in every regime other than LIVE (RegimeBlocked). The four-argument overload reverts with NotOperator unless the caller is onBehalfOf or an approved operator.
Input parameters

borrow

Draws amount USDG from USDGPool against the account’s collateral and sends it to receiver (or to the caller in the two-argument form). Requires LIVE regime, unpaused state, and borrowingEnabled on the book. Reverts with CapExceeded when the book’s debt would pass borrowCap, IssuerCapExceeded when the issuer’s total would pass issuerCap, and Unhealthy when total debt would exceed borrow power (collateral valued at LTV).
Borrow power uses LTV, not the liquidation threshold. Borrowing up to the maximum leaves the position one small price move away from the line. The four-argument overload reverts with NotOperator unless the caller is onBehalfOf or an approved operator.
Debt is stored as scaled debt and rounded up against the borrower. The pool must hold enough idle cash or USDGPool reverts with InsufficientCash.
Input parameters

borrow

Draws amount USDG from USDGPool against the account’s collateral and sends it to receiver (or to the caller in the two-argument form). Requires LIVE regime, unpaused state, and borrowingEnabled on the book. Reverts with CapExceeded when the book’s debt would pass borrowCap, IssuerCapExceeded when the issuer’s total would pass issuerCap, and Unhealthy when total debt would exceed borrow power (collateral valued at LTV).
Borrow power uses LTV, not the liquidation threshold. Borrowing up to the maximum leaves the position one small price move away from the line. The four-argument overload reverts with NotOperator unless the caller is onBehalfOf or an approved operator.
Debt is stored as scaled debt and rounded up against the borrower. The pool must hold enough idle cash or USDGPool reverts with InsufficientCash.
Input parameters

repay

Pulls USDG from the caller and reduces the debt of onBehalfOf (or the caller) in one book. Always live: it works in every regime and while paused. The amount is capped at the outstanding debt, so passing a larger number closes the book cleanly. Reverts with ZeroAmount when there is nothing to repay.
The caller must approve Stockline to spend the USDG. The payer is always the caller, never onBehalfOf.
Principal plus supplier interest goes to USDGPool. The reserve-factor slice, which was already counted at accrual, goes to FeeCollector as cash on repay.
Input parameters

repay

Pulls USDG from the caller and reduces the debt of onBehalfOf (or the caller) in one book. Always live: it works in every regime and while paused. The amount is capped at the outstanding debt, so passing a larger number closes the book cleanly. Reverts with ZeroAmount when there is nothing to repay.
The caller must approve Stockline to spend the USDG. The payer is always the caller, never onBehalfOf.
Principal plus supplier interest goes to USDGPool. The reserve-factor slice, which was already counted at accrual, goes to FeeCollector as cash on repay.
Input parameters

deleverage

Releases amount of collateral from fromBook to callee, calls callee.onDeleverage, then repays repayBook from whatever USDG the callee sent back. Skips the LIVE and pause gates because the net effect only reduces risk. Reverts with NotOperator unless the caller is account or its operator, ZeroAmount if the callback returns no USDG or the repay book has no debt, and Unhealthy if the account ends below the liquidation threshold.
The callee receives the collateral before any USDG is checked. Only use a callee you trust, such as PositionRouter.
USDG the callee returns beyond the debt of repayBook is forwarded to account. The callback runs under the reentrancy lock, so the callee must not call back into Stockline.
Input parameters

liquidate

Liquidates part of an unhealthy account through LiquidationModule. Requires the book’s regime to be LIVE or DARK and the protocol to be unpaused. Reverts with NotLiquidatable when the account is at or above the liquidation threshold. Sets liquidatableSince on the first call, which starts the Dutch auction at a discount of exactly 0.
The liquidator must approve Stockline to spend USDG before calling. Stockline pulls the final repay amount from msg.sender inside applyLiquidation. In DARK the price carries the dark haircut, so the seize is priced against a reduced value.
Liquidations are permissionless. The liquidatorAllowlist flag in RiskRegistry is stored but not enforced. Call LiquidationModule.quote first to preview the repay and seize amounts.
Input parameters

applyLiquidation

Callback that LiquidationModule invokes after sizing a liquidation. Cuts the account’s debt, moves seized collateral to the liquidator and to FeeCollector, and pulls the repay USDG from the liquidator. Reverts with NotModule for any other caller and InsufficientCollateral when the seize exceeds the balance.
Module only. Do not call this directly; use liquidate.
Not nonReentrant: core.liquidate already holds the lock and this is a trusted module callback.
Input parameters

realizeBadDebt

Writes off every remaining debt of an account that holds no collateral in any book. Only LiquidationModule can call it, after a liquidation leaves the account bare. Reverts with StillCollateralized if any book still holds collateral. The written-off amount is socialized to USDGPool through realizeBadDebt, capped at the pool’s outstanding debt.
Module only. Suppliers absorb the loss through a lower sUSDG share price until FeeCollector covers it from the reserve.
SPEC: socialize via the pool now. Reserve then Backstop take priority once those ships.
Input parameters

accrueInterest

Advances the borrow index of one book to the current timestamp. Anyone can call it. Interest splits into the supplier slice (reported to USDGPool) and the reserve-factor slice (reported to FeeCollector). Reverts with UnknownBook for an unknown book.
All state-changing entry points accrue automatically. This call is useful for keepers and indexers that want a fresh index without a position change.
Input parameters

Read methods

usdWithdrawPaused

Returns true while the guardian pause is active. USDGPool reads this to zero out maxWithdraw and maxRedeem. Return values

health

Returns the account’s health factor in WAD (1e18). The value is the sum of collateral valued at each book’s liquidation threshold, divided by total debt. Below 1e18 the account can be liquidated. Returns the maximum uint256 when the account has no debt.
This view reads every book’s oracle price, so it reverts with PriceUnavailable when any held book is HALTED, in CA_WINDOW, or SEQ_DOWN.
Input parameters Return values

maxBorrow

Returns how much more USDG the account can borrow right now. Borrow power is collateral valued at LTV; the result is that power minus total debt, or 0 when debt already exceeds it.
This does not check book caps, issuer caps, pool cash, or regime. A borrow for exactly this amount can still revert on those.
Input parameters Return values

liquidationPrice

Returns the collateral price of one book at which the account reaches the liquidation threshold, with every other book held fixed. Returns 0 when the other books alone cover the debt or when the account holds none of this collateral.
Price of bookId (1e36) at which this account hits LT, other books held fixed.
Input parameters Return values

debtOf

Returns the account’s current debt in one book, including interest accrued up to the current block that has not yet been written to storage. Input parameters Return values

booksOf

Lists the books in which the account holds collateral or debt. A book is removed from the list once both are zero. Input parameters Return values

Events

SupplyCollateral

Fires when collateral is credited to an account in a book.

WithdrawCollateral

Fires when collateral leaves an account’s book.

Borrow

Fires when USDG debt is added to an account in a book.

Repay

Fires when debt is reduced by a repay, with the amount actually paid.

AccrueInterest

Fires when a book’s index advances, with the interest, the reserve slice, and the new index.

Liquidate

Fires after a liquidation through LiquidationModule, with the repay amount the liquidator requested.

BadDebt

Fires when an account’s leftover debt is written off and socialized to the pool.

Pause

Fires when the guardian turns the pause on.

Unpause

Fires when the guardian turns the pause off.

OperatorSet

Fires when an operator is granted or revoked, by call or by signature.

Deleverage

Fires after a deleverage, with the collateral released and the USDG repaid.

Errors

ZeroAddress

A required address argument was the zero address.

ZeroAmount

An amount was zero, or a repay or deleverage found nothing to repay.

UnknownBook

The book id does not exist in RiskRegistry.

Paused

The guardian pause blocks borrow, withdrawCollateral, and liquidate.

RegimeBlocked

The book’s oracle regime does not allow the action. Borrow and withdraw need LIVE; liquidate needs LIVE or DARK.

BorrowingDisabled

The book’s borrowingEnabled flag is off.

CapExceeded

The borrow would push the book’s total debt above its borrow cap.

IssuerCapExceeded

The borrow would push the issuer’s aggregate debt above its issuer cap.

Unhealthy

The action would leave the account below the line (borrow uses LTV, withdraw and deleverage use the liquidation threshold).

InsufficientCollateral

The requested collateral amount exceeds the account’s balance in that book.

NotGuardian

Only the guardian can pause or unpause.

NotModule

Only LiquidationModule can call applyLiquidation and realizeBadDebt.

NotLiquidatable

The account’s health is at or above 1e18.

StillCollateralized

realizeBadDebt was called while the account still holds collateral.

NotOperator

The caller is neither the account nor an approved operator.

Expired

The signature deadline has passed.

InvalidSignature

The recovered signer does not match the account.