fix(template): align apyWindow options with api-served smoothing windows - #4
Open
alexbensimon wants to merge 2 commits into
Open
Conversation
alexbensimon
marked this pull request as ready for review
August 7, 2026 12:54
Collaborator
Author
|
@codex review |
spennyp
approved these changes
Aug 7, 2026
The template shipped `apyWindow: "7d"`, but `VaultV2History.avgApy/avgNetApy` cap each plotted point's smoothing at 24h. A default deployment holding V2 vaults therefore rendered a headline APY labelled 7d next to a chart the app honestly relabels 1d. Adapt the configurable options to what the API actually serves: - Add "6h" to `ApyWindow` and `APY_WINDOW_HOURS`. The fork already carries `"6h" | "1d" | "7d" | "30d"` and runs on `6h`; the narrower union here was an oversight in the port — the vault history adapters already key their series by "6h" and market data already carries `supplyApy6h`/`borrowApy6h`. - Default `apyWindow` to `1d`: the only window that plots at full fidelity on every surface (V2 history caps at 24h above it; market history has no sub-daily series below it). - Document the V2 24h cap next to `apyWindow` in `config/types.ts`, so an integrator choosing 7d/30d learns about it before shipping. `7d` and `30d` stay configurable — they are genuinely served for headline numbers and for V1 vault charts. The user-facing range selector is untouched. Allowing `6h` exposes the mirror-image gap on the borrow chart: market history serves daily/weekly/monthly borrow APY series only. `marketHistoryApyWindow` handles it with the same honesty rule already used for V2 vaults — the label tracks the headline, the description discloses the series window when it differs. VAU-1315 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ages Adversarial review of the `apyWindow` change found that widening the union to include `6h` activated a previously-unreachable branch: the V1 history path mapped the `"6h"` key onto `VaultHistory.netApy`, which the schema shows is the instantaneous series — `VaultHistory`'s averaged family starts at `dailyNetApy`, there is no six-hour series. A `6h` deployment would therefore have plotted an instantaneous V1 series titled `Net APY (6h)` beside a genuinely-6h headline, with no disclosure. That is exactly the mislabelling this branch exists to remove, on the one value it adds. Fixed the same way as market history: `vaultV1HistoryApyWindow` floors the configured window at `1d`, the V1 path files the corresponding daily/weekly/monthly series under the configured window, and `VaultHistoricalApyChart` derives its series window per protocol so the disclosure fires for V1 as well as V2. The `netApy` selection is dropped from the V1 history fragment — no consumer remains, and its presence is what invited the mismapping. Also corrects several comments and doc-strings that asserted things the code does not do, including the deployer-facing `apyWindow` block, which had the labelling rule backwards: the tab label names the configured window (the one the headline beside it genuinely uses) and the description discloses the window actually plotted. VAU-1315 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
alexbensimon
force-pushed
the
feature/vau-1315-fixtemplate-align-apywindow-options-with-api-served
branch
from
August 7, 2026 16:04
8a9317c to
57a090e
Compare
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes VAU-1315 — https://linear.app/morpho-labs/issue/VAU-1315
Problem
The template ships
apyWindow: "7d", butVaultV2History.avgApy/avgNetApy(lookbackHours:)cap each plotted point's smoothing at 24h. A default deployment holding V2 vaults renders a headline APY labelled 7d next to a chart the app honestly relabels 1d.Nothing was broken or dishonest —
vaultV2HistoryLookbackHoursclamps the request andvaultV2HistoryApyWindowrelabels the series rather than claiming a smoothing the points don't have. The problem is that the public reference implementation walks into that mismatch out of the box, and didn't expose the option Anchorage uses to avoid it.The fix adapts the configurable options to what the API actually serves, rather than working around the gap in app code.
Changes
Add
"6h"toApyWindow(config/types.ts) andAPY_WINDOW_HOURS/APY_LOOKBACK_PERIOD(common/utils/timeframe.ts). The API servesSIX_HOURSon bothVaultV1LookbackPeriodandVaultV2LookbackPeriod, the fork already carries"6h" | "1d" | "7d" | "30d"and runs on6h, and this repo's data layer was already written for it —MarketSupplyApyWindows/MarketBorrowApyWindowsalready carrysupplyApy6h/borrowApy6h, backed byMarketState.avg*fields the schema documents as genuine 6h averages. Only the config union was narrower: an oversight in the port, not a decision.Default
apyWindow→"1d"(config/index.ts).The ticket left
6hvs1dopen.1dis the only window that plots at full fidelity on every surface, because the API's per-point smoothing is coarser than its current-state averages in both directions:6h1d7d30d6hmatches production Anchorage, but Anchorage is a vaults-only deployment. The template ships every surface, so6hwould trade the V2 vault mismatch for two new ones.1dhas none, and is the more conventional public default.Document the gaps at the config site (
config/types.ts), so an integrator learns which windows plot natively where before shipping rather than after.Handle the windows the API doesn't serve per surface.
marketHistoryApyWindowandvaultV1HistoryApyWindowfloor the configured window at1dfor the two surfaces with no sub-daily averaged series, mirroring the pre-existingvaultV2HistoryApyWindowat the other end. Established rule throughout: the tab label names the configured window (the one the headline beside it genuinely uses), and the tab description discloses the window actually plotted, whenever they differ. On the default1dnothing diverges anywhere.Explicitly not done
7d/30dare genuinely served for headline numbers and for V1 vault and market charts. Removing them would strip real capability from V1-only deployments to work around a V2-only limitation.DATA_RANGES/CHART_RANGESalready align with the API. The cap is on per-point smoothing only.Review
Ran a 4-round adversarial review loop (three independent reviewers per round, fresh each round).
Round 1 caught a real defect in my first cut: widening the union activated a previously-dead branch that mapped the
"6h"key ontoVaultHistory.netApy. Per the schema that is the instantaneous series —VaultHistory's averaged family starts atdailyNetApy, there is no six-hour series. A6hdeployment would have plotted an instantaneous V1 series titledNet APY (6h), undisclosed, beside a genuinely-6h headline: precisely the mislabelling this PR exists to remove, on the one value it adds. Fixed in 8a9317c viavaultV1HistoryApyWindow, per-protocol series-window selection in the chart, and dropping the now-unusednetApyselection from the V1 fragment (which is what invited the mismapping).Rounds 2–4 found no further functional defects. Their remaining findings were all comments and doc-strings asserting things the code does not do — including my own new
apyWindowdoc block, which had the labelling rule backwards — and are fixed in the same commit. Final round scored 4/5, 5/5, 4/5 with no blockers.One reviewer note left deliberately unfixed, flagged here for a human call:
DataChart.tsx:71falls back to the last plotted point whentotalApyis falsy, andassembleApycoerces a null APY to0. So a genuinely-0% headline renders the series' last value under a label naming a different window. The mechanism is pre-existing and untouched by this PR; on a6hdeployment the fallback can now disagree with the label where before it couldn't. Low impact (needs a zero/absent headline) and out of scope here — happy to open a follow-up.Validation
pnpm codegen,pnpm check:typesandpnpm checkall pass clean.pnpm testlocally: the 6 env-independent test files pass (83 tests); the other 11 fail inviem's HTTP transport because they fork mainnet / read the Chainalysis oracle and this machine has no RPC URLs configured (smoke.test.tsassertsMAINNET_RPC_URL_1is defined and fails first). The same set fails identically before and after this change — none of them touchapyWindow. The change has not been verified against a green suite; that has to come from CI.CI note
This branch is cut from
main, which predates #2 (ci/pin-action-shas). The org enforcessha_pinning_requiredand the current workflow uses tag refs, so novitestcheck can run on this PR and it will show BLOCKED against the now-requiredviteststatus. Expected — unblocks once #2 merges and this rebases onto it. No workflow files touched here.🤖 Generated with Claude Code