Oracle staleness check present
Sushi (SushiSwap) — v2 + v3 + Trident + BentoBox/Kashi + SushiXSwap's assessment for RD-F-059 — scored red on the v1.7.0 rubric. The evidence below is the curator's reasoning for this score.
Evidence summary #
Kashi has no independent staleness check on the oracle's updatedAt timestamp. KashiPair calls updateExchangeRate() which calls the IOracle (ChainlinkOracleV1) and returns a cached rate, but borrow() uses the last stored exchangeRate without first checking whether it is fresh. The Nov-2022 exploit root cause was exactly this: borrow() used the outdated cached exchangeRate while liquidate() called updateExchangeRate() first, creating an exploitable discrepancy. Chainlink heartbeats (1h for major assets, 24h for stables) are Chainlink-side safeguards that do not substitute for a protocol-level updatedAt staleness check in KashiPair.
Sources #
- URLBlockSec: Beyond the market risk — KashiPairMediumRiskV1 logic bugBlockSec Nov 2022 analysis — root cause confirmed as staleness handling failure: borrow uses cached rate, liquidate updates firstretrieved 2026-05-17
- KashiPairMediumRiskV1 EtherscanKashiPairMediumRiskV1 ABI — updateExchangeRate() exists but borrow() does not force-call it (confirmed by exploit mechanics)retrieved 2026-05-17
Methodology #
Determine whether the protocol rejects oracle reads older than a declared maximum age (i.e., checks `updatedAt > block.timestamp - maxStaleness`).
See the full factor methodology and distribution across all protocols →