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
The source code is
src/core/Stockline.sol on GitHub. The ABI is /abis/Stockline.json.
Write methods
pause
unpause
setOperator
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.
Input parameters
setOperatorWithSig
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).
supplyCollateral
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.
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.supplyCollateral
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.
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.withdrawCollateral
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.
LIVE only. Blocked when paused. Health must hold after the pull.
withdrawCollateral
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.
Input parameters
borrow
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).
Debt is stored as scaled debt and rounded up against the borrower. The pool must hold enough idle cash or USDGPool reverts with InsufficientCash.
borrow
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).
Debt is stored as scaled debt and rounded up against the borrower. The pool must hold enough idle cash or USDGPool reverts with InsufficientCash.
repay
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.
Principal plus supplier interest goes to USDGPool. The reserve-factor slice, which was already counted at accrual, goes to FeeCollector as cash on repay.
repay
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.
Principal plus supplier interest goes to USDGPool. The reserve-factor slice, which was already counted at accrual, goes to FeeCollector as cash on repay.
deleverage
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.
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.liquidate
liquidatableSince on the first call, which starts the Dutch auction at a discount of exactly 0.
Liquidations are permissionless. The
liquidatorAllowlist flag in RiskRegistry is stored but not enforced. Call LiquidationModule.quote first to preview the repay and seize amounts.applyLiquidation
Not nonReentrant: core.liquidate already holds the lock and this is a trusted module callback.
realizeBadDebt
realizeBadDebt, capped at the pool’s outstanding debt.
SPEC: socialize via the pool now. Reserve then Backstop take priority once those ships.
accrueInterest
All state-changing entry points accrue automatically. This call is useful for keepers and indexers that want a fresh index without a position change.
Read methods
usdWithdrawPaused
maxWithdraw and maxRedeem.
Return values
health
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.
Return values
maxBorrow
This does not check book caps, issuer caps, pool cash, or regime. A borrow for exactly this amount can still revert on those.
Return values
liquidationPrice
Price of
bookId (1e36) at which this account hits LT, other books held fixed.
Return values
debtOf
Return values
booksOf
Return values
Events
SupplyCollateral
WithdrawCollateral
Borrow
Repay
AccrueInterest
Liquidate
BadDebt
Pause
Unpause
OperatorSet
Deleverage
Errors
ZeroAddress
ZeroAmount
UnknownBook
Paused
RegimeBlocked
BorrowingDisabled
borrowingEnabled flag is off.