Skip to content

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:

  1. Read the pool's reserves.
  2. Compute the exact UniswapV2 getAmountOut for selling qty, including the 0.3% pool fee.
  3. 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: getAmountOut returns 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:

LevelPrice vs spotCumulative tokensCumulative HYPE
198.5%7,6080.753 HYPE
297.0%15,3921.511 HYPE
395.5%23,3592.276 HYPE
494.0%31,5163.046 HYPE
592.5%39,8703.823 HYPE
691.0%48,4304.606 HYPE
789.5%57,2055.396 HYPE
888.0%66,2026.192 HYPE
986.5%75,4336.995 HYPE
1085.0%84,9077.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) is min(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 soundingPhase 1 · book sounding (after ArbOS upgrade)
ContractSoundingV0SoundingV1
ReadsElysium pools, exact getAmountOutElysium pools plus the HyperCore bid book
Trawl venueElysium pool swapHyperCore intent, with pool swap as fallback
Effect on LinesLimits from pool depthExisting 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