refactor(interface): rename to AggregatorV2V3Interface + add getRoundData#222
refactor(interface): rename to AggregatorV2V3Interface + add getRoundData#222hardyjosh wants to merge 1 commit into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
4bf3a79 to
c8842ed
Compare
7c1d3ea to
b0f9ab3
Compare
c8842ed to
34429b9
Compare
34429b9 to
7e45f29
Compare
b0f9ab3 to
34be518
Compare
7e45f29 to
35029d5
Compare
34be518 to
cfbe962
Compare
35029d5 to
5599f88
Compare
cfbe962 to
4f54fad
Compare
5599f88 to
653f532
Compare
653f532 to
336605a
Compare
b928009 to
a9a35d3
Compare
336605a to
6d85151
Compare
…Data The local oracle interface was named `AggregatorV3Interface` but its surface is actually V2+V3: it includes the deprecated V2 `latestAnswer()` (needed for Aave V3 and Compound V3 compatibility) and omitted V3's `getRoundData(uint80)`. Two integrator-facing footguns followed: 1. Anyone importing the canonical Chainlink `AggregatorV3Interface` and casting a `PassthroughProtocolAdapter` instance to it would compile against a five-method surface including `getRoundData` and runtime-revert when that selector was called. 2. The interface name suggested "V3" semantics while the contents matched Chainlink's own `AggregatorV2V3Interface`. New code reaching for the "real" V3 surface would silently lose `latestAnswer` without warning. Renames the type to `AggregatorV2V3Interface` (matching Chainlink's own hybrid type), moves the file to `src/interface/IAggregatorV2V3.sol`, and adds full NatSpec including an explicit deprecation note on `latestAnswer`. Adds the missing canonical `getRoundData(uint80)` method. Implementations: - `BasePythOracleAdapter.getRoundData` reverts with `HistoricalRoundDataUnsupported(uint80)`. Pyth does not expose per-round history through this interface; callers needing point-in-time data should use Pyth's `getPriceAtPublishTime` or an indexer directly. The error selector is explicit so integrators can detect it on the wire. - `PassthroughProtocolAdapter.getRoundData` forwards to the underlying oracle unchanged — a future Chainlink-backed oracle returns real historical data; a Pyth-backed oracle bubbles up the revert. Tests: - `testPassthroughGetRoundData` — happy path through Passthrough with a mocked underlying oracle returning real round data. - `testPassthroughGetRoundDataRevertSelectorPropagates` — confirms the Pyth-backed revert selector + payload reach the integrator unchanged. - `testGetRoundDataAlwaysReverts` — fuzzes the round ID into the `BasePythOracleAdapter` revert path. Hardens `ProdFork.t.sol` at the same time: - Replaces silent `return;` in fork-availability modifiers with `vm.skip(true)` so missing fork env or unset prod addresses surface as SKIPPED in CI output instead of false-green vacuously-passing tests (audit #213). - Removes the duplicate `LibProdOracles.ORACLE_REGISTRY` constant and imports the canonical `LibProdDeploy.ORACLE_REGISTRY` so a future prod-address rotation only requires one edit (audit #208). Does not touch the in-adapter `latestAnswer()` consumption (Morpho still calls `latestAnswer` without a staleness check — that's a separate Pass 5 finding tracked at MEDIUM and out of this PR's scope). Found by /audit Pass 1 (Security), Pass 3 (Documentation), Pass 4 (Code Quality), and Pass 5 (Correctness / Intent Verification) — A14p5-1 "Interface name asserts V3, contents are V2+V3 hybrid". Closes #208, #213. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
a9a35d3 to
48b9306
Compare
6d85151 to
2134c50
Compare

The local oracle interface was named
AggregatorV3Interfacebut its surfaceis actually V2+V3: it includes the deprecated V2
latestAnswer()(needed forAave V3 and Compound V3 compatibility) and omitted V3's
getRoundData(uint80).Two integrator-facing footguns followed:
AggregatorV3Interfaceandcasting a
PassthroughProtocolAdapterinstance to it would compile againsta five-method surface including
getRoundDataand runtime-revert whenthat selector was called.
Chainlink's own
AggregatorV2V3Interface. New code reaching for the"real" V3 surface would silently lose
latestAnswerwithout warning.Renames the type to
AggregatorV2V3Interface(matching Chainlink's ownhybrid type), moves the file to
src/interface/IAggregatorV2V3.sol, andadds full NatSpec including an explicit deprecation note on
latestAnswer.Adds the missing canonical
getRoundData(uint80)method.Implementations:
BasePythOracleAdapter.getRoundDatareverts withHistoricalRoundDataUnsupported(uint80). Pyth does not expose per-roundhistory through this interface; callers needing point-in-time data should
use Pyth's
getPriceAtPublishTimeor an indexer directly. The errorselector is explicit so integrators can detect it on the wire.
PassthroughProtocolAdapter.getRoundDataforwards to the underlyingoracle unchanged — a future Chainlink-backed oracle returns real
historical data; a Pyth-backed oracle bubbles up the revert.
Tests:
testPassthroughGetRoundData— happy path through Passthrough with amocked underlying oracle returning real round data.
testPassthroughGetRoundDataRevertSelectorPropagates— confirms thePyth-backed revert selector + payload reach the integrator unchanged.
testGetRoundDataAlwaysReverts— fuzzes the round ID into theBasePythOracleAdapterrevert path.Does not touch the in-adapter
latestAnswer()consumption (Morpho stillcalls
latestAnswerwithout a staleness check — that's a separate Pass 5finding tracked at MEDIUM and out of this PR's scope).
Found by /audit Pass 1 (Security), Pass 3 (Documentation), Pass 4 (Code
Quality), and Pass 5 (Correctness / Intent Verification) — A14p5-1
"Interface name asserts V3, contents are V2+V3 hybrid".
Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com