On-chain hypotheses
Fifteen assumptions about Robinhood Chain that must be verified before deployment. Every one of them is blocking, because none can be corrected afterwards.
Fyber's design rests on assumptions about contracts it does not control: the Stock Token, the Chainlink feed, the sequencer, the Uniswap pools, the reference lending market. In a protocol with setters, a wrong assumption is a configuration change. Here it is not.
Each hypothesis below is therefore blocking. It must be resolved before the specification is frozen, because freezing the specification freezes the constants. The "Impact" column describes what changes in the specification before deployment, never what happens afterwards — after deployment, an unfavourable finding is handled by shutting a branch down and building a new version (Rule R-17).
H1 — The token cannot be frozen, blocklisted, or upgraded without delay
What is assumed. The issuer cannot freeze the protocol's token balance, cannot blocklist its address, and cannot upgrade the token contract instantly.
How it is checked. Decompile the bytecode and search for blacklist, freeze, pause, seize and ERC-1404 transfer-restriction selectors; read the EIP-1967 implementation and admin slots; identify the owner and whether a timelock sits in front of it.
Impact if unfavourable. If the balance can be frozen, the CDP is structurally uninsurable without a contractual arrangement with the issuer — and the alternative is abandoning the design. If the token is upgradable without delay, the automatic upgrade response is the only protection, the capacity tiers are halved at construction, and the immutability disclosure is strengthened.
This is the single most important question in the project.
H2 — balanceOf() returns the raw balance
What is assumed. ERC-8056 semantics: balanceOf returns raw units, and the multiplier is presentational.
How it is checked. Read balanceOf, uiMultiplier and totalSupply on a token whose multiplier is not one, and verify that balance × feed price equals the expected market value and not that value multiplied again.
Impact if unfavourable. If the balance is scaled, the whole vault accounting is wrong by a factor of the multiplier, and a 10-for-1 split would multiply the apparent collateral value by 100. The accounting rules, the on-chain market cap formula and the implied-share check would all be rewritten, a split would become an accounting event rather than a non-event, and a dedicated audit would be required.
This is the costliest possible bug in the design, and it is trivial to detect.
H3 — oraclePaused() lives where the design expects it
What is assumed. The selector exists on the token contract, or on the feed proxy, and survives an upgrade.
How it is checked. Presence of the selector on both addresses, its gas cost, and its behaviour after an implementation change.
Impact if unfavourable. The read address becomes an immutable pausedSource per branch. If the selector exists nowhere, the PAUSED state is not detectable at all, the implied-share check and the 24-hour pre-action flag become the only corporate-action protections, and the return ramp is triggered by the multiplier delta instead of by the pause.
The staticcall is fail-closed, which means a selector that is not where the design believes it is would freeze the protocol permanently rather than fail open.
H4 — A sequencer uptime feed exists on chain 4663
How it is checked. Locate a Chainlink uptime feed address and call latestRoundData.
Impact if unfavourable. The sequencer address is zero at construction, the check does not exist in the deployed code, the ETH/USD substitute and the heartbeat threshold absorb an outage instead, and the residual risk is disclosed rather than mitigated.
H5 — The staleness thresholds match real source behaviour
How it is checked. Log roundId, answer and updatedAt for ten sources over 28 days; take the 99.5th percentile of the publication interval and double it; pay specific attention to the quietest hours of the week.
Impact if unfavourable. The thresholds are replaced by the measurements at construction. A source that goes quiet for longer than its threshold simply stops counting toward the composite.
A wrong threshold after deployment degrades — it produces DEGRADED, with a haircut — rather than breaking.
H6 — Depth is sufficient, and the valve decision
What is assumed. d2 for the selected tokens is at least 500 000 USD at the 25th percentile over 30 days.
How it is checked. Snapshot every Uniswap v2, v3 and v4 pool for the twenty largest Stock Tokens; compute d2 hourly for 30 days; take the 25th percentile. Separately, price the cost of pushing a time-weighted price by a full band.
Impact if unfavourable. The capacity tiers are halved at construction; a branch with no pool deep enough to qualify simply carries a larger haircut and can never be liquidated in DEGRADED; and the dormant branches open only when their own measurements allow it.
H7 — The liquidation and sale mechanisms are not a regulated multilateral system, and fyUSD has no identifiable issuer
How it is checked. A memorandum from a financial-markets law firm — eight to twelve weeks, 40 000 to 80 000 EUR — covering MiFIR article 1(5b), MiFID II annex I B(2), the MiCA issuer and offeror definitions, and the exposure reasoning in Samuels v. Lido DAO.
Impact if unfavourable. If a trading-venue authorisation is required, direct liquidation, CollateralSale and open redemptions may have to be restructured before deployment, plausibly reducing liquidation to the Stability Pool alone; the mainnet launch is blocked until the answer arrives. If fyUSD is classified as an e-money token, the options are an issuing entity with authorisation, or abandoning the European Union. If the Closer alone constitutes an issuer, the answer is a planned early renunciation or no key at all from day zero.
H8 — A backing attestation is published and readable
What is assumed. The verification agent publishes an attestation of backing, readable and dated within 72 hours.
Impact if unfavourable. No on-chain rule can depend on it in any case, because there are no setters. The issuer-default disclosure stands alone and the capacity tiers stay conservative.
H9 — The pause exit covers a real corporate action
How it is checked. Observe a dividend and a split end to end on mainnet before deployment: the exact duration of the pause, the order of operations — multiplier before or after the first post-pause price — the size of that first price, and how effectiveAt relates to the real ex-date.
Impact if unfavourable. The ramp length is adjusted at construction. If the feed is systematically updated before the multiplier, the design additionally requires uiMultiplier == newUIMultiplier before the first round is read at all.
H10 — Historical rounds are reachable
What is assumed. getRoundData(roundId − k) works to a depth of at least ten rounds, which the pre-pause snapshot uses.
Impact if unfavourable. The snapshot falls back to the last round seen by poke(), which the specification already tolerates, and the residual risk is documented. Chainlink proxies lose history across an aggregator rotation.
H11 — Gas after the subsidy ends leaves the keeper mechanisms viable
What is assumed. After the 90-day subsidy expires, flag, poke at 150 000 to 300 000 gas, accrue and buy remain economic.
Impact if unfavourable. The keeper share is raised at construction; the liquidity oracle is limited to two pools; the flag window is widened. The 100 fyUSD minimum debt stays frozen and becomes an accepted defect of version 1.
H12 — A suitable Morpho market exists for the rate floor
What is assumed. A Morpho Blue market on chain 4663 with USDG as the loan token, at least 10 M USD supplied, and an interest-rate model exposing borrowRateView.
How it is checked. Read IMorpho.market(id) and idToMarketParams, call IIrm.borrowRateView, and pull 30 days of rate history.
Impact if unfavourable. RateFloor is deployed with a null reference: the module stays, its formula degenerates, and the fixed floors of 1.5% and 3.0% apply. The cost is roughly 0.3 to 0.5 points of yield, noted rather than mitigated.
H13 — Uniswap v3 and v4 pools are readable within the gas budget
What is assumed. slot0, tickBitmap and liquidity are readable on v3, StateView is deployed and stable on v4, and the whole depth computation fits the gas budget.
How it is checked. Calls against real pools in a fork, with gas measurement.
Impact if unfavourable. Fall back to v2 pools only, or to a single pool. If no reliable reading is possible at all, d2_eff is zero, the branch cannot open any position, and this is blocking for SPY and QQQ.
H14 — The token is an EIP-1967 proxy whose implementation slot is readable
How it is checked. extcodehash, a read of the slot, and the observed behaviour of any past upgrade.
Impact if unfavourable. If the token is not a proxy and not upgradable at all, the upgrade-detection mechanism has no purpose and the Probe contracts are kept anyway. If it is upgradable through a different scheme, detection moves to comparing the token's extcodehash at each checkUpgrade().
H15 — No group of sources can dominate the composite
How it is checked. Measured over 28 days: how often each of the three source groups is readable, and whether any two of them are correlated closely enough that they should not count as independent.
Impact if unfavourable. The independence test is tightened before deployment. After deployment, a group that turns out to be less independent than measured simply pushes the branch into DEGRADED more often.
Why this page exists
A conventional protocol treats these as integration details to be worked out during implementation, because a wrong answer is a configuration change. Fyber cannot do that. Every one of these fifteen answers is written into a constructor, and a constructor runs once.
The verification work is therefore not a preliminary to the build. It is a gate in front of it, and several of the answers can cancel the project rather than adjust it.
Last reviewed: 2026-09-07 · Spec v0.4