Skip to content

Commit

Permalink
Merge pull request #422 from scorpioborn/fix/disallow-rewards-for-no-bet
Browse files Browse the repository at this point in the history
Feature / Force at least single bet for reward grant
  • Loading branch information
scorpioborn authored Jul 11, 2024
2 parents 04346b5 + 225fb42 commit 6536cdc
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 3 deletions.
4 changes: 2 additions & 2 deletions app/upgrades/v10/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"github.com/sge-network/sge/app/upgrades"
)

// UpgradeName defines the on-chain upgrade name for the v1.7.1 upgrade.
const UpgradeName = "v1.7.1"
// UpgradeName defines the on-chain upgrade name for the v1.7.2 upgrade.
const UpgradeName = "v1.7.2"

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
Expand Down
16 changes: 16 additions & 0 deletions x/bet/keeper/bet.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ func (k Keeper) GetBets(ctx sdk.Context) (list []types.Bet, err error) {
return
}

// IsAnyBetForAccount checks if there is any bet for the account
func (k Keeper) IsAnyBetForAccount(ctx sdk.Context, creator string) (thereIs bool, err error) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.BetListByCreatorPrefix(creator))

// create iterator for all existing records
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer func() {
err = iterator.Close()
}()

// check if the iterator has any records
thereIs = iterator.Valid()

return
}

// SetBetID sets a specific bet id map in the store
func (k Keeper) SetBetID(ctx sdk.Context, uid2ID types.UID2ID) {
store := k.getBetIDStore(ctx)
Expand Down
14 changes: 14 additions & 0 deletions x/bet/keeper/bet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/sge-network/sge/testutil/nullify"
"github.com/sge-network/sge/testutil/sample"
"github.com/sge-network/sge/testutil/simapp"
"github.com/sge-network/sge/x/bet/keeper"
"github.com/sge-network/sge/x/bet/types"
Expand Down Expand Up @@ -104,3 +105,16 @@ func TestSortBetGetAll(t *testing.T) {
nullify.Fill(bets),
)
}

func TestBetIsAnyBetForAccount(t *testing.T) {
tApp, k, ctx := setupKeeperAndApp(t)
items := createNBet(tApp, k, ctx, 10)

thereIs, err := k.IsAnyBetForAccount(ctx, items[0].Creator)
require.NoError(t, err)
require.True(t, thereIs)

thereIs, err = k.IsAnyBetForAccount(ctx, sample.AccAddress())
require.NoError(t, err)
require.False(t, thereIs)
}
96 changes: 95 additions & 1 deletion x/reward/keeper/msg_server_reward_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ func TestMsgApplySignupReward(t *testing.T) {
promoter := simapp.TestParamUsers["user1"].Address.String()
receiverAddr := simapp.TestParamUsers["user2"].Address.String()

// dummy bet to pass at least one bet condition
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
receiverAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)

