05 / 14 · docs
Settlement formula
the lower price is the true one.
The exact formula, the oracle averaging window, the TWAP window, why the lower of the two, and worked examples.
simulation Simulation only. The protocol is not live. No transaction is ever sent.
This page is the precise version. If you only need the idea, read Selling first.
The formula#
settlement price = min( oracle average , realized TWAP )
settled value = quantity × settlement price
fee = settled value × nights × fee per night
balance = max( 0 , settled value − fee − advance )
seller receives = advance (at night) + balance (at the open)
With the current parameters:
| Term | Value |
|---|---|
| Advance rate | 90% (earnings night: 75%) |
| Fee per night | 0.25% |
| Fee base | settled-value todo |
| Oracle averaging window | 5 to 15 minutes; used: 10 minutes todo |
| TWAP window | 30 minutes |
| Staleness limit | 120 seconds todo |
The two prices#
Oracle average#
After the opening bell, EVE waits for the first fresh Chainlink price: a round written after the bell, not the frozen value left from the previous close. From that first fresh round, it averages every round written during the window, which lasts between 5 to 15 minutes.
Why average, and not take the first print:
- The first minutes after the open are the noisiest of the day. The opening auction, wide spreads and a rush of orders produce prints that do not last.
- A single price is easier to move than an average.
- An average over several minutes is closer to a price at which size can really be traded.
Why a window of at most 15 minutes: sellers should be paid quickly, and the longer the window, the more the "opening price" drifts into being just "the morning price".
Realized TWAP#
In parallel, the pool sells the stocks it bought during the night. It sells in equal slices across the first 30 minutes of the session. The realized TWAP is simply what it got:
realized TWAP = total USDC received ÷ total shares sold
It is a realized price, not a quoted one. It includes slippage and trading costs, because those are real.
Why the lower of the two#
the lower price is the true one.
The pool pays out against a price. If that price is higher than what the pool can actually sell at, depositors lose the difference. Taking the lower of the two removes that possibility:
- If the pool realizes less than the oracle says (thin liquidity, slippage, a fast-moving open), the seller is paid the realized price. The pool paid out exactly what it received, minus the fee. Depositors are whole.
- If the pool realizes more than the oracle says, the seller is paid the oracle price and the difference stays in the protocol as a surplus, which goes to: reserve todo.
Be clear about what this means for a seller: the rule is asymmetric, and it is asymmetric in the pool's favour. That is deliberate. It is the reason depositors can fund the night without taking a view on the stock, and the reason the fee can be a fraction of a percent. The difference between the two prices is normally small, since both are measured over the same minutes of the same market.
The fee#
The fee is 0.25% of the settled value per calendar night between the close and the open. It is deducted from the balance, never from the advance. See Fees for the schedule and the split.
When the haircut is not enough#
Normally the settled value is comfortably above the advance, because of the haircut. If the stock gaps down by more than the haircut, it is not. Then:
balance = 0 (the seller keeps the advance)
fee collected = whatever is left above the advance, up to the fee due
shortfall = advance − realized proceeds (if positive)
reserve pays = min( shortfall , reserve balance )
depositors pay = shortfall − reserve pays (only if the reserve is empty)
The order of protection is always the same: haircut, then reserve, then depositors.
How far the stock can fall before the haircut is used up depends on the advance rate and the fee:
largest absorbed drop = 1 − advance rate ÷ (1 − fee rate)
| Stretch | Advance | Largest drop absorbed |
|---|---|---|
| Weeknight, 1 night | 90% | 9.77% |
| Weekend, 3 nights | 90% | 9.32% |
| Holiday weekend, 4 nights | 90% | 9.09% |
| Earnings night, 1 night | 75% | 24.81% |
Order of operations at the open#
- The opening bell rings. Nothing settles on the frozen overnight price.
- The first fresh Chainlink round after the bell arrives. The oracle window starts.
- The pool starts selling the night's stocks in equal slices over 30 minutes.
- The oracle window ends. The oracle average is known.
- The TWAP window ends. The realized TWAP is known.
- For each sale: settlement price, settled value, fee, balance.
- Balances are paid to sellers. Fees are split. Any shortfall is drawn from the reserve.
- Queued depositor withdrawals are served from the USDC that came back.
Who triggers these steps: not decided todo.
Worked examples#
All four use illustrative prices. Every line is computed by the settlement code.
A normal night#
| Step | How | Amount |
|---|---|---|
| Reference value at the close | 10 × $180.00 | $1,800.00 |
| Advance paid at night (90%) | $1,800.00 × 90% | $1,620.00 |
| Oracle average after the open | fresh Chainlink price, averaged | $181.20 |
| Realized TWAP | what the pool got selling | $181.05 |
| Settlement price | the lower of the two (TWAP), +0.58% vs the close | $181.05 |
| Settled value | 10 × $181.05 | $1,810.50 |
| Fee (1 night) | $1,810.50 × 0.25% | −$4.53 |
| Advance already paid | −$1,620.00 | |
| Balance paid at the open | settled value − fee − advance | $185.97 |
| Total received by the seller | advance + balance | $1,805.97 |
A weekend#
| Step | How | Amount |
|---|---|---|
| Reference value at the close | 10 × $240.00 | $2,400.00 |
| Advance paid at night (90%) | $2,400.00 × 90% | $2,160.00 |
| Oracle average after the open | fresh Chainlink price, averaged | $238.10 |
| Realized TWAP | what the pool got selling | $238.40 |
| Settlement price | the lower of the two (oracle), -0.79% vs the close | $238.10 |
| Settled value | 10 × $238.10 | $2,381.00 |
| Fee (3 nights) | $2,381.00 × 0.75% | −$17.86 |
| Advance already paid | −$2,160.00 | |
| Balance paid at the open | settled value − fee − advance | $203.14 |
| Total received by the seller | advance + balance | $2,363.14 |
| Pool surplus | realized $2,384.00 − settled value | $3.00 |
Here the oracle average is the lower price. The pool realized slightly more than it paid out, and that surplus goes to: reserve todo.
A holiday weekend#
| Step | How | Amount |
|---|---|---|
| Reference value at the close | 10 × $200.00 | $2,000.00 |
| Advance paid at night (90%) | $2,000.00 × 90% | $1,800.00 |
| Oracle average after the open | fresh Chainlink price, averaged | $201.50 |
| Realized TWAP | what the pool got selling | $201.30 |
| Settlement price | the lower of the two (TWAP), +0.65% vs the close | $201.30 |
| Settled value | 10 × $201.30 | $2,013.00 |
| Fee (4 nights) | $2,013.00 × 1.00% | −$20.13 |
| Advance already paid | −$1,800.00 | |
| Balance paid at the open | settled value − fee − advance | $192.87 |
| Total received by the seller | advance + balance | $1,992.87 |
Four calendar nights, so four nightly fees.
A big gap#
| Step | How | Amount |
|---|---|---|
| Reference value at the close | 5 × $700.00 | $3,500.00 |
| Advance paid at night (90%) | $3,500.00 × 90% | $3,150.00 |
| Oracle average after the open | fresh Chainlink price, averaged | $595.00 |
| Realized TWAP | what the pool got selling | $593.60 |
| Settlement price | the lower of the two (TWAP), -15.20% vs the close | $593.60 |
| Settled value | 5 × $593.60 | $2,968.00 |
| Fee (1 night) | $2,968.00 × 0.25%, of which $0.00 can be collected | −$0.00 |
| Advance already paid | −$3,150.00 | |
| Balance paid at the open | never below zero | $0.00 |
| Total received by the seller | advance + balance | $3,150.00 |
| Pool shortfall | advance − realized proceeds ($2,968.00) | $182.00 |
| Covered by the reserve | reserve before: $25,000.00 | $182.00 |
The seller keeps the advance. The pool sold the shares for less than it advanced, and the reserve makes up the difference.
An earnings night#
| Step | How | Amount |
|---|---|---|
| Reference value at the close | 20 × $180.00 | $3,600.00 |
| Advance paid at night (75%) | $3,600.00 × 75% | $2,700.00 |
| Oracle average after the open | fresh Chainlink price, averaged | $156.60 |
| Realized TWAP | what the pool got selling | $156.20 |
| Settlement price | the lower of the two (TWAP), -13.22% vs the close | $156.20 |
| Settled value | 20 × $156.20 | $3,124.00 |
| Fee (1 night) | $3,124.00 × 0.25% | −$7.81 |
| Advance already paid | −$2,700.00 | |
| Balance paid at the open | settled value − fee − advance | $416.19 |
| Total received by the seller | advance + balance | $3,116.19 |
The same kind of drop as the big gap, but the reduced advance left a cushion wide enough to absorb it. No reserve needed.
Edge cases#
No fresh price. If no Chainlink round is written after the bell (a halted stock, an unscheduled market closure, an oracle outage), there is no oracle average and therefore no settlement. The sale stays open until a fresh price exists. See Oracles.
The pool cannot sell everything in the window. The volume cap exists to prevent this. What happens to unsold inventory after 30 minutes is not decided.
Rounding. USDC has six decimals. Amounts are rounded to that precision; rounding remainders go to the reserve.
Several sales of the same ticker. Every sale of a ticker on the same night settles at the same settlement price.
In code#
The formula lives in one pure function. This is the one the simulator and the worked examples above call:
import { settle } from "@/lib/protocol";
const result = settle({
qty: 10,
advance: 1620, // paid at night: 10 × 180.00 × 90%
feeBps: 25, // one night
oraclePrice: 181.2, // fresh Chainlink price, averaged
twapPrice: 181.05, // what the pool realized
reserveBefore: 25_000,
});
result.settlementPrice; // 181.05 (the lower of the two)
result.settledValue; // 1810.50
result.feeCollected; // 4.52625
result.balance; // 185.97375
result.sellerTotal; // 1805.97375
Source: src/lib/protocol/settlement.ts. Tests: src/lib/protocol/__tests__/settlement.test.ts, including a property test of 5,000 random settlements that checks the invariants: the lower price always binds, the seller never pays back, cash is conserved, and depositors lose only once the reserve is empty.