> For the complete documentation index, see [llms.txt](https://docs.efficientdex.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.efficientdex.com/run-a-pool/operate-a-pool.md).

# Operate a pool

How a pool operator keeps an Efficient pool running: the keeper's calls, the calls open to anyone, hook changes, monitoring, emergencies and practice on Base.

**A live Efficient pool needs regular calls between swaps.** Its hooks rely on some of them. Once the pool borrows, it also needs collateral top-ups. The pool operator can make these calls itself or appoint a keeper, and a few are open to anyone.

[Configure a pool](/run-a-pool/configure-a-pool.md) covers the settings before launch. [Roles and governance](/run-a-pool/roles-and-governance.md) lists every call each role can make and the notice each change gets.

## The keeper's calls

**The keeper runs routine maintenance inside limits set by the pool operator and the code.** The pool operator can make every keeper call itself.

| Call                                                 | Contract           | What it does                                                                                                                                                                  |
| ---------------------------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `recenter(minAnchorN36, maxAnchorN36, deadline)`     | Pool               | Asks the recentring hook to move its anchor inside the caller's bounds. Never runs while paused                                                                               |
| `setDials(phiWad, ltvWad)`                           | Pool               | Moves the credit setting and the LTV pin inside their envelope. A rise in the pin has a step limit, and the two share a cooldown                                              |
| `setPriorities(borrow_, supply_, withdraw_, repay_)` | Pool               | Sets the order in which the pool uses its venues. A venue is a position at one lending market                                                                                 |
| `maintain(kind, a, b, amount)`                       | Pool               | Tops up or releases collateral, refinances debt or moves supply. Works only while feature bit 4, `FEATURE_MAINTENANCE`, is on                                                 |
| `setTuning(Tuning)`                                  | Everlong hook      | Posts the hook's whole tuning row, inside the bounds the pool operator sets with `setBounds`. The row's largest recentre step can be at most twice the lowest fee a fill pays |
| `setTargetApr(aprWad)`                               | Tranche controller | Moves the senior tranche's target rate inside its envelope                                                                                                                    |

A lower LTV pin skips the step limit. It skips the cooldown too, if two conditions hold. The credit setting must not rise, and a lending market's liquidation LTV must sit under the pin plus the safety gap. Only a lending market that can lend to the pool, or still holds its debt, counts towards that exception. [Credit and collateral](/how-pools-work/credit-and-collateral.md#moving-the-dials) covers these rules.

`setPriorities` and `maintain` act only in a pool with a lending market. A controller hook can also call `setPriorities`, `maintain` and `recenter`. That lets the order of lending markets follow conditions the pool operator sets.

A hook with an anchor, such as the Everlong hook, needs recentres to follow the market. A hook that prices straight from the feed needs none. [The Everlong strategy](https://docs.foreverlong.io/everlong/everlong-strategy) covers the Everlong hook's settings.

## Calls open to anyone

**A pool that borrows needs regular calls to `maintainCollateral()`.** That's because not every flow posts collateral. Only a proportional deposit and a sell or loan-to-loan swap that borrows do. See [Credit and collateral](/how-pools-work/credit-and-collateral.md#collateral-top-ups).

* `poke()` passes the current feed price to the recentring hook's `observe`. A swap records no observation unless its hook folds in the price the swap carries. So pokes and recentres keep a hook current. In a pool with no price band, `poke()` reverts with `NoBand`, and a recentre passes the hook no reference price. There, only a hook that can move its anchor without one follows the market. The Everlong hook can't.
* `maintainCollateral()` posts unposted pool asset at the least healthy venue that has fallen due. It posts enough to bring that venue back to what the LTV pin requires. A venue carrying debt falls due once its LTV has used a fifth of the room from the pin to its liquidation LTV. While the oracle band is on, the call prices each venue at the lending market's oracle price, where that's lower than the feed. A venue's liquidation LTV may sit under the pin plus the safety gap. If so, that liquidation LTV less the gap can replace the pin there.
* `skimPerformanceFee()` charges any performance fee owed. [Fees](/use-efficient/fees.md) explains how.
* `executePerformanceFee()` applies a scheduled rise in the pool operator's performance fee once the governance delay has passed.
* `proveDebtFree()` marks each loan asset the pool no longer owes as debt-free. A loan asset is the other token in the pool's pair, or any extra token the pool can borrow. In an Efficient pool that trades BTC against USDC, USDC is the loan asset. The call does this after a liquidation, or a repay made directly at a lending market, ends a debt.

`maintainCollateral()` is permissionless. So a process separate from the keeper, with its own key, can send it. That process keeps running if the keeper stops. `maintainCollateral()` reverts in a pool where no venue has borrowing on or carries debt. In such a pool, `setDials` accepts only a move that lowers the LTV pin.

## Changing hooks

**A hook change is a planned stop.** It waits out the governance delay and executes only while the pool is paused. The wait is at least 10 days while the pool's band ceiling allows no price band. The same holds while a raise to that ceiling is scheduled. [Hooks](/how-pools-work/hooks.md#changing-hooks) covers hook changes.

Any keeper or monitor that calls the old hook directly needs pointing at the new one. [Roles and governance](/run-a-pool/roles-and-governance.md#making-a-delayed-change) gives each step, from switching buys off to the first recentre.

## What to monitor

**The lens and the financing router report each venue's position and limits.** The lens's price-dependent reads return a flag instead of reverting. Position reads include interest accrued to date.

| Watch                        | Why it matters                                                                                                                                                                                                                    | Where to read it                                                                                                                                                |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Health at the feed price     | The top-up acts once a venue's LTV has used a fifth of the room from the pin to its liquidation LTV. The LTV is priced at the feed price. While the oracle band is on, the market's oracle price is used instead where it's lower | `venues(pool)` on the lens: each venue's collateral, debt, what it can lend now and its health                                                                  |
| Health at the market's price | The lending market liquidates at its own oracle's price                                                                                                                                                                           | `venueHealthy(pool, id)` on the router. It's false past the liquidation line, or when the market's oracle is unreadable                                         |
| The oracle band              | A venue whose oracle strays outside the band lends nothing                                                                                                                                                                        | The venue account's `oraclePrice(id)` against `price36` from the lens's `loans(pool)`. The band comes from `pin(pool)` on the router                            |
| The execution buffer         | A sell that needs more than the loan asset on hand reverts if the venues can't fund it. With borrowing off, it fills only up to the loan asset held and supplied                                                                  | `loans(pool)` on the lens: each loan asset's balance on hand, supply, debt and reserve target. For the pool asset, `physical` in `facts(pool)`                  |
| Interest                     | Debt grows at the market's borrow rate                                                                                                                                                                                            | The venue account's `borrowRateAfter(id, 0, 0)`: the per-second rate in WAD the position pays once pending interest accrues. `ok` is false when it's unreadable |
| The price feed               | In a pool with a price band, a failed or stale price stops swaps, pokes, recentres and the top-up                                                                                                                                 | `price(pool)` on the lens, and `feedOk(token)` on the feed, which skips the sequencer check                                                                     |
| The pause and switches       | A paused pool's anchor ages while buys still fill                                                                                                                                                                                 | `paused()` and `switches()` on the pool                                                                                                                         |

The health, oracle band and interest rows apply only to a pool that borrows.

Each venue's record gives its `account` and its market `id`. The record comes from the `venue` field in the lens's `venues(pool)`, or from the router's `venue(pool, id)`. The two venue account reads in the table take that bytes32 market `id`. `venue(pool, id)`, `venueHealthy` and `emergency` take the pool's uint16 venue number instead.

[Credit and collateral](/how-pools-work/credit-and-collateral.md) gives the health and band formulas. [Price feeds and oracles](/how-pools-work/price-feeds-and-oracles.md) covers each feed check.

## Emergencies

**In an emergency, the pool operator and the guardian first stop the flows that add risk.** Exits and top-ups stay open.

1. **Stop what adds risk.** The pool operator or the guardian pauses the pool with `setPaused(true)`. A pause stops sells and deposits, but never buys, exits or top-ups. Clearing a bit with `setFeatures` stops one flow, buys included. The guardian can only clear bits.
2. **Act on a venue directly.** In a pool with a lending market, the pool operator and the guardian share four emergency calls through `emergency(kind, id, assets)`. They repay debt, top up collateral, withdraw supply, or withdraw collateral from a venue without debt. No pause stops them. None can send assets anywhere but the pool or its own accounts at lending markets. [Credit and collateral](/how-pools-work/credit-and-collateral.md#emergency-calls) gives each call's conditions.
3. **Reopen and check.** Only the pool operator unpauses. The keeper then recentres an anchored hook. The pool's own `swapContext(poolAssetIn, amountIn)` reverts while a pause, a switch or an unreadable price would still refuse a swap.

Switching buys off can hold up exits that wait on a buy to repay a venue whose oracle has stopped. [Risks and safeguards](/use-efficient/risks-and-safeguards.md) explains this.

## Practice on Base

**In a pool that borrows, `maintainCollateral()` reverts during a sequencer outage and its grace.** So during that time, only `maintain` with `TopUp` or the emergency `TopUp` posts collateral. Neither reads the feed. The lending market keeps testing health at its own oracle's price. [Price feeds and oracles](/how-pools-work/price-feeds-and-oracles.md#the-sequencer-check) covers the sequencer check and the first Everlong vault's 1-hour grace. [When the feed can't price](/how-pools-work/price-feeds-and-oracles.md#when-the-feed-cant-price) lists every call the check stops.

**The gap between the LTV pin and a venue's liquidation LTV covers the time the pool can't top up.** It has to absorb:

* a price move through an outage and its grace
* interest between flows
* the distance the oracle band allows between the market's oracle and the feed

[Credit and collateral](/how-pools-work/credit-and-collateral.md) covers the rules on that gap and the first vault's values.

**Sales paid from the loan asset's execution buffer cost less gas than funded sales.** They withdraw, borrow and post nothing at a lending market. Both kinds of sale still accrue interest at each live venue first, as long as the first loan asset can be borrowed. [Just-in-time financing](/how-pools-work/just-in-time-financing.md#the-execution-buffer) covers the reserve target and supply batch. These decide how often sales pay from that buffer.

A proportional deposit or exit touches every venue carrying debt, so its gas grows with their number. Base caps a transaction at 2^24 gas, about 16.8 million. That's why a pool holds at most 32 venues.
