Corporate actions
break collateral
One oracle address that stops splits, pauses and stale feeds from liquidating healthy positions.
See live dataTokenized equities carry a second set of books
Balances stay raw. Prices already carry the corporate-action multiplier. Mixing the two conventions is silent and expensive.
Tokenized assets on Robinhood Chain
194
Covered by an on-chain price feed
35
With no on-chain price at all
159
How old the prices are, right now
Every covered feed, sorted by how long it has been silent, against the 24-hour heartbeat it is allowed. A feed near the dashed line is still "fresh" by its own contract and hours behind the market.
Two right answers and two wrong ones
The naive integration is accidentally correct. The careful one, which reads the multiplier and applies it, is the one that breaks.
Price read from
Chainlink feed
Price read from
REST /prices
Balance read as
balanceOf()
Correct
x1
The multiplier is applied exactly once, inside the price.
Wrong
/ m
Multiplier applied zero times. Collateral is undervalued and healthy positions are liquidated.
Balance read as
balanceOfUI()
Wrong
x m
Multiplier applied twice. On a 4:1 split this overvalues collateral fourfold.
Correct
x1
Both sides use the unadjusted convention.
The correct answers sit on the diagonal: each applies the multiplier exactly once. Every mixed pair applies it twice or not at all, and neither reverts.
A fuse between the price and the protocol
The adapter is an AggregatorV3-compatible contract. It classifies the moment before it answers, and holds the last trustworthy price when the moment is unsafe.
Four answers, and every state is one of them
Passes it through
The price is fresh and nothing is staged. The adapter answers with the feed’s own number and adds nothing to it.
Serves the last price
The feed is silent but every flag is clean and the continuity invariant holds. The last published price still stands: silence is not the same as breakage.
Holds the pre-window price
Something makes the current number untrustworthy. The adapter answers with the price that stood before the window opened — the same number for everyone, so no position enters the window healthier than it was.
Refuses to answer
The protection budget is spent. The adapter reverts rather than serve a number it can no longer stand behind. Breaking loudly beats lying quietly.
Where the market sits right now
The same rules, run against every covered feed this second. A zero is a finding, not an empty slot: it says no feed is in that state at the moment you are reading.
Normal
34
Quiet
1
Corporate action
0
Token halted
0
Past heartbeat
0
Desync and Unsafe carry no count: one needs the adapter’s own committed snapshot and the other is a property of a deployed contract, so neither can be read from feed data. Showing them as zero would claim knowledge we do not have.
35 covered feeds, read from Robinhood Chain mainnet (chain 4663) at block 59480609.
Why a held price cannot be abused
The held price is the one that stood before the window opened, and it is the same for everyone. A position cannot enter the window healthier than it was. Anyone already underwater stays underwater and stays liquidatable. The window removes the artefact, not the debt.
One address
No code changes, no second audit. Point the oracle at the adapter and the protection is live.
- oracle: 0x4A1166a659A55625345e9515b32adECea5547C38 // Chainlink RHTSLA/USD
+ oracle: 0x0000000000000000000000000000000000000000 // Depth adapter — RHTSLA/USDThe adapter address is issued by the factory the moment you deploy one, and it is deterministic in the token and the feed. The zero above stands in until the factory is on chain.
What this does not do
Publishing the boundary is part of the product. A protocol that cannot see the edges cannot price the risk.
01
It does not stop new borrowing against a held price
An oracle cannot see who is calling it. Freezing the price protects a position from a false liquidation, but it does not stop the same borrower taking on more debt at that frozen number.
What covers it
Three lines on your side: gate new borrows on status() == NORMAL. Liquidation protection itself needs no code change at all.
02
It does not price the assets with no feed
Most tokenized assets on this chain have no on-chain price whatsoever. The adapter guards the feeds that exist; it does not invent the ones that do not.
Assets with an on-chain price
35 / 194
What covers it
Nothing, and deliberately so. Inventing a price for an unpriced asset is the failure this product exists to prevent.
03
It does not detect a sequencer outage today
No sequencer uptime feed has been published on this chain, so there is nothing for the check to read.
What covers it
The state is built and dormant. The constructor takes an uptime feed address, and a zero disables it — the day Chainlink publishes one, a new deployment switches it on with no change to the logic.
04
It cannot tell a closed market from a broken oracle
Solidity has no calendar, and hard-coding an exchange holiday table into an immutable contract guarantees it will one day be wrong.
What covers it
Both cases resolve to the same conservative behaviour, which makes the ambiguity safe: silence is never served as a fresh price, whatever caused it.