Skip to content
Developers

ABI

How the ABIs will be published, and the public surface of every module so you can plan an integration before they exist.

The ABIs do not exist yet, because nothing is deployed. This page tells you how they will be published and what will be in them, so that you can design against the interface now.

How the ABIs will be published

Four sources, in order of authority:

  1. Verified source on Blockscout, for both mainnet and testnet, at deployment. This is the authoritative ABI: it is generated from the bytecode you can read at the address.
  2. The repository, which ships out/*.sol/*.json from the Foundry build, plus a hand-maintained abi/ directory containing the flattened interface of each module. The compiler is pinned to Solidity 0.8.26 with published optimiser settings, so a local forge build reproduces the deployed bytecode byte for byte — this equality is asserted by the deployment test (Rule R-16.5.1).
  3. An npm package exporting typed ABIs and address maps per chain id, for TypeScript integrations.
  4. forge doc output, published as static pages, giving the NatSpec of every public function alongside its signature.

Because the contracts are immutable, an ABI never changes after publication. There is no versioning problem, no upgrade to track, and no proxy indirection to resolve. An ABI you pin today is correct for the life of the deployment.

Guarantee

No published ABI will ever contain a function named set*, add*, remove*, grant*, revoke*, upgrade*, transferOwnership or pause — other than updateMintFreeze, which computes a state rather than setting one. Their absence is asserted at deployment and fuzzed continuously (Rule R-16.5.1, Rule R-12.2.1).

Public surface by module

The signatures below are the specification's, and are what the published ABIs will contain. Views are omitted where they are obvious. Full context for each module: Modules.

FYUSD

function mint(address to, uint256 amount) external;                 // onlyMinter
function burn(uint256 amount) external;
function burnFrom(address from, uint256 amount) external;
function minted(address) external view returns (uint256);
function isMinter(address) external view returns (bool);
// plus the standard ERC-20 and ERC20Permit surface

OracleAdapter

function quote() external view returns (Quote memory);
function poke() external;
function markShutdown(uint256 lastGood) external;      // onlyBranch
function longestDegraded() external view returns (uint64);
function deployedAt() external view returns (uint64);

The PriceView struct carries pComposite, ageComposite, pDex, dDex, dispBps, uBps, confBps, bandBps, pRef, pLiq, pRedeem, sources, regime, plus preAction, quietEdge, edgeUntil and degradedSince. Read all of it; do not reduce it to a single price.

LiquidityOracle

function poke() external;
function d2Now() external view returns (uint256);
function d2Eff() external view returns (uint256);
function d2P25() external view returns (uint256);
function bufferFill() external view returns (uint16);
function poolDepths() external view returns (uint256[] memory);

RateFloor

function poke() external;
function rRef() external view returns (uint256);
function floor(uint8 tier) external view returns (uint256);

Branch

Write functions:

function open(uint256 coll, uint256 debt, uint256 annualRate, Hints calldata h) external;
function adjust(int256 collDelta, int256 debtDelta, Hints calldata h) external;
function addCollateral(address onBehalfOf, uint256 amount) external;
function repay(address onBehalfOf, uint256 amount) external;
function withdraw(uint256 amount, address to) external;
function borrow(uint256 amount, address to) external;
function close() external;
function setRate(uint256 annualRate, Hints calldata h) external;
function setRateFor(address user, uint256 annualRate, Hints calldata h) external;
function setDelegate(address manager, uint256 minRate, uint256 maxRate) external;
function clearDelegate() external;
function claimSurplus() external;
function accrue() external;
function updateMintFreeze() external;
function activate() external;
function flagShutdown() external;
function shutdown() external;
function settleAfterShutdown(address user) external;
function checkUpgrade() external;
function forceShutdown() external;                      // onlyCloser
function freeze(uint8 mask, uint64 until) external;     // onlyCloser
function freezeLiquidation(uint64 until) external;      // onlyCloser
function unfreeze() external;                           // onlyCloser

Views:

function getDebt(address) external view returns (uint256);
function getICR(address, uint256 price) external view returns (uint256);
function getTCR(uint256 price) external view returns (uint256);
function getEntireDebt() external view returns (uint256);
function debtCeiling() external view returns (uint256);
function cAbs() external view returns (uint256);
function addressCap() external view returns (uint256);
function isActive() external view returns (bool);
function canActivate() external view returns (bool, uint8 failingCriterion);

Typed errors you should handle: StateForbids(op, state), ICRBelowMint, TCRBelowCCR, DebtBelowMin, CeilingExceeded, AddressCapExceeded, PositionMaxExceeded, SameBlockTouch, RateOutOfBounds(floor, max), NotDelegate, Shutdown, NotActivated, ActivationCriterionFailed(uint8), FrozenByCloser(op, until), UpgradeFreeze(until), CloserExpired.

Events you should index: PositionOpened, PositionAdjusted, RateChanged, InterestMinted, InterestClockPaused, InterestClockResumed, Liquidated, Redeemed, MintFreeze, Activated, CapTierReached, CapTierLocked, Shutdown, Settled, BadDebtRecorded, SurplusClaimed, UpgradeDetected, UpgradeCleared, UpgradeExtended, Frozen, LiquidationFrozen, Unfrozen.

SortedTroves

function insert(address user, uint256 rate, address prevHint, address nextHint) external;
function remove(address user) external;
function reInsert(address user, uint256 rate, address prevHint, address nextHint) external;
function getFirst() external view returns (address);
function getNext(address) external view returns (address);
function findInsertPosition(uint256 rate, address prevHint, address nextHint) external view returns (address, address);

Compute hints off-chain with findInsertPosition and pass them in; without hints, insertion is O(n).

StabilityPool

function provide(uint256 amount) external;
function withdraw(uint256 amount) external;
function claimCollateral() external;
function offset(uint256 debt, uint256 coll) external;   // onlyLiquidationEngine or onlyBranch
function triggerYield(uint256 amount) external;         // onlyInterestRouter
function getDeposit(address) external view returns (uint256);
function getCollateralGain(address) external view returns (uint256);
function totalDeposits() external view returns (uint256);
function cap() external view returns (uint256);
function capPerAddress() external view returns (uint256);

LiquidationEngine

function flag(address branch, address user) external;
function liquidate(address branch, address user, uint256 maxDebtToRepay)
    external returns (uint256 debtRepaid, uint256 collSeized);
function bucketAvailable(address branch) external view returns (uint256);
function previewLiquidation(address branch, address user)
    external view returns (uint256 debtLiq, uint256 coll, uint256 bonus, uint256 price, uint8 mode);

RedemptionRouter

function redeem(uint256 amount, uint256 maxIterationsPerBranch, uint256[] calldata minCollOut, uint256 maxFeeWad)
    external returns (uint256 burned);
function urgentRedeem(address branch, uint256 amount, address[] calldata users, uint256 minCollOut) external;
function baseRate() external view returns (uint256);
function getRedemptionFee(uint256 amount) external view returns (uint256 feeWad);
function eligibleBranches() external view returns (address[] memory, uint256[] memory unbackedDebt);

InterestRouter, Backstop, PoolIncentive

function route(uint256 amount) external;                          // onlyBranch or onlyPSM
function latchFeeSwitch() external;
function shares() external view returns (uint256 sp, uint256 treasury, uint256 pil, uint256 backstop);

function fund(uint256 amount) external;
function coverBadDebt(address branch, uint256 amount) external;
function redistribute(address branch) external;
function receiveCollateral(address branch, uint256 amount) external;   // onlyLiquidationEngine
function sellCollateral(address branch, uint256 amount, uint256 minFy) external;

function stake(uint256 tokenId) external;
function unstake(uint256 tokenId) external;
function checkpoint() external;
function claim() external;
function purge() external;

PSM

function swapIn(uint256 usdgAmount, uint256 minFyOut) external returns (uint256);
function swapOut(uint256 fyAmount, uint256 minUsdgOut) external returns (uint256);
function repayWithUSDG(address branch, address onBehalfOf, uint256 usdgAmount, uint256 minDebtRepaid) external;
function swapInToSP(address branch, uint256 usdgAmount, uint256 minDeposit) external;
function reserve() external view returns (uint256);
function intakeCapacity() external view returns (uint256);
function feeIn() external view returns (uint256);
function feeOut() external view returns (uint256);
function capShare() external view returns (uint256);
function freezeIntake(uint64 until) external;      // onlyCloser
function unfreezeIntake() external;                // onlyCloser

BranchRegistry

function branches() external view returns (address[] memory);
function allBranches() external view returns (address[5] memory);
function isBranch(address) external view returns (bool);
function aggregateTCR() external view returns (uint256);
function flagSunset() external;
function enterSunset() external;
function sunsetAt() external view returns (uint64);

sfyUSD, CollateralSale, Router

// sfyUSD: the full ERC-4626 surface, plus
function redeemInKind(uint256 shares, address receiver) external;
function harvest() external;

// CollateralSale
function start(uint256 amount) external;                     // onlyWrapper
function buy(uint256 collAmount, uint256 maxFyIn) external;
function discount() external view returns (uint256);
function inventory() external view returns (uint256);

// Router
function depositUSDG(address branch, uint256 usdg, address receiver, uint256 minShares)
    external returns (uint256 shares);
function withdrawToUSDG(address branch, uint256 shares, address receiver, uint256 minUsdg)
    external returns (uint256 usdg, uint256 fyLeft);

Closer

function freeze(address branchOrAll, uint8 mask, uint64 duration) external;   // onlySafe
function freezeLiquidation(address branch, uint64 duration) external;         // onlySafe
function unfreeze(address branchOrAll) external;                              // onlySafe
function shutdown(address branch) external;                                   // onlySafe
function shutdownAll() external;                                              // onlySafe
function renounce() external;                                                 // onlySafe
function expiresAt() external view returns (uint64);
function isAlive() external view returns (bool);

Conventions

  • WAD = 1e18 for every ratio, price and share. RAY = 1e27 for interest indices. No basis points appear anywhere in the code.
  • Ratios are WAD, so 125% is 1.25e18.
  • Prices are USD per raw token, already carrying the ERC-8056 multiplier. Never apply uiMultiplier() to a valuation.
  • Time is block.timestamp. Nothing in the protocol reads a market calendar.
  • Errors are typed custom errors, not revert strings. Decode them.

Last reviewed: 2026-09-07 · Spec v0.4