03 / 14 · Docs
Sounding, the depth oracle
Depth Value, the walk algorithm, the 15% stop, and the sound() interface.
Sounding is the depth oracle. Given a token and a quantity, it returns the HYPE you would actually receive selling that quantity now, stopping at 15% below the best bid.
Definition
sound(token, qty) → Depth Value in HYPE
Depth Value (DV) is the HYPE obtainable now for a quantity of a token, with 15% maximum slippage. It is not a price. It is the result of a simulated sale against the live market, so it already accounts for size: doubling the quantity less than doubles the Depth Value, and past the slippage stop it adds nothing at all.
Every limit in Bythos is built on Sounding. A Line can borrow up to 70% of the applied Depth Value of its matured collateral. See Lines.
The walk (Phase 0)
In Phase 0 · pool sounding, Sounding v0 reads the Market's registered Elysium pool. It does not use a TWAP for the walk. It computes the exact executable output of the sale:
- Read the pool's reserves.
- Compute the exact UniswapV2
getAmountOutfor sellingqty, including the 0.3% pool fee. - Stop where the marginal price falls 15% below the best bid (the spot price).
The result is what a real swap of that size would return in the same block, up to the stop.
The 15% slippage stop
On a constant-product pool with token reserve R, the marginal price after selling x tokens is:
marginal = spot × (R / (R + 0.997 × x))²
Setting that equal to 0.85 × spot gives the stop quantity:
x_stop = R × (1 / sqrt(0.85) − 1) / 0.997 ≈ 0.08491 × R
So the walk stops after selling about 8.49% of the pool's token reserve. Quantity beyond that point adds nothing to Depth Value. This is what makes large deposits get a lower effective LTV: the book, not a parameter, decides how much of a position is worth lending against.
Worked example
Take an example pool with 1,000,000 tokens and 100 HYPE. Spot is 0.0001 HYPE per token.
- Selling 20,000 tokens:
getAmountOutreturns 20,000 × 0.997 × 100 / (1,000,000 + 20,000 × 0.997) ≈ 1.955 HYPE. 20,000 tokens is short of the stop quantity, so DV = 1.955 HYPE. - The stop is reached at 1,000,000 × 0.08491 ≈ 84,907 tokens, which returns about 7.80 HYPE.
- Selling 500,000 tokens: the walk stops at 84,907 tokens, so DV = 7.80 HYPE, not 50 HYPE.
Detailed soundings
soundDetailed reports the walk as 10 levels, each 1.5% of price wide, from 0% to 15% below spot. Each level gives its price, the token quantity that level absorbs, and the cumulative HYPE. For the example pool:
| Level | Price vs spot | Cumulative tokens | Cumulative HYPE |
|---|---|---|---|
| 1 | 98.5% | 7,608 | 0.753 HYPE |
| 2 | 97.0% | 15,392 | 1.511 HYPE |
| 3 | 95.5% | 23,359 | 2.276 HYPE |
| 4 | 94.0% | 31,516 | 3.046 HYPE |
| 5 | 92.5% | 39,870 | 3.823 HYPE |
| 6 | 91.0% | 48,430 | 4.606 HYPE |
| 7 | 89.5% | 57,205 | 5.396 HYPE |
| 8 | 88.0% | 66,202 | 6.192 HYPE |
| 9 | 86.5% | 75,433 | 6.995 HYPE |
| 10 | 85.0% | 84,907 | 7.805 HYPE |
You can run this on any demo token at Sounding.
Records, the window and the TWAP
The instant value is never used for borrowing on its own. Sounding keeps a history:
record(token)snapshots the pool's reserves. Anyone can call it: keepers do, and the app calls it through your wallet when the last record is older than 60 s. At most one record per token every 30 s. Snapshots are kept in a ring buffer of 64 entries, about 32 minutes.minSounding(token, qty, 900)is the minimum of the live sounding and the sounding recomputed against every snapshot inside the 15-minute window, including the snapshot that was in force when the window opened.twap(token, 1800)is the time-weighted average of the recorded spot prices over 30 minutes. It returns 0 until the Market's oldest stored snapshot is at least 30 minutes old.applied(token, qty)ismin(minSounding over 15 min, qty × TWAP30 × 0.9). This is the value used for limits.
Why each rule exists is covered in Anti-manipulation.
Interface
interface ISounding {
struct Level { uint256 price; uint256 qty; uint256 cumulativeHype; }
function sound(address token, uint256 qty) external view returns (uint256 depthValue);
function soundDetailed(address token, uint256 qty) external view returns (Level[] memory levels, uint256 depthValue, uint256 walked);
function minSounding(address token, uint256 qty, uint256 window) external view returns (uint256);
function twap(address token, uint256 window) external view returns (uint256 priceE18);
function applied(address token, uint256 qty) external view returns (uint256);
function record(address token) external;
}
sound is a view function. Other contracts on Elysium can call it, for example a perps venue such as Shortcap.
Phase 0 vs Phase 1
| Phase 0 · pool sounding | Phase 1 · book sounding (after ArbOS upgrade) | |
|---|---|---|
| Contract | SoundingV0 | SoundingV1 |
| Reads | Elysium pools, exact getAmountOut | Elysium pools plus the HyperCore bid book |
| Trawl venue | Elysium pool swap | HyperCore intent, with pool swap as fallback |
| Effect on Lines | Limits from pool depth | Existing Lines see their limits rise |
In Phase 0, only tokens whose LP is locked in Horkos are accepted as Markets on mainnet. In Phase 1, Sounding v1 reads the entire HyperCore order book, every level, for free, in-block, through the EL1Read precompile planned in the ArbOS upgrade. On testnet, SoundingV1 is a stub that reverts with NotYetAvailable(). See Phases and roadmap.
Official announcements: @BythosDepth