Documentation

ExitQueue is a non-custodial exit queue for holders of locked Moonwell markets on Base. This page explains exactly what the contracts do.

Overview

Several Moonwell markets on Base have almost no free cash: holders can withdraw only when someone deposits or repays a loan, and bots race for every such deposit. ExitQueue lets holders line up for that cash and choose the discount they are willing to give for exiting earlier. The discount is the service fee.

How the queue works

  • Join: approve the mToken amount you want to exit, then call join(amount, discount). Your tokens stay in your wallet.
  • Discount: from 1% to 99.9% in 0.1% steps. Minimum order — $100 worth of the market's token (fixed in token units at deployment).
  • Order: the highest discount is filled first; within the same discount — first come, first served. Changing your order (amount or discount) moves you to the end of your discount level.
  • Fill: when cash arrives in the market, anyone can call fill(). In one transaction the contract takes mTokens from the queue in order, redeems them on Moonwell and pays each holder.
  • Partial fills: if cash covers only part of an order, the holder receives that part and the rest stays first in line.
  • Leave: call leave() or simply revoke the approval.

Payout

payout = USDC (or the market's token) actually received for your mTokens × (1 − your discount). It is computed from the real redeem result in the same transaction. The contract never takes more than the minimum of your queued amount, your approval and your balance. Either you are paid in the same transaction, or nothing is taken from you.

Dropped vs. skipped orders

  • Dropped (removed from the queue, nothing taken): approval or balance became zero, tokens can't move (e.g. used as borrow collateral), the order is worth less than one cent.
  • Skipped (keeps its place): when gas is expensive, a fully backed order whose fee doesn't cover its share of gas is skipped in the deposit race. It is filled later via loan repayments or when gas is cheaper.
  • Transfer paused by Moonwell: holders are skipped and keep their place.

Gas and the deposit race

Deposits are contested by other bots that bid priority fees. We fill an order in that race only when its fee pays for its gas with a margin (gas ≤ 50% of the order's fee). The app shows, for your amount, the minimum discount that currently qualifies. Orders below it still get filled via loan repayments (no race) or when competition calms down.

Repay with rebate

A borrower (or anyone on their behalf) can repay a Moonwell loan through repayAndFill(). The repayment goes straight to the queue in the same transaction, so nobody can take that cash in between. The payer receives 0.2% of the part of the fill funded by the repayment (cash that was already free on the market does not count). The payer sets a maximum amount and a minimum rebate; if the queue changes and the rebate would be lower, the transaction reverts.

Contracts

One immutable contract per market. Source is the same for all of them.

MarketExitQueue contract

Security

  • No owner, no admin functions, no pause, no upgradeability. All parameters are fixed at deployment.
  • Fees always go to a fixed address; whoever calls fill() gets nothing — the queue works even if the operator disappears.
  • USDC-blacklisted recipients don't block anyone: their payout is kept in the contract and can be claimed later with claim().
  • Reviewed twice (internal review and an independent adversarial review); unit, fuzz and fork tests against live Moonwell markets. An external professional audit has not been done yet.

Risks

  • Approval: you grant the contract the right to move the approved mTokens. Approve only the amount you want to exit.
  • Moonwell governance: markets can be changed, paused or reconfigured by Moonwell governance; the contract cannot be upgraded to follow such changes.
  • Speed: the queue moves only when cash arrives. In markets with little inflow, waiting can be long.
  • Fairness: markets with bad debt are a bank run — those who exit first get full value, the loss stays with those who remain. Choose your discount consciously.

FAQ

Can you take my tokens? No. The contract can move your mTokens only inside a fill that pays you in the same transaction, and never more than you approved and queued.

Why is my order not filled? Either cash hasn't reached your place in the queue, or (when gas is expensive) your order's fee doesn't cover its gas yet — it keeps its place.

Can I change the discount? Yes, join again with the new discount. You move to the end of that discount level.