Oracle on Cosmos Hub
Should the Cosmos Hub have its own price oracle? CosmWasm is now permissionless on the Hub, but there is no price oracle available to contracts. Pyth dropped CosmWasm, SEDA is EVM-only, and Band over IBC is slow and costs fees on every query. Without prices, we can’t build any advanced defi on the Hub. So these apps get built on chains like Injective or dYdX, and ATOM ends up used everywhere except on its own chain. Idea: integrate an enshrined oracle based on the Slinky fork. Validators would publish prices at every block, secured by the Hub’s own validator set, with no dependency on an external provider. And beyond the Hub: these prices could be distributed over IBC to any connected chain that lacks an oracle. The Hub would become an interchain’s price provider, with fees flowing back to ATOM stakers. Longer term: prices are only the first step. The same validator-voted mechanism could later carry other data the interchain needs, such as LST exchange rates, proof of reserves or other verified off-chain data. The Hub would become the interchain’s trusted data layer. The Community Pool could fund the development and audit. Would you support this direction?…
Excerpt (1188 of 1247 characters). Read the whole post on the forum ↗
I don’t support this because sometimes blocks are empty and continuously pushing prices to empty blocks is only extra cost nothing more, and their is not value setting oracle on validator, oracle is only required in contract layer
this is what I feel anyone can counter this
Good direction from a contract-safety point of view. Without prices, every lending or perps idea for CosmWasm on the Hub moves elsewhere. A few things we’d want settled before contracts rely on it, because they decide how those apps fail: • Freshness. A validator-voted price only moves when enough stake reports it. The query should return the last-updated height and time next to the price, and contracts should enforce a maximum age. If it only returns a number, most contracts will read a stale price without knowing. • Participation. What share of voting power has to report a pair before its price updates, and what happens when a sidecar outage drops it below that? For lending, holding the last price and marking it stale is safer than updating from a handful of validators. • Listing. The median protects against a few dishonest validators, not against a thin market. If a pair’s source exchanges can be moved cheaply, every validator honestly reports the moved price. Minimum liquidity and a minimum number of independent sources per pair matter more here than the size of the validator set. • IBC consumers. Chains reading these prices over IBC add relay delay on top, and they…
Excerpt (1194 of 1614 characters). Read the whole post on the forum ↗
Thanks both for the replies, this is exactly the kind of discussion I was hoping for.
To be clear: I’m not planning anything specific at this stage. I’m only opening the conversation on the principle, to gather opinions, discuss whether this is useful, and, if people want it, figure out the most efficient technical approach to get there. Slinky was a starting idea, not a fixed choice. I also possibly know people who would be ready to build it if the community supports the direction.
@Ignismeow That’s a fair point, and it’s the core trade-off: an enshrined oracle at the validator level versus a contract-level oracle (pull model with signed prices). Both have costs and different trust assumptions, and I’d like the community to weigh them openly.
@Zealynx Thanks, these are exactly the questions a spec would need to answer. On aggregation: nothing is decided, and how prices are weighted is part of what I’d like to discuss here.
So the question I’d like to put to the community is: how can we build an efficient oracle system, first for the Hub, and if possible for other chains over IBC?Which model do you think fits best, and what would it need to be safe?
This discussion misses why we need Slinky in the first place.
ON COST:Hub already producesblocks every 6s,empty or not. Slinky just adds ~200bytes of price data to blocks that already exists. Cost is negligible to securing $1B+ in IBC.
ON CONTRACT vs VALIDATOR LAYER:Contract - level oracles work for a DEX, not for a Hub that wants safe lending /Perps. If every Cosmwasm has its own Oracle, you get fragmented, manipulable price feeds and unsafe liquidations. Validator - level price (where 180 Validators agree) is the only way to protect stakers - especially those of us with ATOM staked long - term.
Without this, we keep bleeding value to Osmosis while Hub stakers pay the price via inflation. That’s not sustainable
I fully agree with your points.
+1 for bringing Slinky (now Connect) to the Hub. Price feeds are the missing building block for most DeFi on the Hub: lending markets, CDP-style stablecoins, liquidations, perps all depend on them. With Connect, prices are pushed by the validators through vote extensions and written into every block. That means no external relayer, no extra trust assumption, and the security of the Hub’s own validator set. The main cost is that every validator has to run the sidecar. In my opinion that cost is justified as soon as there are apps on the Hub that consume those prices, and permissionless CosmWasm makes that much more likely now. I also looked at SEDA, which is already connected to the Hub through IBC Eureka. It’s interesting, but for a different use case. SEDA is a programmable oracle: anyone can publish an oracle program that fetches arbitrary data (sports results, off-chain events, custom APIs) and returns a verified result. It’s a good fit for on-demand or custom data, not for continuous price feeds. It would be great to see SEDA support CosmWasm, and it wouldn’t take much, because the hard part already exists: a SEDA IBC light client is live on the Hub and kept up to date by…
Excerpt (1197 of 2227 characters). Read the whole post on the forum ↗
Skip already has Slinky so why doesn’t CL just deploy it on the Hub?
Lazy ? Not invested 100% in the hub ? working on 3rd pillar that make revenues ( for ICF not Atom ) … They are playing for themselves . not the atom holders
Does their Hub unit also only work for the ICF, not ATOM holders?
Fair question. From the contract side the safety needs are the same in both models, they just land in different places.
Push (validator-voted, Slinky style): prices are there every block and the Hub’s stake secures them, but liveness depends on enough validators running the sidecar, and every listed pair costs every validator. It fits a short list of liquid pairs best.
Pull (signed prices the user submits in the tx): adding long-tail pairs is cheap, but each contract has to verify the signer set, the freshness, and that the price isn’t older than the last one it used. That check logic ends up copied into every app, which is where mistakes tend to happen.
A common middle ground is push for the few core collateral pairs (ATOM, stables, the main LSTs) and pull for the rest, with one shared CosmWasm library for the checks so each app doesn’t write its own. Either way, the query should return height and timestamp with the price so contracts can enforce a max age.
Hi everyone I just opened a small PR on gaia: !feat: allow CosmWasm contracts to query IBC light clients by Victor118 · Pull Request #4196 · cosmos/gaia · GitHub (follows issue #4023 ). What it does It adds the IBC light client `VerifyMembership` query (and consensus state) to the gRPC allowlist available to CosmWasm. That’s it: a tiny change, no new module, no new logic. Why it matters With it, a smart contract on the Hub can check that a piece of data, submitted by anyone, really exists on another chain that has an IBC light client on the Hub. The submitter doesn’t need to be trusted: the contract verifies the ICS-23 proof itself, against the Hub’s own light client. I built a working POC of this proof verification on Neutron. The only trust assumption left was the consensus state supplied by an off-chain watcher, and this PR removes exactly that. What it unlocks • Cross-chain events: emit an event in a contract on chain A, prove it on the Hub, and react to it. • Bringing external data to the Hub: dYdX (Connect) prices, or SEDA / Band results, all provable the same way. • On top of that, we can imagine a Liquity-style stablecoin backed by ATOM, where…
Excerpt (1190 of 2315 characters). Read the whole post on the forum ↗
Nice, this is what your Neutron POC was missing, the app hash stops coming from the submitter.
Something the contracts on top will have to handle themselves: the submitter still picks the proof height, and VerifyMembership accepts any height the client still has a consensus state for. Once interchain-events reads the consensus state at the submitted height, nothing ties that height to the subscription, so a GreaterThan or LessThan watch can fire on a value from before the watch was even created. For the Liquity-style idea it’s worse, a liquidator would prove the lowest price in the window. Reading the timestamp from ConsensusState at the proof height and requiring it to be recent, and newer than the last one the contract used, closes it.
Also worth writing down for whoever builds the SEDA gateway: creating an IBC client is permissionless, so a contract that accepts the client ID from the caller can be handed a valid proof from a client the caller set up for a chain they control. Pinning the client ID at instantiate avoids that.
Thanks a lot, both points are spot on. On the proof height: agreed, this has to be handled in the contracts on top. For interchain-events, the plan is to store a starting point in each subscription when it’s created: the client’s latest height at that moment (or a later height/timestamp chosen by the subscriber, if they want to start listening from a point in the future). A proof is then only accepted if its height is above that starting point and above the last height already processed for that subscription. That way a watch can never fire on a value from before it existed, and values can’t be replayed or go backwards. For the Liquity-style idea, same logic on the oracle side: read the timestamp from the ConsensusState at the proof height, reject it if it’s older than a small window compared to the Hub’s block time, and require it to be newer than the last price the contract used. It could even require the proof to be at the client’s latest height, since the liquidator updates the client in the same transaction anyway. On the client ID: completely right, I hadn’t written it down explicitly. The client ID will be pinned at instantiate, and the contract will also build the…
Excerpt (1196 of 2871 characters). Read the whole post on the forum ↗
Makes sense, and for events an app controls it’s a much better thing to prove than another module’s internal keys.
I’d store each event under info.sender plus a sequence per sender. Then the Hub contract checks which contract emitted it, instead of trusting an “inj1… lent 10,000 USDC on Neptune” line in the body, which anyone could write by calling the emitter themselves. The per sender sequence also lets a consumer following one app require last + 1, so a watcher can’t push the loans and leave out the liquidation that came after. Proofs are permissionless, so one honest watcher is enough to keep it moving.
I’d also instantiate the emitter without an admin. A migrated emitter could rewrite past events under the same keys and every proof would still verify.
Thanks a lot, these are great points, and they really sharpen the design.
Keying events by info.sender + a per-sender sequence is clearly the right approach: the Hub checks who emitted the event, not what the event says. And it has a nice side effect: subscriptions on the Hub become simply (client ID, sender), e.g. “events from Neptune on Injective”. The Hub contract can then reject any event that matches no subscription, so its state only stores what someone actually asked for. On the other side, since the key starts with the sender, watchers can read just that sender’s key range on the source chain instead of scanning everything, and only push what has subscribers.
last + 1 per sender is also exactly what’s needed to make sure nobody can skip a liquidation. A new subscription will just record its starting sequence when it’s created, so it doesn’t need the full history, and it can never fire on events from before it existed.
And agreed on the emitter: no admin, fully immutable, otherwise the proofs don’t mean anything.
If you think the change in the gaia PR itself is sound, a short comment there would really help it get reviewed ![]()
Read the PR and your notes in #4023. I think it’s sound, and against v10.7.0 the handlers do what you wrote. VerifyMembership refuses localhost and solo machine clients, charges the cached context’s gas back to the caller and checks Active. ConsensusState only reads the store and returns the Hub’s own height with no proof, and ClientStatus is the same GetClientStatus call. Gaia already lets 08-wasm call ConsensusState too. I’ll leave a short note on the PR.
On the starting sequence, where it comes from matters. If the Hub takes it from the first event a watcher proves after the subscription exists, the watcher picks the start and can begin right after the liquidation. I’d have the subscriber set it explicitly, or require the first proof to include the emitter’s counter for that sender at a height after creation, and only enforce last + 1 from there.
Thanks everyone for the feedback. Zealynx’s security notes and Victor’s Gaia PR have already moved this forward. This post may become a signaling proposal asking Cosmos Labs to take on the engineering and long-term maintenance of a native price oracle for the Hub. Before that, here is a full picture: who needs it, what it costs, how to fund it, how it compares to the competition, and the questions validators and Cosmos Labs would need to answer. What this post answers from the thread so far @Zealynx • Freshness: every query returns the price, height, timestamp and pair status, so contracts can enforce a maximum age (section 11). • Participation: below the 2/3 threshold, the price is not updated and grows stale. It is never updated from a handful of validators (section 2). • Listing: listing requires minimum liquidity and at least 3 independent sources, because the median doesn’t protect against a thin market (section 9). • IBC consumers: the spec should state that they add relay delay and inherit the Hub validator set as a trust assumption, and recommend tighter maximum ages for them (section 4). • Aggregation: we would keep Slinky’s stake-weighted median at launch,…
Excerpt (1197 of 23028 characters). Read the whole post on the forum ↗
Thanks for pulling it all together, and for carrying the earlier points over.
In Connect, any address in the x/marketmap MarketAuthorities param can call UpdateMarkets, and that overwrites a live market’s providers and MinProviderCount in the same block. The 2/3 median then publishes whatever the new sources say, so for ATOM, BTC and the LSTs that lending will lean on, whoever holds that role is the real trust boundary, more than the validator set. If Cosmos Labs runs the market map with fast feed additions, the spec could say who holds that key and keep changes to core pairs behind governance or a delay lending markets can see coming, with the fast lane only for new listings.
On delisting, a last price frozen with a delisted status is your second case in section 10 for any contract that doesn’t read the status, and those are the contracts the procedure is meant to protect. If the query returns an error once a pair is delisted, they stop instead of lending against it, and the ones that do read the status already had 90 days of sunsetting to switch.
Guinch_Roze: • Does a native oracle fit your vision for the Hub, given that your rails already plan for cross-chain pricing? • Would Cosmos Labs be willing to take on the engineering and long-term maintenance: code, market map, new feeds and on-call support, as Skip did for Neutron? • Would it be compatible with your Hub safety criterion and performance roadmap? Could you measure the validator load from section 6 on testnet? • Could Cosmos Labs or the ICF fund the validator reward pool for the first 12 to 24 months, until fees take over? • What timeline would you consider realistic, audit included? Hey! I will answer from the perspective of the roadmap work we are doing and how this aligns or has overlap points, as you mention a few! Thank you for the great breakdown. Does a native oracle fit the roadmap we are developing? Yes, but a bit narrower. In your post, you mostly talk about a general-purpose DeFi chain and generic price feeds. The roadmap work has explicitly moved away from that since the shift out of the EVM-based vision. There are also data options available today, and dApps have also utilized mixed models with off-chain sources for a while now.…
Excerpt (1196 of 4189 characters). Read the whole post on the forum ↗