Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/migaloo alliance hub #100

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
3 changes: 3 additions & 0 deletions config/alliance_default_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ var AllianceDefaultConfig = AllianceConfig{
},
},
},
VTAllianceHubMap: map[string]string{
"factory/migaloo190qz7q5fu4079svf890h4h3f8u46ty6cxnlt78eh486k9qm995hquuv9kd/ualliance": "migaloo190qz7q5fu4079svf890h4h3f8u46ty6cxnlt78eh486k9qm995hquuv9kd",
},
}
7 changes: 4 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ type ProviderConfig struct {
}

type AllianceConfig struct {
GRPCUrls []string `json:"lcdList,omitempty"`
LSTSData []LSTData `json:"lstData,omitempty"`
LSTOnPhoenix []LSTOnPhoenix `json:"lstOnPhoenix,omitempty"`
GRPCUrls []string `json:"lcdList,omitempty"`
LSTSData []LSTData `json:"lstData,omitempty"`
LSTOnPhoenix []LSTOnPhoenix `json:"lstOnPhoenix,omitempty"`
VTAllianceHubMap map[string]string `json:"vtAllianceHubMap,omitempty"`
}

type LSTData struct {
Expand Down
127 changes: 127 additions & 0 deletions internal/provider/alliance/alliance_protocols_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ package alliance_provider

import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"time"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"

alliancetypes "github.com/terra-money/alliance/x/alliance/types"
"github.com/terra-money/oracle-feeder-go/config"
Expand Down Expand Up @@ -90,6 +94,7 @@ func (p *allianceProtocolsInfo) GetProtocolsInfo(ctx context.Context) (*pkgtypes
mintClient := mintypes.NewQueryClient(grpcConn)
stakingClient := stakingtypes.NewQueryClient(grpcConn)
allianceClient := alliancetypes.NewQueryClient(grpcConn)
wasmClient := wasmtypes.NewQueryClient(grpcConn)

// Request alliances from the origin chain.
allianceRes, err := allianceClient.Alliances(ctx, &alliancetypes.QueryAlliancesRequest{})
Expand All @@ -102,6 +107,12 @@ func (p *allianceProtocolsInfo) GetProtocolsInfo(ctx context.Context) (*pkgtypes
continue
}

allianceRes, err = p.pullAndMergeAllianceHubAssets(ctx, wasmClient, allianceRes)
if err != nil {
fmt.Printf("error merging alliance hub assets: %v \n", err)
return nil, err
}

allianceParamsRes, err := allianceClient.Params(ctx, &alliancetypes.QueryParamsRequest{})
if err != nil {
fmt.Printf("allianceParamsRes: %v \n", err)
Expand Down Expand Up @@ -253,6 +264,122 @@ func (p *allianceProtocolsInfo) parseLunaAlliances(
return lunaAlliances
}

func (p *allianceProtocolsInfo) pullAndMergeAllianceHubAssets(ctx context.Context, wasmClient wasmtypes.QueryClient, allianceRes *alliancetypes.QueryAlliancesResponse) (finalAlliances *alliancetypes.QueryAlliancesResponse, err error) {
// Deal with alliance hub implementations
for i, hubAlliance := range allianceRes.Alliances {
// Alliance Hub implementations need to be adding in the config
allianceHub := p.config.VTAllianceHubMap[hubAlliance.Denom]
if allianceHub == "" {
continue
}
// Setting the alliance hub VT token reward weight to 0 since
// we are going to assign the reward weight to alliance hub assets
allianceRes.Alliances[i].RewardWeight = sdktypes.ZeroDec()

// Query the total staked balances
res, err := wasmClient.SmartContractState(ctx, &wasmtypes.QuerySmartContractStateRequest{
Address: allianceHub,
QueryData: []byte("{\"total_staked_balances\": {}}"),
})
if err != nil {
return finalAlliances, err
}

var hubBalances types.AllianceHubBalances
err = json.Unmarshal(res.Data, &hubBalances)
if err != nil {
return finalAlliances, err
}

// Query the reward distribution
res, err = wasmClient.SmartContractState(ctx, &wasmtypes.QuerySmartContractStateRequest{
Address: allianceHub,
QueryData: []byte("{\"reward_distribution\": {}}"),
})
if err != nil {
return finalAlliances, err
}

var hubDistribution types.AllianceHubRewardDistribution
err = json.Unmarshal(res.Data, &hubDistribution)
if err != nil {
return finalAlliances, err
}

// Create a map of the distribution for easy access later
distributionMap := make(map[string]sdktypes.Dec)
for _, distribution := range hubDistribution {
assetDenom := distribution.Asset.Cw20
if assetDenom == "" {
assetDenom = distribution.Asset.Native
}
distributionMap[assetDenom] = sdktypes.MustNewDecFromStr(distribution.Distribution)
}

// Convert the staked assets into alliance assets
// Default values since these are not used and are not available in the hub
// TakeRate: sdktypes.ZeroDec(),
// TotalValidatorShares: sdktypes.ZeroDec(),
// RewardChangeRate: sdktypes.Dec{},

for _, hubBalance := range hubBalances {
totalStaked, ok := sdktypes.NewIntFromString(hubBalance.Balance)
if !ok {
return finalAlliances, fmt.Errorf("failed to parse totalStaked: %v for %s", ok, hubBalance.Asset)
}
assetDenom := hubBalance.Asset.Cw20
if assetDenom == "" {
assetDenom = hubBalance.Asset.Native
}
alliance := alliancetypes.AllianceAsset{
Denom: assetDenom,
RewardWeight: hubAlliance.RewardWeight.Mul(distributionMap[assetDenom]),
TakeRate: sdktypes.ZeroDec(),
TotalTokens: totalStaked,
TotalValidatorShares: sdktypes.ZeroDec(),
RewardStartTime: hubAlliance.RewardStartTime,
RewardChangeRate: sdktypes.ZeroDec(),
RewardChangeInterval: 0,
LastRewardChangeTime: time.Time{},
RewardWeightRange: alliancetypes.RewardWeightRange{},
IsInitialized: hubAlliance.IsInitialized,
}
allianceRes.Alliances = append(allianceRes.Alliances, alliance)
}
}

// Merge duplicated alliances by averaging the reward weight and take rate based on staked tokens
var allianceMap = make(map[string]alliancetypes.AllianceAsset)
for _, alliance := range allianceRes.Alliances {
// if the asset does not exist add it to the map as a new asset
// else merge the asset with the existing asset
if _, ok := allianceMap[alliance.Denom]; !ok {
allianceMap[alliance.Denom] = alliance
} else {
finalAlliance := allianceMap[alliance.Denom]
totalStaked := finalAlliance.TotalTokens.Add(alliance.TotalTokens)
finalAlliance.RewardWeight = finalAlliance.RewardWeight.
Mul(sdktypes.NewDecFromInt(finalAlliance.TotalTokens)).
Add(alliance.RewardWeight.Mul(sdktypes.NewDecFromInt(alliance.TotalTokens))).
Quo(sdktypes.NewDecFromInt(totalStaked))

finalAlliance.TakeRate = finalAlliance.TakeRate.
Mul(sdktypes.NewDecFromInt(finalAlliance.TotalTokens)).
Add(alliance.TakeRate.
Mul(sdktypes.NewDecFromInt(alliance.TotalTokens))).
Quo(sdktypes.NewDecFromInt(totalStaked))
allianceMap[finalAlliance.Denom] = finalAlliance
}
}

// Combine into a map of alliances and return it
allianceRes.Alliances = make([]alliancetypes.AllianceAsset, 0)
for _, alliance := range allianceMap {
allianceRes.Alliances = append(allianceRes.Alliances, alliance)
}
return allianceRes, nil
}

func calculateAnnualizedTakeRate(
params alliancetypes.Params,
alliance alliancetypes.AllianceAsset,
Expand Down
16 changes: 16 additions & 0 deletions internal/types/alliance_hub_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,19 @@ type AllianceHubConfigData struct {
AllianceTokenSupply string `json:"alliance_token_supply"`
RewardDenom string `json:"reward_denom"`
}

type AllianceHubBalances []struct {
Asset struct {
Cw20 string `json:"cw20,omitempty"`
Native string `json:"native,omitempty"`
} `json:"asset"`
Balance string `json:"balance,omitempty"`
}

type AllianceHubRewardDistribution []struct {
Asset struct {
Cw20 string `json:"cw20,omitempty"`
Native string `json:"native,omitempty"`
}
Distribution string `json:"distribution,omitempty"`
}
Loading