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

[OTE-779] Check affiliate tiers are strictly increasing before updating tiers #2220

Merged
merged 4 commits into from
Sep 13, 2024
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
6 changes: 4 additions & 2 deletions protocol/x/affiliates/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ func TestAffiliateInfo(t *testing.T) {

// Set up affiliate tiers
tiers := types.DefaultAffiliateTiers
k.UpdateAffiliateTiers(ctx, tiers)
err := k.UpdateAffiliateTiers(ctx, tiers)
require.NoError(t, err)

// Run the setup function
tc.setup(ctx, k, tApp)
Expand Down Expand Up @@ -174,7 +175,8 @@ func TestAllAffiliateTiers(t *testing.T) {
req := &types.AllAffiliateTiersRequest{}

tiers := types.DefaultAffiliateTiers
k.UpdateAffiliateTiers(ctx, tiers)
err := k.UpdateAffiliateTiers(ctx, tiers)
require.NoError(t, err)

res, err := k.AllAffiliateTiers(ctx, req)

Expand Down
17 changes: 13 additions & 4 deletions protocol/x/affiliates/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,20 @@ func (k Keeper) GetTierForAffiliate(

// UpdateAffiliateTiers updates the affiliate tiers.
// Used primarily through governance.
func (k Keeper) UpdateAffiliateTiers(ctx sdk.Context, affiliateTiers types.AffiliateTiers) {
func (k Keeper) UpdateAffiliateTiers(ctx sdk.Context, affiliateTiers types.AffiliateTiers) error {
store := ctx.KVStore(k.storeKey)
// TODO(OTE-779): Check strictly increasing volume and
// staking requirements hold in UpdateAffiliateTiers
store.Set([]byte(types.AffiliateTiersKey), k.cdc.MustMarshal(&affiliateTiers))
affiliateTiersBytes := k.cdc.MustMarshal(&affiliateTiers)
tiers := affiliateTiers.GetTiers()
// start at 1, since 0 is the default tier.
for i := 1; i < len(tiers); i++ {
if tiers[i].ReqReferredVolumeQuoteQuantums <= tiers[i-1].ReqReferredVolumeQuoteQuantums ||
tiers[i].ReqStakedWholeCoins <= tiers[i-1].ReqStakedWholeCoins {
return errorsmod.Wrapf(types.ErrInvalidAffiliateTiers,
"tiers values must be strictly increasing")
}
}
store.Set([]byte(types.AffiliateTiersKey), affiliateTiersBytes)
return nil
}

func (k *Keeper) SetRevShareKeeper(revShareKeeper types.RevShareKeeper) {
Expand Down
69 changes: 56 additions & 13 deletions protocol/x/affiliates/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,11 @@ func TestGetTakerFeeShareViaReferredVolume(t *testing.T) {
k := tApp.App.AffiliatesKeeper
// Set up affiliate tiers
affiliateTiers := types.DefaultAffiliateTiers
k.UpdateAffiliateTiers(ctx, affiliateTiers)
err := k.UpdateAffiliateTiers(ctx, affiliateTiers)
require.NoError(t, err)
stakingKeeper := tApp.App.StakingKeeper

err := stakingKeeper.SetDelegation(ctx,
err = stakingKeeper.SetDelegation(ctx,
stakingtypes.NewDelegation(constants.AliceAccAddress.String(),
constants.AliceValAddress.String(), math.LegacyNewDecFromBigInt(
new(big.Int).Mul(
Expand Down Expand Up @@ -194,13 +195,14 @@ func TestGetTakerFeeShareViaStakedAmount(t *testing.T) {
ctx = ctx.WithBlockTime(time.Now())
// Set up affiliate tiers
affiliateTiers := types.DefaultAffiliateTiers
k.UpdateAffiliateTiers(ctx, affiliateTiers)
err := k.UpdateAffiliateTiers(ctx, affiliateTiers)
require.NoError(t, err)

// Register affiliate and referee
affiliate := constants.AliceAccAddress.String()
referee := constants.BobAccAddress.String()
stakingKeeper := tApp.App.StakingKeeper
err := stakingKeeper.SetDelegation(ctx,
err = stakingKeeper.SetDelegation(ctx,
stakingtypes.NewDelegation(constants.AliceAccAddress.String(),
constants.AliceValAddress.String(), math.LegacyNewDecFromBigInt(
new(big.Int).Mul(
Expand Down Expand Up @@ -248,12 +250,13 @@ func TestGetTierForAffiliate_VolumeAndStake(t *testing.T) {
k := tApp.App.AffiliatesKeeper

affiliateTiers := types.DefaultAffiliateTiers
k.UpdateAffiliateTiers(ctx, affiliateTiers)
err := k.UpdateAffiliateTiers(ctx, affiliateTiers)
require.NoError(t, err)
affiliate := constants.AliceAccAddress.String()
referee := constants.BobAccAddress.String()
stakingKeeper := tApp.App.StakingKeeper

err := stakingKeeper.SetDelegation(ctx,
err = stakingKeeper.SetDelegation(ctx,
stakingtypes.NewDelegation(constants.AliceAccAddress.String(),
constants.AliceValAddress.String(), math.LegacyNewDecFromBigInt(
new(big.Int).Mul(
Expand Down Expand Up @@ -296,12 +299,52 @@ func TestUpdateAffiliateTiers(t *testing.T) {
ctx := tApp.InitChain()
k := tApp.App.AffiliatesKeeper

// Set up valid affiliate tiers
validTiers := types.DefaultAffiliateTiers
k.UpdateAffiliateTiers(ctx, validTiers)
tests := []struct {
name string
affiliateTiers types.AffiliateTiers
expectedError error
}{
{
name: "Valid tiers",
affiliateTiers: types.DefaultAffiliateTiers,
expectedError: nil,
},
{
name: "Invalid tiers - decreasing volume requirement",
affiliateTiers: types.AffiliateTiers{
Tiers: []types.AffiliateTiers_Tier{
{ReqReferredVolumeQuoteQuantums: 1000, ReqStakedWholeCoins: 100, TakerFeeSharePpm: 100},
{ReqReferredVolumeQuoteQuantums: 500, ReqStakedWholeCoins: 200, TakerFeeSharePpm: 200},
},
},
expectedError: types.ErrInvalidAffiliateTiers,
},
{
name: "Invalid tiers - decreasing staking requirement",
affiliateTiers: types.AffiliateTiers{
Tiers: []types.AffiliateTiers_Tier{
{ReqReferredVolumeQuoteQuantums: 1000, ReqStakedWholeCoins: 200, TakerFeeSharePpm: 100},
{ReqReferredVolumeQuoteQuantums: 2000, ReqStakedWholeCoins: 100, TakerFeeSharePpm: 200},
},
},
expectedError: types.ErrInvalidAffiliateTiers,
},
}

// Retrieve and validate updated tiers
updatedTiers, err := k.GetAllAffiliateTiers(ctx)
require.NoError(t, err)
require.Equal(t, validTiers, updatedTiers)
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := k.UpdateAffiliateTiers(ctx, tc.affiliateTiers)

if tc.expectedError != nil {
require.ErrorIs(t, err, tc.expectedError)
} else {
require.NoError(t, err)

// Retrieve and validate updated tiers
updatedTiers, err := k.GetAllAffiliateTiers(ctx)
require.NoError(t, err)
require.Equal(t, tc.affiliateTiers, updatedTiers)
}
})
}
}
5 changes: 4 additions & 1 deletion protocol/x/affiliates/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ func (k msgServer) UpdateAffiliateTiers(ctx context.Context,
)
}

k.Keeper.UpdateAffiliateTiers(sdkCtx, msg.Tiers)
err = k.Keeper.UpdateAffiliateTiers(sdkCtx, msg.Tiers)
if err != nil {
return nil, err
}

return &types.MsgUpdateAffiliateTiersResponse{}, nil
}
Expand Down
Loading