Description
Add support for the current Ethereum yTranche deployment. Kong will discover tranches through the controller, retain controller state, enrich tranche snapshots with current Hook state, generate controller-backed tranche PPS and performance history, and expose the data through REST only.
Scope
Deployment:
| Component |
Address |
| Main vault |
0xDa87123895a043Ed3610155550177C54ce8ba49B |
| Controller |
0xF0145433E5289dd10712650dCd28333FA317eF36 |
| Hook |
0x776DEd3273440f1481d07B6CE916b5d5Fac170dC |
A controller is bound to one asset class: ASSET and VAULT are constructor arguments with no setters, so a USD, BTC and ETH system each require their own controller. Only the USD deployment above is indexed, and nothing may assume a chain has exactly one controller.
Out of scope:
- GraphQL changes
- Shareholder balances or cooldown state
- Indexing additional deployments or chains — though everything keyed by controller must admit more than one per chain
- Hook things or standalone Hook snapshots
- Hook-change tracking
- New event hooks
- New REST performance shapes
- Governance and transaction execution
Internal naming
Use functional names without the y prefix:
trancheController
tranche
Use “yTranche” in documentation and user-facing descriptions.
Tasks
1. Index the deployment
Add controller and tranche ABIs as sibling paths:
packages/ingest/abis/yearn/3/tranche/controller/
packages/ingest/abis/yearn/3/tranche/vault/
packages/ingest/abis/yearn/3/tranche/hook/
They must be siblings rather than sharing a yearn/3/tranche hook path: kong's hook resolver applies a parent path's hooks to every child path, which would cross-wire the controller and the tranches.
Include the Hook read interface required by the tranche snapshot hook. Configure the Ethereum controller as a static source in config/abis.yaml.
Events contained in the configured ABIs must be indexed through Kong’s existing automatic event extraction. Do not add event hooks.
2. Discover tranches
Add a controller snapshot hook that:
- Reads
VAULT, ASSET, reserveVault, tranchesLength, and tranchesByPriority.
- Discovers every registered tranche in priority order.
- Creates or updates the required
tranche, vault, and strategy things.
- Creates or updates a
trancheController thing carrying asset, mainVault, inceptBlock and inceptTime, whether or not any tranches are registered. Deployments are enumerated from this label rather than from the tranches pointing at it.
- Adds these defaults to each tranche:
trancheController
priority
trancheType
asset
mainVault
inceptBlock
inceptTime
erc4626
v3
yearn
trancheType identifies whether the contract uses the base or locked tranche implementation. A/B/E names are not used as protocol types.
The indexing configuration must ensure each tranche address has one snapshot owner and is not independently processed by conflicting generic ABI paths.
3. Enrich the controller snapshot with tranche state
Kong’s automatic controller snapshot stores the controller’s zero-argument state.
The controller snapshot hook must use tranchesLength and tranchesByPriority(index) to append an ordered tranches array. For each tranche, read tranches(tranche), liveAssets(tranche), and trancheCoverage(tranche).
Each tranche entry must contain:
address
priority
registered
accrualPaused
excessShareBps
targetRatePerSecondWad
baselineAssets
lastAccrual
pendingExcess
liveAssets
claim
covered
Use the automatic snapshot’s block for every appended read.
4. Enrich tranche snapshots with Hook state
Kong’s automatic tranche snapshot stores the current Solidity hook() return value as the raw hook address.
The tranche snapshot hook must use that address to append a separate hookState object containing:
open
rateLimitWindow
depositLimit
depositRateLimit.used
depositRateLimit.windowStart
depositRateLimit.rateLimit
withdrawRateLimit.used
withdrawRateLimit.windowStart
withdrawRateLimit.rateLimit
depositCap
withdrawCap
Requirements:
- Read parameterized Hook properties using the tranche address as the target.
depositLimit is the Hook's depositLimits(tranche) value.
- Preserve
hook as the raw Hook address.
- Store derived Hook properties under
hookState; do not return a second top-level hook field from the snapshot hook.
- Use the same block as the tranche snapshot.
- Store fixed-window counters as reported.
- The REST response may additionally expose effective usage after applying the snapshot timestamp and
rateLimitWindow.
- Do not create a Hook thing.
- Do not store a standalone Hook snapshot.
- Do not index account-specific
allowed or cooldown mappings.
5. Add accounting time series
Generate one daily tranche-accounting series per tranche:
baselineAssets
pendingExcess
liveAssets
claim
covered
coverageRatio
targetRatePerSecondWad
excessShareBps
accrualPaused
Generate one daily tranche-system series at the controller address:
totalClaims
vaultAssets
reserveAssets
backingAssets
coverageRatio
Values must be read at a single historical block for each observation. coverageRatio is null when there is no claim to cover — no claim is not evidence of full coverage.
6. Support controller-backed assets, PPS, and TVL-C
Refactor the existing vault calculations to obtain the authoritative asset balance through a shared function that accepts a vault thing and block number.
For ordinary vaults, read:
When the vault thing has a trancheController default, read:
trancheController.liveAssets(vault)
Use the authoritative asset balance in the existing tvl-c calculation.
For ordinary vault PPS, continue reading:
For tranche PPS, calculate:
authoritativeAssets × 10^vaultDecimals / vault.totalSupply()
When totalSupply is zero, return 10^vaultDecimals.
Use the resulting PPS reader for every current, weekly, monthly, and inception observation required by:
trancheController.liveAssets(vault) already excludes pendingExcess; do not add pending excess to PPS or TVL.
Keep the existing output labels, components, pricing, historical sampling, annualization, compounding, storage, and REST shapes unchanged. Existing non-tranche vault calculations must remain unchanged.
7. Add REST resources
Add a collection and a member endpoint:
GET /api/rest/tranche/:chainId/controllers
GET /api/rest/tranche/:chainId/:controller
The collection returns every system on the chain, one document per controller. The member returns one, addressed by controller. controllers is a static route segment, so it resolves ahead of the member route.
Each document returns:
controller
asset
mainVault
reserveVault
system accounting
ordered tranches
blockNumber
blockTime
Each tranche entry must include its thing metadata, current hook address, hookState, controller accounting, current PPS, coverage, and effective deposit and withdrawal capacity.
Expose the new historical labels through Kong’s existing timeseries REST mechanism:
tranche-accounting
tranche-system
pps
apy-historical
Do not add GraphQL fields or resolvers.
8. Prevent double counting
Tranche TVL represents claims on the main vault’s backing, not additional protocol assets.
- Emit tranche
tvl-c outputs using trancheController.liveAssets(tranche).
- Do not emit the legacy
tvl label for tranche vaults.
- Do not create or calculate an aggregate that sums main-vault TVL and tranche TVL as independent backing.
- Do not include
pendingExcess in live tranche NAV or TVL.
- Keep accounting coverage separate from immediately deliverable withdrawal capacity.
9. Tests and documentation
Add focused tests using Kong’s existing unit and fixed-block RPC test patterns:
- Verify authoritative asset source selection: ordinary vaults use
totalAssets() and vault things with trancheController use liveAssets(vault).
- Verify controller-backed assets against the deployed controller at a fixed block.
- Verify tranche PPS against
authoritativeAssets × scale / totalSupply at a fixed block.
- Verify zero-supply PPS returns the share scale when the calculation is implemented as a pure helper.
- Verify ordinary vault PPS continues using
pricePerShare().
- Verify APY obtains its current, weekly, monthly, and inception PPS observations through the shared PPS reader.
- Verify
tvl-c consumes the authoritative asset balance while preserving its existing output shape.
- Verify tranche vaults do not emit the legacy
tvl label.
- Verify controller discovery returns the deployed tranche addresses in priority order at a fixed block.
- Verify tranche snapshot enrichment preserves the raw
hook address and appends representative limit data under hookState.
Do not add new testing infrastructure or broad container-level tests for this work.
Document the REST endpoint, timeseries labels, accounting semantics, snapshot naming distinction, and current deployment.
Reference: yTranche contracts
Acceptance criteria
Description
Add support for the current Ethereum yTranche deployment. Kong will discover tranches through the controller, retain controller state, enrich tranche snapshots with current Hook state, generate controller-backed tranche PPS and performance history, and expose the data through REST only.
Scope
Deployment:
0xDa87123895a043Ed3610155550177C54ce8ba49B0xF0145433E5289dd10712650dCd28333FA317eF360x776DEd3273440f1481d07B6CE916b5d5Fac170dCA controller is bound to one asset class:
ASSETandVAULTare constructor arguments with no setters, so a USD, BTC and ETH system each require their own controller. Only the USD deployment above is indexed, and nothing may assume a chain has exactly one controller.Out of scope:
Internal naming
Use functional names without the
yprefix:trancheControllertrancheUse “yTranche” in documentation and user-facing descriptions.
Tasks
1. Index the deployment
Add controller and tranche ABIs as sibling paths:
They must be siblings rather than sharing a
yearn/3/tranchehook path: kong's hook resolver applies a parent path's hooks to every child path, which would cross-wire the controller and the tranches.Include the Hook read interface required by the tranche snapshot hook. Configure the Ethereum controller as a static source in
config/abis.yaml.Events contained in the configured ABIs must be indexed through Kong’s existing automatic event extraction. Do not add event hooks.
2. Discover tranches
Add a controller snapshot hook that:
VAULT,ASSET,reserveVault,tranchesLength, andtranchesByPriority.tranche,vault, andstrategythings.trancheControllerthing carryingasset,mainVault,inceptBlockandinceptTime, whether or not any tranches are registered. Deployments are enumerated from this label rather than from the tranches pointing at it.trancheTypeidentifies whether the contract uses the base or locked tranche implementation. A/B/E names are not used as protocol types.The indexing configuration must ensure each tranche address has one snapshot owner and is not independently processed by conflicting generic ABI paths.
3. Enrich the controller snapshot with tranche state
Kong’s automatic controller snapshot stores the controller’s zero-argument state.
The controller snapshot hook must use
tranchesLengthandtranchesByPriority(index)to append an orderedtranchesarray. For each tranche, readtranches(tranche),liveAssets(tranche), andtrancheCoverage(tranche).Each tranche entry must contain:
Use the automatic snapshot’s block for every appended read.
4. Enrich tranche snapshots with Hook state
Kong’s automatic tranche snapshot stores the current Solidity
hook()return value as the rawhookaddress.The tranche snapshot hook must use that address to append a separate
hookStateobject containing:Requirements:
depositLimitis the Hook'sdepositLimits(tranche)value.hookas the raw Hook address.hookState; do not return a second top-levelhookfield from the snapshot hook.rateLimitWindow.allowedor cooldown mappings.5. Add accounting time series
Generate one daily
tranche-accountingseries per tranche:Generate one daily
tranche-systemseries at the controller address:Values must be read at a single historical block for each observation.
coverageRatiois null when there is no claim to cover — no claim is not evidence of full coverage.6. Support controller-backed assets, PPS, and TVL-C
Refactor the existing vault calculations to obtain the authoritative asset balance through a shared function that accepts a vault thing and block number.
For ordinary vaults, read:
When the vault thing has a
trancheControllerdefault, read:Use the authoritative asset balance in the existing
tvl-ccalculation.For ordinary vault PPS, continue reading:
For tranche PPS, calculate:
When
totalSupplyis zero, return10^vaultDecimals.Use the resulting PPS reader for every current, weekly, monthly, and inception observation required by:
trancheController.liveAssets(vault)already excludespendingExcess; do not add pending excess to PPS or TVL.Keep the existing output labels, components, pricing, historical sampling, annualization, compounding, storage, and REST shapes unchanged. Existing non-tranche vault calculations must remain unchanged.
7. Add REST resources
Add a collection and a member endpoint:
The collection returns every system on the chain, one document per controller. The member returns one, addressed by controller.
controllersis a static route segment, so it resolves ahead of the member route.Each document returns:
Each tranche entry must include its thing metadata, current
hookaddress,hookState, controller accounting, current PPS, coverage, and effective deposit and withdrawal capacity.Expose the new historical labels through Kong’s existing timeseries REST mechanism:
Do not add GraphQL fields or resolvers.
8. Prevent double counting
Tranche TVL represents claims on the main vault’s backing, not additional protocol assets.
tvl-coutputs usingtrancheController.liveAssets(tranche).tvllabel for tranche vaults.pendingExcessin live tranche NAV or TVL.9. Tests and documentation
Add focused tests using Kong’s existing unit and fixed-block RPC test patterns:
totalAssets()and vault things withtrancheControlleruseliveAssets(vault).authoritativeAssets × scale / totalSupplyat a fixed block.pricePerShare().tvl-cconsumes the authoritative asset balance while preserving its existing output shape.tvllabel.hookaddress and appends representative limit data underhookState.Do not add new testing infrastructure or broad container-level tests for this work.
Document the REST endpoint, timeseries labels, accounting semantics, snapshot naming distinction, and current deployment.
Reference: yTranche contracts
Acceptance criteria
trancheControllerthing, and REST enumerates deployments from it.hookaddress and enrichedhookState.tvl-cuses controller-backed assets and does not emit legacytvl.