How PAYOFF works.
PAYOFF is a non-custodial protocol for self-repaying loans on Robinhood Chain. You borrow USDG against tokenized stocks (or WETH, USDe…) on Morpho Blue; the borrowed USDG earns Uniswap V3 trading fees and every fee is paid onto the debt. The part that does the work is a small program we call the agent; this page explains it in full.
The vault
Every position lives in its own PayoffVault, a small contract the factory clones for you. It holds one pair — collateral token and loan token — for its whole life. The collateral sits in a Morpho market under the vault's name; borrowed USDG stays in the vault until it is deployed into the pair's Uniswap V3 pool as an NFT position the vault owns.
Your money in the vault
Short version: everything in the vault is yours, only you can take it out, and you can take it out at any time. Here is where each thing sits and how it comes back.
Who can move it
The vault contract only ever sends tokens to four places: Morpho, the Uniswap position manager, the Uniswap router, and your own wallet. Your wallet is the only destination for a withdrawal. The agent's key cannot change that, and neither can PAYOFF. This is in the code, not in a promise.
How to get everything out
Two or three clicks on the vault page, in this order: Close any open position into USDG (the agent may have done this already), Repay the debt, then Withdraw collateral. If USDG is left over after repaying, Withdraw token sends it to you. Morpho will not let collateral leave while it still backs debt, which is why repay comes before withdraw.
What can make it smaller
Three things, all visible on the vault page: interest on the USDG you borrowed (the rate shown on the market), the market moving against a liquidity position (a position that holds more of the stock after the price fell is worth less in USDG), and, if the price falls far enough with nobody repaying, liquidation by Morpho. The policy's protection trigger exists to repay before that last one happens; it only works while an agent is running.
What cannot happen
Your collateral cannot be sent to someone else. The agent cannot borrow past the ceiling you set. No swap can fill below the oracle price less your slippage setting. If the price oracle stops answering, the vault refuses to trade at all rather than trade blind. Turning the agent off stops every automatic action immediately; your own buttons keep working.
If PAYOFF disappears
The vault is a contract on Robinhood Chain; it does not need this website. You can call repay, withdrawCollateral and withdrawToken from the block explorer with your owner wallet, and the collateral comes back the same way.
The policy
Borrow ceiling (max LTV)
No borrow or refinance may leave loan-to-value above this. Set it well under the market's LLTV so a price move does not become a liquidation.
Protection trigger and repay share
Once LTV reaches the trigger, protect() repays the given share of the debt: first with idle USDG, then by closing positions into USDG, then by selling collateral. That last step borrows the repayment from Morpho's flash loan, frees the collateral, sells it, and pays the loan back inside one transaction.
Max slippage
Every swap the vault makes gets a floor of the Morpho oracle price less this. Every mint and burn first checks that the pool's spot price is within this of the oracle. An operator can pass a floor of zero; the vault tightens it.
Refinancing
On Robinhood Chain one collateral usually has several Morpho markets against USDG, at different LLTVs and with different curators. Each has its own utilisation and so its own borrow rate. You allow-list the markets you trust; when one is cheaper by at least the savings threshold, has the liquidity, and keeps LTV inside the ceiling, the agent moves the whole position there: flash-borrow the debt, repay the old market, withdraw the collateral, supply it to the new market, borrow there, repay the flash loan. All or nothing.
Who runs auto-repay
By default, PAYOFF does. A program we host checks every vault whose operator is our key (0x0Cd627866983bE556cDf62C6fF3eC45a704DaC5B) once a minute and signs the steps the plan below calls for. The key is an operator: the contract lets it borrow within your ceiling, place and collect liquidity, repay, refinance between markets you allowed, and run protection. It cannot withdraw anything; every withdraw path pays the owner and nobody else. You can turn it off on the vault page, or replace it with your own key at any time. Its live status is public at payoff-agent-production.up.railway.app/health ↗.
Prefer to run it yourself? Choose "I'd rather run it myself" in the borrow wizard, save the key it makes, and start npm run agent on any machine that stays on, with PAYOFF_API_URL, PAYOFF_FACTORY_ADDRESS, AGENT_VAULTS and AGENT_PRIVATE_KEY set. It starts in dry-run: watch /decisions first, then set AGENT_DRY_RUN=false.
The agent
The brain is one file, lib/services/plan.ts, evaluated by the site for any vault at /api/vaults/<vault>/plan. In priority order: protect, refinance, close (loss limit or out of range), harvest (above the fee floor), deploy idle USDG into the pool with the best recent fee yield. The runner (agent/index.mjs) fetches the plan every tick, simulates each transaction, and signs with the operator key. It starts in dry-run. With an Anthropic key, Claude may veto an action with a reason — it can never add one.
Fees
Risks, plainly
- A concentrated position carries impermanent loss; if the stock moves out of the range it stops earning and the agent closes it into USDG, realising the move.
- Debt accrues interest whether or not the position earns. Fee income is variable; a quiet week can be a losing week.
- Liquidation protection needs the agent to be running and funded with gas. A vault with the agent turned off does not protect itself.
- Equity oracles pause outside market hours; the vault refuses to mint or burn while the pool price drifts from the oracle beyond your slippage.
- Thin markets show any rate. A "best" rate with no liquidity cannot be borrowed.
API
GET /api/health
GET /api/markets[?stocks=1] Morpho USDG markets by collateral, live rates
GET /api/markets/opportunities?from=&debt=&collateral=
GET /api/pools?collateral=0x.. Uniswap V3 pools for the pair, fee yield from recent swaps
GET /api/vaults[?owner=0x..]
GET /api/vaults/<vault> full state
GET /api/vaults/<vault>/plan what the agent would do now (with calldata)
GET /api/vaults/<vault>/activity event log
GET /api/vaults/<vault>/targets markets of the pair, for the allow-list
POST /api/vaults/<vault>/tx {action, ...} unsigned calldata for any vault action
POST /api/tx/create {marketId, operator, policy}
GET /api/leaderboard