CryptopoolLPOracle
The source code of the CryptopoolLPOracle.vy contract can be found on GitHub. The contract is written with Vyper version 0.4.3.
Overview
The CryptopoolLPOracle is a price oracle contract that provides LP token pricing for Curve cryptopools. It combines the LP token price from a Curve cryptopool with a price aggregator to return the LP token value in aggregated USD terms. This oracle is used by the Yield Basis protocol to determine the value of LP tokens for various calculations including debt limits, collateral values, and trading operations.
Oracle Principle and Reliability
The oracle operates on a crvUSD price normalization principle that enhances reliability and reduces manipulation risks:
- Cryptopool components — the oracle reads
POOL.virtual_price()andPOOL.price_scale()directly. It does not callPOOL.lp_price(); the formula is computed locally to avoid depending on any per-pool helper. - Internal LP price:
lp_price_internal = 2 · virtual_price · sqrt(price_scale · 1e18) / 1e18. This is the Curve LP price formula for a 2-coin pool, expressed in pool units (numeraire =coins(0), i.e. crvUSD). - crvUSD aggregation: A price aggregator (
AGG) provides the "real" price of crvUSD across multiple major liquidity pools. - Final price:
price = lp_price_internal · AGG.price() / 1e18— LP value in aggregated USD.
This approach is reliable because:
- Curve pools are battle-tested and the LP-price formula derives from the AMM invariant rather than an external helper.
- crvUSD price aggregation uses multiple major liquidity pools to avoid price swings from any single source.
- Local computation keeps the oracle independent of any future
POOL.lp_price()behaviour change in the Twocrypto fork.
Staleness and update cadence
The oracle stores no price and has no update transaction to miss, so it cannot go stale in the push-feed (heartbeat) sense. Every call recomputes from live chain state:
virtual_price/price_scaleare read from the pool in the block of the call.price_scaleis slow-moving by design — it shifts only when Cryptoswap's internal rebalance condition triggers.AGG.price()is the crvUSD aggregator's EMA over multiple liquidity pools. That EMA is the intentional lag in the system: it makes the feed sandwich-resistant, and it means the oracle tracks sharp crvUSD price moves with a delay rather than instantly.price_w()(used by state-mutating protocol calls) ticks the aggregator's EMA viaAGG.price_w(), so routine protocol operations refresh the aggregator as a side effect. There is no keeper dependency.
There is no explicit staleness check and no fallback feed in this contract. If the aggregator's underlying pools stopped updating, price() would keep returning values computed from the last-observed aggregator state. The only hard validation on the aggregator is the Factory's band check at market init and on set_agg; routine operations do not re-validate the band (see Factory).
Function Documentation
Public Variables
Immutable Variables
POOL(Cryptopool) - Curve cryptopool contract address (immutable)AGG(PriceOracle) - Price aggregator contract address (immutable)
lp_price() (internal)
Description:
Internal helper that computes the LP token's value in pool-numeraire units (coins(0) = crvUSD) directly from virtual_price and price_scale. Never reverts; never reads POOL.lp_price().
@internal
@view
def lp_price() -> uint256:
virtual_price: uint256 = staticcall POOL.virtual_price()
p_scale: uint256 = staticcall POOL.price_scale()
return 2 * virtual_price * isqrt(p_scale * 10**18) // 10**18
price()
Description: Returns the current LP token price in aggregated USD terms. View function — multiplies the internal LP price by the crvUSD aggregator's USD value.
Returns:
uint256 - LP token price in aggregated USD (scaled by 10^18).
📄 View Source Code
@external
@view
def price() -> uint256:
return self.lp_price() * staticcall AGG.price() // 10**18
price_w()
Description: Returns the current LP token price in aggregated USD terms. Mutates the aggregator's EMA tick — used when fresh pricing is needed for state-mutating calls.
Returns:
uint256 - LP token price in aggregated USD (scaled by 10^18).
📄 View Source Code
@external
def price_w() -> uint256:
return self.lp_price() * extcall AGG.price_w() // 10**18
Related
- Core: AMM — price oracle consumer.
- User: Oracle Design — user-level explainer.