Context
Kong currently emits apr-oracle timeseries rows from the v3 APR oracle path. The shared reader in packages/ingest/abis/yearn/3/vault/timeseries/apr-oracle/hook.ts calls getStrategyApr(address, 0) first and only falls back to getCurrentApr(address) when the strategy APR call reverts. That means the stored apr-oracle apr/apy components represent a single resolved oracle APR value, not both oracle perspectives.
For analysis/debugging, we want to index getCurrentApr(address) as its own timeseries value so we can compare current vault APR against the strategy APR / resolved APR that Kong already stores.
Goal
Add additional apr-oracle output components for the oracle's getCurrentApr(address) value at each indexed block, without changing the existing apr / apy semantics.
Proposed implementation
- Update
packages/ingest/abis/yearn/3/vault/timeseries/apr-oracle/hook.ts to read both values independently:
- keep existing resolved APR behavior for
apr, apy, netApr, and netApy
- add a dedicated read for
getCurrentApr(address) even when getStrategyApr(address, 0) succeeds
- tolerate
getCurrentApr failures by omitting only the new current APR components, not the whole apr-oracle output
- Emit new components under the existing
apr-oracle label, likely:
currentApr
currentApy
- for v3 vaults, also consider
currentNetApr and currentNetApy using the same fee extraction path as the existing resolved APR
- Keep plain ERC-4626 behavior explicit in
packages/ingest/abis/erc4626/timeseries/apr-oracle/hook.ts:
- either emit only
currentApr / currentApy if the oracle supports it for those addresses
- or document/test why ERC-4626 remains
apr / apy only
- Update latest-performance consumers only where useful:
packages/ingest/helpers/apy-apr.ts currently reads only apr / apy from apr-oracle
packages/ingest/abis/yearn/3/vault/snapshot/hook.ts currently maps only apr / apy into performance.oracle
- decide whether the new current APR fields should be surfaced in snapshots/API responses or remain timeseries-only for comparison queries
- Update the REST timeseries surface:
packages/web/app/api/rest/timeseries/db.ts already fetches/groups all components for a label, so no SQL/schema change should be required for new apr-oracle components
packages/web/app/api/rest/timeseries/refresh.ts and refresh-historical.ts should automatically cache the new components after the new rows exist, but both refresh jobs need to run after deploy/backfill so Redis contains currentApr history
packages/web/app/api/rest/timeseries/[segment]/[chainId]/[address]/route.ts already supports repeated components query params, so consumers should be able to request ?components=apr&components=currentApr
- keep the default
apr-oracle component as apr in packages/web/app/api/rest/timeseries/labels.ts unless we intentionally want the default response to become multi-component
- update
docs/rest.md with apr-oracle examples showing currentApr / currentApy and comparison requests
- Add or update tests for:
- strategy APR succeeds and current APR is also indexed
- strategy APR reverts and existing fallback behavior remains unchanged
- current APR failure does not drop the resolved oracle APR output
- component names and APY/net calculations
- REST
apr-oracle requests can return currentApr when passed through components
Acceptance criteria
- Historical/new timeseries extraction for v3 vault
apr-oracle rows includes separate current APR components when getCurrentApr returns a value.
- Existing
apr-oracle apr and apy components remain backward compatible.
- Querying GraphQL
timeseries(label: "apr-oracle", component: "currentApr") works without a database migration.
- Querying REST
/api/rest/timeseries/apr-oracle/:chainId/:address?components=currentApr returns the new component after cache refresh.
- Querying REST with repeated components, for example
?components=apr&components=currentApr, returns both series for comparison.
- REST docs describe the new component names and comparison request shape.
- Tests cover success, fallback, and failure behavior for the new current APR read.
- Any decision about surfacing the new values in snapshots/API responses is documented in the PR.
Notes
The output table key already includes component, so adding components under the existing label should not require a schema migration. This is mostly an ingest/hook, cache refresh, docs, and consumer-contract decision.
Context
Kong currently emits
apr-oracletimeseries rows from the v3 APR oracle path. The shared reader inpackages/ingest/abis/yearn/3/vault/timeseries/apr-oracle/hook.tscallsgetStrategyApr(address, 0)first and only falls back togetCurrentApr(address)when the strategy APR call reverts. That means the storedapr-oracleapr/apycomponents represent a single resolved oracle APR value, not both oracle perspectives.For analysis/debugging, we want to index
getCurrentApr(address)as its own timeseries value so we can compare current vault APR against the strategy APR / resolved APR that Kong already stores.Goal
Add additional
apr-oracleoutput components for the oracle'sgetCurrentApr(address)value at each indexed block, without changing the existingapr/apysemantics.Proposed implementation
packages/ingest/abis/yearn/3/vault/timeseries/apr-oracle/hook.tsto read both values independently:apr,apy,netApr, andnetApygetCurrentApr(address)even whengetStrategyApr(address, 0)succeedsgetCurrentAprfailures by omitting only the new current APR components, not the wholeapr-oracleoutputapr-oraclelabel, likely:currentAprcurrentApycurrentNetAprandcurrentNetApyusing the same fee extraction path as the existing resolved APRpackages/ingest/abis/erc4626/timeseries/apr-oracle/hook.ts:currentApr/currentApyif the oracle supports it for those addressesapr/apyonlypackages/ingest/helpers/apy-apr.tscurrently reads onlyapr/apyfromapr-oraclepackages/ingest/abis/yearn/3/vault/snapshot/hook.tscurrently maps onlyapr/apyintoperformance.oraclepackages/web/app/api/rest/timeseries/db.tsalready fetches/groups all components for a label, so no SQL/schema change should be required for newapr-oraclecomponentspackages/web/app/api/rest/timeseries/refresh.tsandrefresh-historical.tsshould automatically cache the new components after the new rows exist, but both refresh jobs need to run after deploy/backfill so Redis containscurrentAprhistorypackages/web/app/api/rest/timeseries/[segment]/[chainId]/[address]/route.tsalready supports repeatedcomponentsquery params, so consumers should be able to request?components=apr&components=currentAprapr-oraclecomponent asaprinpackages/web/app/api/rest/timeseries/labels.tsunless we intentionally want the default response to become multi-componentdocs/rest.mdwithapr-oracleexamples showingcurrentApr/currentApyand comparison requestsapr-oraclerequests can returncurrentAprwhen passed throughcomponentsAcceptance criteria
apr-oraclerows includes separate current APR components whengetCurrentAprreturns a value.apr-oracleaprandapycomponents remain backward compatible.timeseries(label: "apr-oracle", component: "currentApr")works without a database migration./api/rest/timeseries/apr-oracle/:chainId/:address?components=currentAprreturns the new component after cache refresh.?components=apr&components=currentApr, returns both series for comparison.Notes
The
outputtable key already includescomponent, so adding components under the existing label should not require a schema migration. This is mostly an ingest/hook, cache refresh, docs, and consumer-contract decision.