useDutchAuction on, a liquidation sends seized collateral to the venue and opens an auction there instead of delivering it to the router.
A market priced from a live market price (MARKET) cannot run Dutch auctions at all, and wiring a venue for it is refused with AUCTION_UNSUPPORTED_PRICE_SOURCE. Nothing on this page turns auctions on. Once the venue is wired, the issuer enables useDutchAuction through market configuration, which is refused while no venue is wired or while the collateral token refuses it.
Check the venue
module reads the venue state live from the chain on every call.
routerAuthorized says whether the venue can hand an expired remainder to the liquidation router. tokenAdmitted says whether the collateral token accepts the venue as a holder. readFailed: true means the read failed, which is not a verdict either way.
Wire an auction venue
Wiring takes two calls towireModule. The first, without moduleAddress, deploys a new venue as a contract creation. Any wallet can deploy it, because the venue gains standing only when the market admin binds it. With a signer, the SDK reads the new address from the deployment receipt through the signer’s provider.
moduleAddress is null when the signer has no provider to read the receipt from. Read the contract address from the deployment receipt yourself in that case. A market that already names a venue is refused with MODULE_ALREADY_SET. The venue is not upgradeable.
The second call, with moduleAddress, returns the legs still missing, so a repeated call returns fewer or none. Each leg has its own authority.
MARKET_ADMIN for the binding leg and ROUTER_ADMIN for the router leg. A missing role throws a ValidationError before anything is sent, and a role that could not be read throws ROLE_UNREADABLE with a status of 503.
The two token-side legs belong to the register provider’s side, never to the market admin. When the plan carries one, the SDK refuses to sign it. Prepare without a signer and hand each leg to the wallet that holds its authority.
{ txHash } is refused, and the venue is read back from the chain on the next module call. The other auction routes cache each market’s venue for up to five minutes, so they can answer with the previous venue for that long.
Passing a different moduleAddress replaces the market’s venue. The market accepts a replacement only while the current venue has no open auction, including an expired one not yet settled. The API does not check this, so setAuctionModule reverts on chain in that case.
Read auctions
list returns every auction the venue still holds open: RUNNING ones that take bids, and EXPIRED ones that wait for settlement. get also returns closed auctions, with phase CLOSED. forLoan is a live lookup, not a history: the venue unlinks a loan from its auction when the last unit sells or the expired auction settles.
An empty list, an auction of null and AUCTION_NOT_FOUND also answer a market with no venue and a venue that could not be read. Check module before treating any of them as proof that no auction exists.
The price falls linearly from the seizure price times auctionStartPremium to that price times auctionMinPremium, across auctionDuration. The schedule is fixed when the auction opens, so later oracle updates do not move it. currentPrice reflects the moment of the request, and phase uses the API server’s clock while the venue judges by the block timestamp.
Bid on an auction
Bids can be partial: buy any quantity up tocollateralRemaining, and the auction stays open for the rest until its end time. collateralAmount is a decimal string in the collateral token’s units. The plan approves the venue for the estimated cost in the settlement token (stablecoin), then calls bidOnAuction. The approval is left out when the bidder’s allowance already covers the cost.
bidder set, the API refuses the auction’s own borrower with SELF_PURCHASE_NOT_ALLOWED and a short balance with INSUFFICIENT_BALANCE. It refuses an auction past its end time with AUCTION_EXPIRED. The venue still reverts a bid when the market is paused, when the oracle price is stale, or when the end time passes between preparing and mining.
A bid larger than the collateral left is clamped to what remains. The price only falls, so the amount paid is at or below the prepared estimatedCost, never above. The bid that buys the last unit closes the auction and settles the market’s record in the same transaction. Only its result carries auctionSettled: true, with debtCovered, shortfall, reserve and any surplus for the borrower.
Settle an expired auction
Until an expired auction is settled, its collateral is in limbo: no longer purchasable, not yet available for an off-platform sale, and the loan stays locked.settleExpired moves the unsold remainder to the liquidation router, which opens a record for it.
LIQUIDATOR_ROLE on the market. The SDK does not fill signerAddress from the signer here, because sending it turns on a LIQUIDATOR_ROLE check that applies whether or not the market is paused. Pass signerAddress yourself when settling a paused market, and the SDK checks it names the signer.
The remainder always arrives two-step, whatever the router’s atomic mode. Continue with the returned liquidationId on Liquidations: withdraw for sale, report proceeds, settle, or sell it whole where the atomic sale is offered. The 7-day write-off clock does not restart here. It runs from the original seizure into the auction.
