Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions external/vaults/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ type TExternalVault struct {
Info TExternalVaultInfo `json:"info,omitempty"`
FeaturingScore float64 `json:"featuringScore"` // Computing only
PricePerShare *bigNumber.Int `json:"pricePerShare"`
Debts []models.TKongDebt `json:"debts"`
}

/**************************************************************************************************
Expand Down Expand Up @@ -368,6 +369,15 @@ func ApplyKongData(externalVault *TExternalVault, vault models.TVault) {
externalVault.APR.Fees.Management = bigNumber.NewFloat(float64(managementFee) / 10000.0)
externalVault.APR.Fees.Performance = bigNumber.NewFloat(float64(performanceFee) / 10000.0)

for _, strategyAddress := range kongData.StrategyAddresses {
strategy, ok := storage.GuessStrategy(vault.ChainID, strategyAddress)
if !ok {
continue
}

externalVault.Strategies = append(externalVault.Strategies, CreateExternalStrategy(strategy))
}

// Future: Apply other kong data
// applyKongPrices(externalVault, kongData)
// applyKongAPY(externalVault, kongData)
Expand Down Expand Up @@ -485,6 +495,7 @@ func CreateExternalVault(vault models.TVault) (TExternalVault, error) {
Description: vault.Metadata.Description,
Category: fetcher.BuildVaultCategory(vault, strategies),
PricePerShare: vault.LastPricePerShare,
Debts: vault.Debts,
Details: TExternalVaultDetails{
IsRetired: vault.Metadata.IsRetired,
IsHidden: vault.Metadata.IsHidden,
Expand Down
56 changes: 20 additions & 36 deletions external/vaults/route.vaults.one.simplified.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/gin-gonic/gin"
"github.com/yearn/ydaemon/common/bigNumber"
"github.com/yearn/ydaemon/internal/models"
"github.com/yearn/ydaemon/internal/storage"
)
Expand Down Expand Up @@ -100,13 +101,7 @@ func (y Controller) GetSimplifiedVault(c *gin.Context) {
if newVault.APR.NetAPR != nil {
// APR.NetAPR.Float64() returns (float64, big.Accuracy), not an error
// big.Accuracy is an int8 type that indicates precision, not an error
var acc interface{}
APRAsFloat, acc = newVault.APR.NetAPR.Float64()
if acc != nil {
// Log a warning but continue with the calculated value
c.Error(fmt.Errorf("reduced precision when converting APR to float for vault %s: %v",
address.String(), acc))
}
APRAsFloat, _ = newVault.APR.NetAPR.Float64()
}

// Check for potential arithmetic overflow due to very large values
Expand Down Expand Up @@ -137,40 +132,29 @@ func (y Controller) GetSimplifiedVault(c *gin.Context) {
newVault.FeaturingScore = newVault.FeaturingScore * 1e18
}

vaultStrategiesMap, vaultStrategies := storage.ListStrategiesForVault(currentVault.ChainID, common.HexToAddress(newVault.Address))
if len(vaultStrategies) == 0 && len(vaultStrategiesMap) == 0 {
// Log a warning but continue - no strategies is a valid scenario
c.Error(fmt.Errorf("no strategies found for vault %s on chain %d",
address.String(), chainID))
}

// Initialize the strategies array with appropriate capacity to avoid reallocations
newVault.Strategies = make([]TExternalStrategy, 0, len(vaultStrategies))

// Process strategies with context awareness
// Fetch and process strategies with context awareness
vaultStrategies, _ := storage.ListStrategiesForVault(chainID, address)
newVault.Strategies = []TExternalStrategy{}
for _, strategy := range vaultStrategies {
// Try to convert the strategy, capturing any errors
var strategyWithDetails TExternalStrategy
func() {
// Use a deferred recover to handle any panics during conversion
defer func() {
if r := recover(); r != nil {
c.Error(fmt.Errorf("panic while processing strategy %s: %v", strategy.Address.String(), r))
}
}()
strategyWithDetails := CreateExternalStrategy(strategy)

strategyWithDetails = CreateExternalStrategy(strategy)
}()

// Skip invalid strategies
if strategyWithDetails.Address == "" {
c.Error(fmt.Errorf("failed to convert strategy %s to external format",
strategy.Address.String()))
if !strategyWithDetails.ShouldBeIncluded(strategiesCondition) {
continue
}

if !strategyWithDetails.ShouldBeIncluded(strategiesCondition) {
continue
strategyAddress := common.HexToAddress(strategyWithDetails.Address)

for _, debt := range newVault.Debts {
if debt.Strategy == strategyAddress.Hex() {
if debt.CurrentDebt != nil {
strategyWithDetails.Details.TotalDebt = bigNumber.NewInt().SetString(*debt.CurrentDebt)
} else if debt.TotalDebt != nil {
strategyWithDetails.Details.TotalDebt = bigNumber.NewInt().SetString(*debt.TotalDebt)
} else {
strategyWithDetails.Details.TotalDebt = bigNumber.NewInt().SetString("0")
}
break
}
}

newVault.Strategies = append(newVault.Strategies, strategyWithDetails)
Expand Down
26 changes: 17 additions & 9 deletions internal/fetcher/vaults.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fetcher

import (
"encoding/json"
"strconv"
"strings"

Expand Down Expand Up @@ -90,6 +89,9 @@ func fetchVaultsBasicInformations(
if vault.Metadata.IsRetired && !isException {
continue
}
// Preserve debts and other Kong data before processing
preservedDebts := vault.Debts
preservedKongTVL := vault.KongTVL
newVault := vault
newVault.ChainID = chainID
versionMajor := strings.Split(vault.Version, `.`)[0]
Expand All @@ -98,6 +100,9 @@ func fetchVaultsBasicInformations(
} else {
newVault = handleV2VaultCalls(vault, response)
}
// Restore preserved Kong data
newVault.Debts = preservedDebts
newVault.KongTVL = preservedKongTVL
vaultList = append(vaultList, newVault)
}
}
Expand Down Expand Up @@ -168,11 +173,8 @@ func RetrieveAllVaults(
Activation: currentVault.BlockNumber,
}

// Assign Kong debts to vault
if kongDebts, ok := storage.GetKongDebts(chainID, currentVault.Address); ok {
if kongDebtsJSON, err := json.Marshal(kongDebts); err == nil {
newVault.KongDebts = string(kongDebtsJSON)
}
newVault.Debts = kongDebts
}
// Assign Kong TVL to vault
if kongTVL, ok := storage.GetKongTVL(chainID, currentVault.Address); ok {
Expand Down Expand Up @@ -205,9 +207,7 @@ func RetrieveAllVaults(

// Assign Kong debts to vault
if kongDebts, ok := storage.GetKongDebts(chainID, currentVault.Address); ok {
if kongDebtsJSON, err := json.Marshal(kongDebts); err == nil {
newVault.KongDebts = string(kongDebtsJSON)
}
newVault.Debts = kongDebts
}
// Assign Kong TVL to vault
if kongTVL, ok := storage.GetKongTVL(chainID, currentVault.Address); ok {
Expand All @@ -228,6 +228,10 @@ func RetrieveAllVaults(
**********************************************************************************************/
for _, vault := range newVaultList {
vault.ChainID = chainID
// Ensure Kong debts are preserved if they exist
if kongDebts, ok := storage.GetKongDebts(chainID, vault.Address); ok && len(kongDebts) > 0 {
vault.Debts = kongDebts
}
/******************************************************************************************
** In some situation, a vault can be added to multiple registries: by default the public
** one, and sometime another one on top which should be considered as the actual one.
Expand Down Expand Up @@ -299,7 +303,7 @@ func RetrieveAllVaults(
** registry address of the vault we have in the vaults map.
**********************************************************************************************/
vaultMapFromStorage, _ := storage.ListVaults(chainID)
for _, vault := range vaultMap {
for _, vault := range vaultMapFromStorage {
/******************************************************************************************
** In some situation, a vault can be added to multiple registries: by default the public
** one, and sometime another one on top which should be considered as the actual one.
Expand Down Expand Up @@ -355,6 +359,10 @@ func RetrieveAllVaults(
vault.Metadata.Category = models.TVaultCategoryType(category)
}
}
// Ensure Kong debts are preserved if they exist
if kongDebts, ok := storage.GetKongDebts(chainID, vault.Address); ok && len(kongDebts) > 0 {
vault.Debts = kongDebts
}
vaultMapFromStorage[vault.Address] = vault
}
storage.StoreVaultsToJson(chainID, vaultMapFromStorage)
Expand Down
6 changes: 6 additions & 0 deletions internal/indexer/indexer.kong.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,14 @@ func IndexNewVaults(chainID uint64) map[common.Address]models.TVaultsFromRegistr
Debts: debts,
TVL: data.Vault.GetTVL(),
TotalAssets: data.TotalAssets,
StrategyAddresses: data.Vault.GetStrategies(),
}
storage.StoreKongVaultData(chainID, vaultAddr, kongSchema)

// Log if debts were found for debugging
if len(debts) > 0 {
logs.Info(chainID, `-`, `Stored %d debts for vault %s`, len(debts), vaultAddr.Hex())
}
}

logs.Success(chainID, `-`, `Indexed %d vaults from Kong (complete replacement)`, len(vaultsFromKong))
Expand Down
3 changes: 2 additions & 1 deletion internal/models/vaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ type TVault struct {

// Kong-sourced data (single source of truth for TVL and debts)
KongTVL string `json:"kongTvl,omitempty"` // TVL from Kong API (tvl.close field)
KongDebts string `json:"kongDebts,omitempty"` // JSON-encoded debts array from Kong API
Debts []TKongDebt `json:"debts,omitempty"`

// Manual elements. They are manually set by the team
Metadata TVaultMetadata `json:"metadata"` // The metadata of the vault
Expand Down Expand Up @@ -333,4 +333,5 @@ type TKongVaultSchema struct {
APY KongAPY `json:"apy"`
ManagementFee uint64 `json:"managementFee"` // Basis points from Kong (direct field takes priority)
PerformanceFee uint64 `json:"performanceFee"` // Basis points from Kong (direct field takes priority)
StrategyAddresses []common.Address `json:"strategyAddresses"` // Strategy addresses from Kong
}
13 changes: 2 additions & 11 deletions internal/storage/elem.vaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,8 @@ func LoadVaults(chainID uint64, wg *sync.WaitGroup) {
// logs.Info("Apply cms vault metadata", chainID, vault.Address)
}

// Refresh Kong debts and TVL data if available
if kongDebts, ok := GetKongDebts(chainID, vault.Address); ok {
if kongDebtsJSON, err := json.Marshal(kongDebts); err == nil {
vault.KongDebts = string(kongDebtsJSON)
}
vault.Debts = kongDebts
}
if kongTVL, ok := GetKongTVL(chainID, vault.Address); ok {
vault.LastTotalAssets = bigNumber.NewFloat(kongTVL).Int()
Expand Down Expand Up @@ -361,14 +358,8 @@ func RefreshVaultMetadata(chainID uint64) {
ApplyCmsVaultMeta(vaultMeta, &vault)
}

// Refresh Kong debts and TVL data
if kongDebts, ok := GetKongDebts(chainID, address); ok {
if kongDebtsJSON, err := json.Marshal(kongDebts); err == nil {
vault.KongDebts = string(kongDebtsJSON)
}
}
if kongTVL, ok := GetKongTVL(chainID, address); ok {
vault.LastTotalAssets = bigNumber.NewInt(int64(kongTVL))
vault.LastTotalAssets = bigNumber.NewFloat(kongTVL).Int()
}

StoreVault(chainID, vault)
Expand Down