The largest open draw that survives a margin the CALLER chooses: a price fall and a holding
horizon (MK-240). Both are required, and neither has a default, because how much to borrow depends
on how long a position will be held and how much of a fall its owner is prepared to absorb, and the
library knows neither. The ceiling is returned beside it.
draw is solved against a stressed price, price * (1 - priceFallBps / 10000) / (1 + accrual over horizonSeconds), with the accrual at the live global rate a new Trove would carry, through the same
solver and the same open evaluator as getBorrowingPower. A Trove opened at it is not
liquidatable while the price stays above that fall and the elapsed time stays inside that horizon.
Choosing the inputs: how often a fall was reached, on Mezo mainnet. The share of start times after
which fetchPrice() fell at least the given amount at some sample within the horizon, from the
committed instrument, over Mezo mainnet blocks 9841930 to 11868955 (86 days, one sample every 225
blocks, about 14 minutes):
Horizon
fell 2% or more
5% or more
10% or more
20% or more
worst fall seen
1 hour
0.1%
0.0%
0.0%
0.0%
4.18%
1 day
17.4%
1.0%
0.0%
0.0%
5.70%
3 days
43.9%
3.8%
0.01%
0.0%
10.24%
7 days
57.6%
6.7%
0.2%
0.0%
10.80%
30 days
68.2%
10.4%
1.1%
0.0%
11.64%
Reproduce with MEZO_MAINNET_RPC_URL=<endpoint> pnpm tsx scripts/oracle-moves.ts --end 11869000 --consecutive 0 --days 90 --step 225 --horizons 3600,86400,259200,604800,2592000 --falls 200,500,1000,2000. The start counts are 9005, 8910, 8709, 8313 and 5917: a start counts only when
its whole horizon lies inside the sampled range, so the 30 day row sees fewer, later starts.
What that table is not. It is one stretch of history in one market regime, not a distribution of
regimes. Start times overlap, so neighbouring windows share most of their samples and the shares are
not independent trials. It samples one block in 225, so a dip that recovered between two samples is
not in it: every share is a lower bound, and the true worst falls are larger. A position is also
exposed to more than price: debt redistributed from other Troves' liquidations
(TroveManager.sol:980-1047) raises its debt without its owner acting. Read it as how often a margin
of that size would have been crossed recently, never as a guarantee about the next horizon.
The largest open draw that survives a margin the CALLER chooses: a price fall and a holding horizon (MK-240). Both are required, and neither has a default, because how much to borrow depends on how long a position will be held and how much of a fall its owner is prepared to absorb, and the library knows neither. The ceiling is returned beside it.
drawis solved against a stressed price,price * (1 - priceFallBps / 10000) / (1 + accrual over horizonSeconds), with the accrual at the live global rate a new Trove would carry, through the same solver and the same open evaluator as getBorrowingPower. A Trove opened at it is not liquidatable while the price stays above that fall and the elapsed time stays inside that horizon.Choosing the inputs: how often a fall was reached, on Mezo mainnet. The share of start times after which
fetchPrice()fell at least the given amount at some sample within the horizon, from the committed instrument, over Mezo mainnet blocks 9841930 to 11868955 (86 days, one sample every 225 blocks, about 14 minutes):Reproduce with
MEZO_MAINNET_RPC_URL=<endpoint> pnpm tsx scripts/oracle-moves.ts --end 11869000 --consecutive 0 --days 90 --step 225 --horizons 3600,86400,259200,604800,2592000 --falls 200,500,1000,2000. The start counts are 9005, 8910, 8709, 8313 and 5917: a start counts only when its whole horizon lies inside the sampled range, so the 30 day row sees fewer, later starts.What that table is not. It is one stretch of history in one market regime, not a distribution of regimes. Start times overlap, so neighbouring windows share most of their samples and the shares are not independent trials. It samples one block in 225, so a dip that recovered between two samples is not in it: every share is a lower bound, and the true worst falls are larger. A position is also exposed to more than price: debt redistributed from other Troves' liquidations (
TroveManager.sol:980-1047) raises its debt without its owner acting. Read it as how often a margin of that size would have been crossed recently, never as a guarantee about the next horizon.