galacticcouncil / galacticcouncil/hydration-node
Oracle clamping price difference with market
- Dominant language
- Rust
- Stars
- 208
- Forks
- 109
- Avg merge
- 6d 3h
- Merged PRs (30d)
- 3
Description
# EVM: Add **Clamped / Aggregate Oracle** (Primary feed clamped by Hydration Market EMA oracle)
## Context
We want a small Solidity “aggregate oracle” contract that outputs the **primary oracle price**, but **clamps** it within a configurable max deviation from **our Market EMA oracle** (available via the Chainlink adapter precompile).
## Problem
Current setup can allow:
- Primary oracle reports price far from Hydration market (EMA).
We need a bounded output price so that external feeds can’t exceed a safe band around our market.
## Proposed solution
Create a Solidity contract that:
- reads from **two Chainlink-style feeds** (`AggregatorV3Interface`)
- **Oracle1 (primary)**: DIA/Chainlink adapter feed
- **Oracle2 (secondary)**: Hydration **Market EMA** oracle feed (chainlink_adapter precompile address for the pair)
- clamps primary by a max deviation around secondary:
If `maxDiff = 10%` and:
- primary = 1.50
- secondary = 1.00
Bounds: `[0.90, 1.10]` → output = **1.10**
Math (bps):
- `lower = S * (10_000 - d) / 10_000`
- `upper = S * (10_000 + d) / 10_000`
- `out = clamp(P, lower, upper)`
Deployment model:
- **one clamped oracle per reserve** (different constructor args per reserve)
- both feeds can be constants passed in constructor (no admin setters required)
## Scope
- New Solidity contract: `ClampedOracle` (Chainlink `AggregatorV3Interface` compatible)
- Foundry tests (unit + fuzz)
- Docs: short README / comments explaining clamp and how to compute EMA feed address
## References
- Chainlink adapter precompile example:
https://github.com/galacticcouncil/hydration-node/blob/f389797e069277273a064591577b7aada4845a7e/runtime/hydradx/src/evm/precompiles/chainlink_adapter.rs#L44
- Aave hydration market uses EMA oracle here:
https://github.com/galacticcouncil/aave-v3-deploy/blob/745c8641161ff7f20726f8a3ee0c799342e457d7/markets/hydration/index.ts#L157
## Notes from discussion
- Both parent oracles can be constant; deploy per reserve with constructor args.
- Clamp % can also be set via constructor.
Contributor guide
Assessment
This issue has not been assessed yet.