Quoters
All implement IQuoter. SwapPool calls them during swap / quote.
DecimalQuoter
Stateless, no proxy. Implementation is the instance: 0x336f493d5472FD59e9E05128804E2D05Be89c4B7.
1:1 value, scales decimals only. Use when every voucher in the pool is the same unit (e.g. all KES-pegged, mixed 6/18 decimals).
RelativeQuoter
Proxy: yes. Per-token rate in PPM. Unset rate = 1_000_000 (1.0).
out = adjustedValue * inRate / outRateadjustedValue applies the decimal delta before the rate, so cross-decimal quotes keep precision.
Owner: setPriceIndexValue(token, exchangeRate). Event: PriceIndexUpdated.
OracleQuoter
Proxy: yes. Chainlink AggregatorV3 feeds, all in one quote denomination (typically USD). Cross-rates any pair that shares that denominator.
initialize(owner, baseCurrency) // baseCurrency is metadata only
setOracle(token, feed)
setOracle(token, feed, maxStaleness) // 0 → global fallback
setMaxStaleness(seconds) // default 86400
setMultiplier(ppm) // 900_000–1_000_000 inclusiveMissing / stale / non-positive price reverts (OracleNotSet, StaleOraclePrice, InvalidOraclePrice). No fallback rate.
multiplier haircuts every quote. Above parity is rejected (same factor on both legs, so A→B→A would return multiplier²). Uninitialized storage (0) is treated as 1_000_000.
| Pool | Quoter |
|---|---|
| Same unit, mixed decimals | DecimalQuoter |
| Steward-set rates | RelativeQuoter |
| Live FX / stables | OracleQuoter |