_, err := tApp.SubaccountKeeper.CreateSubaccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{
{
Amount: sdkmath.ZeroInt(),
Expand Down Expand Up @@ -163,6 +171,14 @@ func TestMsgApplySignupRewardWithCap(t *testing.T) {
promoter := simapp.TestParamUsers["user1"].Address.String()
receiverAddr := simapp.TestParamUsers["user2"].Address.String()

// dummy bet to pass at least one bet condition
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
receiverAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)

_, err := tApp.SubaccountKeeper.CreateSubaccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{
{
Amount: sdkmath.ZeroInt(),
Expand Down Expand Up @@ -221,6 +237,14 @@ func TestMsgApplySignupRefereeReward(t *testing.T) {

referrer := simapp.TestParamUsers["user3"].Address.String()

// dummy bet to pass at least one bet condition
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
receiverAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)

_, err := tApp.SubaccountKeeper.CreateSubaccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{
{
Amount: sdkmath.ZeroInt(),
Expand Down Expand Up @@ -314,6 +338,26 @@ func TestMsgApplySignupReferrerReward(t *testing.T) {
referee := simapp.TestParamUsers["user3"].Address.String()
referrer := simapp.TestParamUsers["user4"].Address.String()

// dummy bet to pass at least one bet condition
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
referrer,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
referee,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
receiverAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)

_, err := tApp.SubaccountKeeper.CreateSubaccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{
{
Amount: sdkmath.ZeroInt(),
Expand Down Expand Up @@ -453,6 +497,14 @@ func TestMsgApplySignupAffiliateReward(t *testing.T) {

leadGen := simapp.TestParamUsers["user3"].Address.String()

// dummy bet to pass at least one bet condition
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
receiverAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)

_, err := tApp.SubaccountKeeper.CreateSubaccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{
{
Amount: sdkmath.ZeroInt(),
Expand Down Expand Up @@ -546,6 +598,26 @@ func TestMsgApplySignupAffiliateeReward(t *testing.T) {
affiliatee := simapp.TestParamUsers["user3"].Address.String()
affiliator := simapp.TestParamUsers["user4"].Address.String()

// dummy bet to pass at least one bet condition
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
affiliatee,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
affiliator,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
receiverAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)

_, err := tApp.SubaccountKeeper.CreateSubaccount(ctx, receiverAddr, receiverAddr, []subaccounttypes.LockedBalance{
{
Amount: sdkmath.ZeroInt(),
Expand Down Expand Up @@ -845,6 +917,21 @@ func TestMsgApplySignupRewardSubaccount(t *testing.T) {
})
require.NoError(t, err)

noSubaccountAddr := sample.AccAddress()
// dummy bet to pass at least one bet condition
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
receiverAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)
tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
noSubaccountAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)

for _, tc := range []struct {
desc string
claims jwt.MapClaims
Expand Down Expand Up @@ -883,7 +970,7 @@ func TestMsgApplySignupRewardSubaccount(t *testing.T) {
"exp": time.Now().Add(time.Minute * 5).Unix(),
"iat": time.Now().Unix(),
"common": types.RewardPayloadCommon{
Receiver: sample.AccAddress(),
Receiver: noSubaccountAddr,
SourceUID: "source id",
Meta: "signup reward for sample user",
KycData: &sgetypes.KycDataPayload{
Expand Down Expand Up @@ -939,6 +1026,13 @@ func TestMsgApplySubaccountFunds(t *testing.T) {
promoter := simapp.TestParamUsers["user1"].Address.String()
receiverAddr := simapp.TestParamUsers["user2"].Address.String()

tApp.BetKeeper.SetBet(ctx, *bettypes.NewBet(
receiverAddr,
&bettypes.WagerProps{UID: uuid.NewString()},
&bettypes.BetOdds{},
bettypes.MetaData{},
), 1)

rewardAmount := int64(100)

campClaims := getDefaultClaim(promoter)
Expand Down
1 change: 1 addition & 0 deletions x/reward/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ var (
ErrDuplicateCategoryInConf = sdkerrors.Register(ModuleName, 7130, "duplicate category in promoter configurations")
ErrCategoryCapShouldBePos = sdkerrors.Register(ModuleName, 7131, "category cap should be a positive number")
ErrMissingConstraintForCampaign = sdkerrors.Register(ModuleName, 7132, "missing constraints in the campaign")
ErrNoBetForReceiverFound = sdkerrors.Register(ModuleName, 7133, "reward receiver should have at least one wager")
)
1 change: 1 addition & 0 deletions x/reward/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type BankKeeper interface {
type BetKeeper interface {
GetBet(ctx sdk.Context, creator string, id uint64) (val bettypes.Bet, found bool)
GetBetID(ctx sdk.Context, uid string) (val bettypes.UID2ID, found bool)
IsAnyBetForAccount(ctx sdk.Context, creator string) (thereIs bool, err error)
}

// BetKeeper defines the expected interface needed to access market state.
Expand Down
8 changes: 8 additions & 0 deletions x/reward/types/reward_signup.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ func (sur SignUpReward) Calculate(goCtx context.Context, ctx sdk.Context, keeper
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err)
}

hasBet, err := keepers.BetKeeper.IsAnyBetForAccount(ctx, payload.Common.Receiver)
if err != nil {
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrPanic, "%s", err)
}
if !hasBet {
return RewardFactoryData{}, ErrNoBetForReceiverFound
}

return NewRewardFactoryData(
NewReceiver(
payload.Common.Receiver,
Expand Down
8 changes: 8 additions & 0 deletions x/reward/types/reward_signup_affiliatee.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ func (sur SignUpAffiliateeReward) Calculate(goCtx context.Context, ctx sdk.Conte
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err)
}

hasBet, err := keepers.BetKeeper.IsAnyBetForAccount(ctx, payload.Common.Receiver)
if err != nil {
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrPanic, "%s", err)
}
if !hasBet {
return RewardFactoryData{}, ErrNoBetForReceiverFound
}

return NewRewardFactoryData(
NewReceiver(
payload.Common.Receiver,
Expand Down
8 changes: 8 additions & 0 deletions x/reward/types/reward_signup_affiliator.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ func (sur SignUpAffiliatorReward) Calculate(goCtx context.Context, ctx sdk.Conte
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err)
}

hasBet, err := keepers.BetKeeper.IsAnyBetForAccount(ctx, payload.Common.Receiver)
if err != nil {
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrPanic, "%s", err)
}
if !hasBet {
return RewardFactoryData{}, ErrNoBetForReceiverFound
}

return NewRewardFactoryData(
NewReceiver(
payload.Common.Receiver,
Expand Down
8 changes: 8 additions & 0 deletions x/reward/types/reward_signup_referee.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ func (sur SignUpRefereelReward) Calculate(goCtx context.Context, ctx sdk.Context
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err)
}

hasBet, err := keepers.BetKeeper.IsAnyBetForAccount(ctx, payload.Common.Receiver)
if err != nil {
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrPanic, "%s", err)
}
if !hasBet {
return RewardFactoryData{}, ErrNoBetForReceiverFound
}

return NewRewardFactoryData(
NewReceiver(
payload.Common.Receiver,
Expand Down
8 changes: 8 additions & 0 deletions x/reward/types/reward_signup_referrer.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ func (sur SignUpReferrerReward) Calculate(goCtx context.Context, ctx sdk.Context
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidAddress, "%s", err)
}

hasBet, err := keepers.BetKeeper.IsAnyBetForAccount(ctx, payload.Common.Receiver)
if err != nil {
return RewardFactoryData{}, sdkerrors.Wrapf(sdkerrtypes.ErrPanic, "%s", err)
}
if !hasBet {
return RewardFactoryData{}, ErrNoBetForReceiverFound
}

return NewRewardFactoryData(
NewReceiver(
payload.Common.Receiver,
Expand Down

0 comments on commit 6536cdc

Please sign in to comment.