Skip to content

Consume estimated V2 APRs from Kong into yDaemon #560

@murderteeth

Description

@murderteeth

Description

Replace local forward APR/APY calculations for V2 Curve, Convex, Velodrome, and Aerodrome vaults with pre-computed estimated APRs sourced from Kong's GraphQL API. This establishes Kong as the single source of truth for V2 forward APY data, simplifying the architecture and reducing RPC calls, following the same pattern established in PR #559 for V3 oracle APR.

Context

Current implementation: yDaemon calculates forward APY for V2 vaults locally in processes/apr/main.go by calling computeCurveLikeForwardAPY (for Curve/Convex/Frax vaults) and computeVeloLikeForwardAPY (for Velodrome/Aerodrome vaults). These functions make multiple on-chain calls to curve gauges, convex contracts, and velodrome staking pools to compute APR components (boost, poolAPY, baseAPR, rewardsAPY, cvxAPR, keepCRV, keepVelo).

Proposed/New system: Fetch pre-calculated estimated APR/APY from Kong's performance.estimated field and use it directly for V2 forward APY, bypassing local computation. Kong's v2-estimated-apr-hook already computes these values with the same methodology and stores them in the output table.

Relevant references:

Tasks

1. Add estimated APR types to Kong client

  • Add KongEstimatedComponents struct in internal/kong/client.go with optional fields:
    • Boost *float64
    • PoolAPY *float64
    • BoostedAPR *float64
    • BaseAPR *float64
    • RewardsAPR *float64
    • RewardsAPY *float64
    • CvxAPR *float64
    • KeepCRV *float64
    • KeepVelo *float64
  • Add KongEstimated struct with:
    • Apr *float64
    • Apy *float64
    • Type *string (crv, velo, aero)
    • Components *KongEstimatedComponents
  • Add Estimated *KongEstimated field to KongPerformance struct

2. Update GraphQL queries to fetch estimated APR

  • Update FetchVaultsForChain query in internal/kong/client.go to include:
    performance {
      oracle { apr apy }
      estimated {
        apr
        apy
        type
        components {
          boost
          poolAPY
          boostedAPR
          baseAPR
          rewardsAPR
          rewardsAPY
          cvxAPR
          keepCRV
          keepVelo
        }
      }
    }
  • Update FetchAllVaults query with the same fields

3. Add model types for Kong estimated APR

  • Add TKongEstimatedComponents struct in internal/models/vaults.go:
    • All component fields as *float64 (optional)
  • Add TKongEstimated struct with Apr, Apy, Type, and Components fields
  • Add Estimated TKongEstimated field to TKongPerformance struct

4. Update Kong indexer to store estimated APR

  • Update IndexNewVaults in internal/indexer/indexer.kong.go to extract performance.estimated data
  • Populate TKongPerformance.Estimated when storing Kong vault data

5. Add storage accessor for estimated APR

  • Add GetKongEstimatedAPY function in internal/storage/elem.vaults.go
  • Return (apr *float64, apy *float64, aprType *string, components *TKongEstimatedComponents, exists bool)

6. Update forward APY calculation to use Kong data

  • Modify ComputeChainAPY in processes/apr/main.go:
    • Before calling computeCurveLikeForwardAPY, check if Kong estimated APR is available via storage.GetKongEstimatedAPY
    • If available, construct TForwardAPY from Kong data instead of computing locally
    • Map Kong components to TCompositeData fields
    • Fall back to local computation only if Kong data is unavailable
  • Apply same pattern for Velodrome/Aerodrome vaults (replace computeVeloLikeForwardAPY calls)

7. Add documentation

  • Update docs/apr-oracle-integration.md to document V2 estimated APR integration
  • Note that V2 Curve/Convex/Velo/Aero vaults now source forward APY from Kong

Manual Testing

Prerequisites

  • Local yDaemon build with changes
  • Local yearn.fi frontend clone

Test Steps

  1. Start local yDaemon

    go build -o yDaemon ./cmd
    ./yDaemon -chains 1

    Wait for APY computation to complete (look for 📈 [APY DONE] log)

  2. Start local yearn.fi pointing at local yDaemon

    # In yearn.fi repo
    NEXT_PUBLIC_YDAEMON_BASE_URI=http://localhost:8080 bun dev
  3. Compare V2 estimated APRs

    • Open local yearn.fi at http://localhost:3000
    • Open production yearn.fi at https://yearn.fi
    • Navigate to V2 vaults with Curve/Convex strategies (e.g., yvCurve-stETH, yvCurve-3pool)
    • Compare the displayed APY values between local and production
    • Values should be similar (within reasonable variance due to timing)
  4. Verify API response structure

    # Check a known CRV vault on local
    curl -s http://localhost:8080/1/vaults/0xdCD90C7f6324cfa40d7169ef80b12031770B4325 | jq '.apr.forwardAPR'
    
    # Compare with production
    curl -s https://ydaemon.yearn.fi/1/vaults/0xdCD90C7f6324cfa40d7169ef80b12031770B4325 | jq '.apr.forwardAPR'
  5. Check component fields are populated

    • Verify composite object contains expected fields (boost, poolAPY, baseAPR, etc.)
    • Verify type field reflects the strategy type (crv, velo, aero)

Expected Results

  • Forward APY values match or are very close to production
  • All component fields present in API response
  • No errors in yDaemon logs related to Kong data fetching
  • yearn.fi displays APY correctly without console errors

Acceptance Criteria

  • V2 vaults with Curve/Convex strategies use Kong estimated APR when available
  • V2 vaults with Velodrome/Aerodrome strategies use Kong estimated APR when available
  • All APR components (boost, poolAPY, baseAPR, rewardsAPY, cvxAPR, keepCRV, keepVelo) are preserved in API response
  • Forward APY type reflects Kong source (e.g., crv, velo, aero from Kong)
  • Graceful fallback to local computation when Kong data is unavailable
  • No breaking changes to existing API response structure (apr.forwardAPR format unchanged)
  • Reduced RPC calls during APY computation for vaults with Kong data
  • Manual testing completed: local yDaemon + yearn.fi APRs match production

Technical Notes

  • Kong webhook labels are: crv-estimated-apr, velo-estimated-apr, aero-estimated-apr
  • Chains with estimated APR data: 1 (mainnet), 10 (Optimism), 250 (Fantom), 42161 (Arbitrum), 8453 (Base for aero)
  • Kong's netAPR and netAPY map to the headline apr and apy fields
  • Component fields are optional since they vary by APR type:
    • CRV type: boost, poolAPY, boostedAPR, baseAPR, rewardsAPR, rewardsAPY, cvxAPR, keepCRV
    • VELO/AERO type: keepVelo (and potentially fewer components)
  • The type field indicates which strategy type produced the estimate
  • Unlike V3 oracle APR which is always used, V2 estimated APR should gracefully fall back to local computation to maintain backward compatibility during rollout

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions