DEVNETYou are on Solana devnet. Funds are not real. Behavior matches mainnet.

How Milky works

Milky lets you turn a graded trading card into a productive asset. This page walks through the entire round-trip of a loan, from the moment a borrower requests a quote to the moment a card is either reclaimed or auctioned.

The four roles in the protocol

Every loan involves four distinct parties:

  • Borrower — the wallet that owns the card-backed NFT and wants USDC liquidity without selling.
  • Liquidity provider (LP) — the wallet that has deposited USDC into a pool and earns interest from the loans that pool funds.
  • Oracle — an off-chain service operated by Milky that prices each card and signs that price for use on-chain. The oracle is the only entity that can attest to a card's fair market value at a given moment.
  • Auction participants — anyone who places a bid when a defaulted loan goes to auction. Bidders compete to acquire the card by repaying the debt.

There's also a fifth, semi-passive role: the pool admin, who configures each lending pool's parameters (which collections it accepts, what terms it offers, how concentrated it can become).

End-to-end flow

Quoteoff-chain
Verifymerkle proof
Createloan opens
DrawUSDC paid out
repay
CloseNFT returned
Six on-chain steps; the oracle's quote is the only off-chain interaction the borrower has to initiate.

1. Pick a card and request a quote

The borrower selects a graded card from their wallet. Milky resolves the card's grading certificate (e.g. a PSA cert number plus its grade) to a canonical asset identity, then asks the oracle for a fresh quote. The quote is short-lived (about five minutes) and contains:

  • The card's fair market value in USDC.
  • The maximum loan-to-value ratio the protocol will allow on it.
  • The term length and interest rate for the loan the borrower picked.
  • A unique quote id that prevents the same signature from being reused.

2. Verify a Merkle proof on-chain

Milky maintains a rotating allowlist of every card eligible to be used as collateral. Before opening a loan, the borrower submits a small Merkle proof that proves their card is in that allowlist for the current root version. This produces a proof receipt account that the next instruction will consume.

3. Open the loan

The borrower submits the signed oracle quote together with the proof receipt. The protocol verifies the oracle's Ed25519 signature, checks that all the on-chain caps are respected (LTV ceilings, principal limits, per-card and per-asset-type concentration limits), and creates the loan in a Created state. At this point no money or NFT has moved yet — there is a short "pending draw" window during which the borrower can complete the next step.

4. Draw the funds and lock the card

Drawing transfers the borrower's NFT into the protocol's collateral vault and sends them USDC equal to the principal minus the origination fee (the fee is withheld from disbursement). The loan becomes Active, and the maturity clock starts ticking.

5a. Repay before maturity (the happy path)

To close the loan, the borrower pays back the principal plus the full fixed interest. The card is unlocked and returned, and the loan account is closed, refunding rent. There is no early-repayment penalty and no prepayment discount: the interest is fixed at draw time.

5b. Default after maturity (the unhappy path)

If the borrower does not repay by maturity plus the grace period, anyone (typically a keeper bot) can mark the loan as defaulted. This atomically transitions the loan into auction state: the collateral stays locked, but control of the asset transfers from the borrower to the auction process.

6. Auction settlement (only if defaulted)

A Dutch auction starts at roughly twice the total payoff and decays linearly over a few minutes down to the payoff floor. The first bidder to accept the current price wins the card, and the bid is split between the pool (to repay the debt) and the protocol (a percentage of any surplus). The defaulted borrower does not receive any leftover proceeds.

If no bidder appears before the auction expires, the card moves into pool-held custody until the pool admin retrieves it.

Where the protocol lives

Milky is deployed on Solana. The on-chain program is written in Anchor, and all loan, pool, auction, and oracle accounts are publicly inspectable. The off-chain components (oracle, keeper bots, indexers) are operated by Milky today, with a roadmap toward multi-party operation as the protocol matures.

Continue reading