From b41f72de98515f3cd84867544a76c38e2a319ea0 Mon Sep 17 00:00:00 2001 From: Joe Bowman Date: Thu, 26 Sep 2024 13:15:55 +0100 Subject: [PATCH] ensure we use the correct zone denom where evaluating pool claims --- .../osmosis-types/validation.go | 36 +++++-------------- x/airdrop/keeper/claim_handler.go | 2 +- .../keeper/submodule_osmosis.go | 8 ++++- .../keeper/submodule_osmosiscl.go | 36 ++++++++++++++++++- 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/third-party-chains/osmosis-types/validation.go b/third-party-chains/osmosis-types/validation.go index 73279dd53..19d876518 100644 --- a/third-party-chains/osmosis-types/validation.go +++ b/third-party-chains/osmosis-types/validation.go @@ -10,7 +10,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" osmosislockuptypes "github.com/quicksilver-zone/quicksilver/third-party-chains/osmosis-types/lockup" - "github.com/quicksilver-zone/quicksilver/utils" participationrewardstypes "github.com/quicksilver-zone/quicksilver/x/participationrewards/types" cl "github.com/quicksilver-zone/quicksilver/third-party-chains/osmosis-types/concentrated-liquidity" @@ -22,7 +21,7 @@ type ParticipationRewardsKeeper interface { GetProtocolData(ctx sdk.Context, pdType participationrewardstypes.ProtocolDataType, key string) (participationrewardstypes.ProtocolData, bool) } -func DetermineApplicableTokensInPool(ctx sdk.Context, prKeeper ParticipationRewardsKeeper, lock osmosislockuptypes.PeriodLock, chainID string) (math.Int, error) { +func DetermineApplicableTokensInPool(ctx sdk.Context, prKeeper ParticipationRewardsKeeper, lock osmosislockuptypes.PeriodLock, chainID string, poolDenom string) (math.Int, error) { gammtoken, err := lock.SingleCoin() if err != nil { return sdk.ZeroInt(), err @@ -40,18 +39,6 @@ func DetermineApplicableTokensInPool(ctx sdk.Context, prKeeper ParticipationRewa } pool, _ := ipool.(*participationrewardstypes.OsmosisPoolProtocolData) - poolDenom := "" - for _, zk := range utils.Keys(pool.Denoms) { - if pool.Denoms[zk].ChainID == chainID { - poolDenom = zk - break - } - } - - if poolDenom == "" { - return sdk.ZeroInt(), fmt.Errorf("invalid zone, pool zone must match %s", chainID) - } - poolData, err := pool.GetPool() if err != nil { return sdk.ZeroInt(), err @@ -91,8 +78,10 @@ func CalculateUnderlyingAssetsFromPosition(ctx sdk.Context, position clmodel.Pos return coin0, coin1, nil } -func DetermineApplicableTokensInClPool(ctx sdk.Context, prKeeper ParticipationRewardsKeeper, position clmodel.Position, chainID string) (math.Int, error) { +func DetermineApplicableTokensInClPool(ctx sdk.Context, prKeeper ParticipationRewardsKeeper, position clmodel.Position, chainID string, poolDenom string) (math.Int, error) { poolID := position.PoolId + + ctx.Logger().Info("DetermineApplicableTokensInClPool", "poolID", poolID, "position", position) pd, ok := prKeeper.GetProtocolData(ctx, participationrewardstypes.ProtocolDataTypeOsmosisCLPool, fmt.Sprintf("%d", poolID)) if !ok { return sdk.ZeroInt(), fmt.Errorf("unable to obtain protocol data for poolID=%d", poolID) @@ -104,18 +93,6 @@ func DetermineApplicableTokensInClPool(ctx sdk.Context, prKeeper ParticipationRe } pool, _ := ipool.(*participationrewardstypes.OsmosisClPoolProtocolData) - poolDenom := "" - for _, zk := range utils.Keys(pool.Denoms) { - if pool.Denoms[zk].ChainID == chainID { - poolDenom = zk - break - } - } - - if poolDenom == "" { - return sdk.ZeroInt(), fmt.Errorf("invalid zone, pool zone must match %s", chainID) - } - poolData, err := pool.GetPool() if err != nil { return sdk.ZeroInt(), err @@ -126,13 +103,16 @@ func DetermineApplicableTokensInClPool(ctx sdk.Context, prKeeper ParticipationRe if err != nil { return sdk.ZeroInt(), errors.New("unable to determine underlying assets for position") } + + ctx.Logger().Info("DetermineApplicableTokensInClPool", "asset0", asset0, "asset1", asset1) + switch true { case asset0.Denom == poolDenom: asset = asset0 case asset1.Denom == poolDenom: asset = asset1 default: - return sdk.ZeroInt(), fmt.Errorf("position does not match local denom for %s", chainID) + return sdk.ZeroInt(), fmt.Errorf("position does not match local denom for %s (poolDenom: %s)", chainID, poolDenom) } return asset.Amount, nil diff --git a/x/airdrop/keeper/claim_handler.go b/x/airdrop/keeper/claim_handler.go index f85b8219a..e7c35f7b2 100644 --- a/x/airdrop/keeper/claim_handler.go +++ b/x/airdrop/keeper/claim_handler.go @@ -307,7 +307,7 @@ func (k *Keeper) verifyOsmosisLP(ctx sdk.Context, proofs []*cmtypes.Proof, cr ty } func (k *Keeper) verifyPoolAndGetAmount(ctx sdk.Context, lock osmosislockuptypes.PeriodLock, cr types.ClaimRecord) (sdkmath.Int, error) { - return osmosistypes.DetermineApplicableTokensInPool(ctx, k.prKeeper, lock, cr.ChainId) + return osmosistypes.DetermineApplicableTokensInPool(ctx, k.prKeeper, lock, cr.ChainId, "UNUSED") } // ----------- diff --git a/x/participationrewards/keeper/submodule_osmosis.go b/x/participationrewards/keeper/submodule_osmosis.go index 7562b8666..305d8c54d 100644 --- a/x/participationrewards/keeper/submodule_osmosis.go +++ b/x/participationrewards/keeper/submodule_osmosis.go @@ -139,7 +139,13 @@ func (*OsmosisModule) ValidateClaim(ctx sdk.Context, k *Keeper, msg *types.MsgSu } } } - sdkAmount, err := osmosistypes.DetermineApplicableTokensInPool(ctx, k, lock, msg.Zone) + + denom, found := k.ApplicableDenomForZone(ctx, msg.Zone) + if !found { + return math.ZeroInt(), errors.New("no applicable denom found for zone") + } + + sdkAmount, err := osmosistypes.DetermineApplicableTokensInPool(ctx, k, lock, msg.Zone, denom) if err != nil { return sdk.ZeroInt(), err } diff --git a/x/participationrewards/keeper/submodule_osmosiscl.go b/x/participationrewards/keeper/submodule_osmosiscl.go index 519c34011..88313b5f7 100644 --- a/x/participationrewards/keeper/submodule_osmosiscl.go +++ b/x/participationrewards/keeper/submodule_osmosiscl.go @@ -110,7 +110,12 @@ func (*OsmosisClModule) ValidateClaim(ctx sdk.Context, k *Keeper, msg *types.Msg } } - sdkAmount, err := osmosistypes.DetermineApplicableTokensInClPool(ctx, k, position, msg.Zone) + denom, found := k.ApplicableDenomForZone(ctx, msg.Zone) + if !found { + return math.ZeroInt(), errors.New("no applicable denom found for zone") + } + + sdkAmount, err := osmosistypes.DetermineApplicableTokensInClPool(ctx, k, position, msg.Zone, denom) if err != nil { return math.ZeroInt(), err } @@ -126,3 +131,32 @@ func (*OsmosisClModule) ValidateClaim(ctx sdk.Context, k *Keeper, msg *types.Msg func (*OsmosisClModule) KeyPool(poolID uint64) []byte { return osmocl.KeyPool(poolID) } + +func (k *Keeper) ApplicableDenomForZone(ctx sdk.Context, chainId string) (denom string, found bool) { + zone, found := k.icsKeeper.GetZone(ctx, chainId) + if !found { + return "", false + } + + params, found := k.GetProtocolData(ctx, types.ProtocolDataTypeOsmosisParams, types.OsmosisParamsKey) + if !found { + return "", false + } + + paramsData := types.OsmosisParamsProtocolData{} + if err := json.Unmarshal(params.Data, ¶msData); err != nil { + return "", false + } + + k.IteratePrefixedProtocolDatas(ctx, types.GetPrefixProtocolDataKey(types.ProtocolDataTypeLiquidToken), func(idx int64, key []byte, data types.ProtocolData) bool { + liquidToken, _ := types.UnmarshalProtocolData(types.ProtocolDataTypeLiquidToken, data.Data) + liquidTokenData := liquidToken.(*types.LiquidAllowedDenomProtocolData) + if liquidTokenData.ChainID == paramsData.ChainID && liquidTokenData.QAssetDenom == zone.LocalDenom { + found = true + denom = liquidTokenData.IbcDenom + return true + } + return false + }) + return denom, found +}