Skip to content

Commit

Permalink
Merge pull request #135 from hallazzang/134-allocate-all-balances
Browse files Browse the repository at this point in the history
fix: Fix comparison bug when allocating all balances of the farming pool
  • Loading branch information
dongsam authored Sep 24, 2021
2 parents c73ffe5 + a3b073c commit cc2de5e
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 3 deletions.
26 changes: 24 additions & 2 deletions x/farming/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ func (suite *KeeperTestSuite) AdvanceEpoch() {
suite.Require().NoError(err)
}

func (suite *KeeperTestSuite) SetFixedAmountPlan(id uint64, farmingPoolAcc sdk.AccAddress, stakingCoinWeighsMap map[string]string, epochAmountMap map[string]int64) {
func (suite *KeeperTestSuite) SetFixedAmountPlan(id uint64, farmingPoolAcc sdk.AccAddress, stakingCoinWeightsMap map[string]string, epochAmountMap map[string]int64) {
stakingCoinWeights := sdk.NewDecCoins()
for denom, weight := range stakingCoinWeighsMap {
for denom, weight := range stakingCoinWeightsMap {
stakingCoinWeights = stakingCoinWeights.Add(sdk.NewDecCoinFromDec(denom, sdk.MustNewDecFromStr(weight)))
}

Expand All @@ -175,6 +175,28 @@ func (suite *KeeperTestSuite) SetFixedAmountPlan(id uint64, farmingPoolAcc sdk.A
))
}

func (suite *KeeperTestSuite) SetRatioPlan(id uint64, farmingPoolAcc sdk.AccAddress, stakingCoinWeightsMap map[string]string, epochRatioStr string) {
stakingCoinWeights := sdk.NewDecCoins()
for denom, weight := range stakingCoinWeightsMap {
stakingCoinWeights = stakingCoinWeights.Add(sdk.NewDecCoinFromDec(denom, sdk.MustNewDecFromStr(weight)))
}

epochRatio := sdk.MustNewDecFromStr(epochRatioStr)

suite.keeper.SetPlan(suite.ctx, types.NewRatioPlan(
types.NewBasePlan(
id,
fmt.Sprintf("plan%d", id),
types.PlanTypePublic,
farmingPoolAcc.String(),
farmingPoolAcc.String(),
stakingCoinWeights,
types.ParseTime("0001-01-01T00:00:00Z"),
types.ParseTime("9999-12-31T00:00:00Z"),
), epochRatio,
))
}

func intEq(exp, got sdk.Int) (bool, string, string, string) {
return exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String()
}
Expand Down
2 changes: 1 addition & 1 deletion x/farming/keeper/reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ func (k Keeper) AllocationInfos(ctx sdk.Context) []AllocationInfo {
}

balances := farmingPoolBalances[farmingPool]
if !totalCoins.IsAllLT(balances) {
if !totalCoins.IsAllLTE(balances) {
continue
}

Expand Down
74 changes: 74 additions & 0 deletions x/farming/keeper/reward_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"

simapp "github.com/tendermint/farming/app"
"github.com/tendermint/farming/x/farming/types"

_ "github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -172,6 +173,79 @@ func (suite *KeeperTestSuite) TestAllocateRewards() {
}
}

func (suite *KeeperTestSuite) TestAllocateRewards_FixedAmountPlanAllBalances() {
farmingPoolAcc := simapp.AddTestAddrs(suite.app, suite.ctx, 1, sdk.ZeroInt())[0]
err := simapp.FundAccount(suite.app.BankKeeper, suite.ctx, farmingPoolAcc, sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000000)))
suite.Require().NoError(err)

// The sum of epoch ratios is exactly 1.
suite.SetFixedAmountPlan(1, farmingPoolAcc, map[string]string{denom1: "1.0"}, map[string]int64{denom3: 600000})
suite.SetFixedAmountPlan(2, farmingPoolAcc, map[string]string{denom2: "1.0"}, map[string]int64{denom3: 400000})

suite.Stake(suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 1000000), sdk.NewInt64Coin(denom2, 1000000)))

suite.AdvanceEpoch()
suite.AdvanceEpoch()

rewards := suite.Rewards(suite.addrs[0])
suite.Require().True(coinsEq(sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000000)), rewards))
}

func (suite *KeeperTestSuite) TestAllocateRewards_RatioPlanAllBalances() {
farmingPoolAcc := simapp.AddTestAddrs(suite.app, suite.ctx, 1, sdk.ZeroInt())[0]
err := simapp.FundAccount(suite.app.BankKeeper, suite.ctx, farmingPoolAcc, sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000000)))
suite.Require().NoError(err)

// The sum of epoch ratios is exactly 1.
suite.SetRatioPlan(1, farmingPoolAcc, map[string]string{denom1: "1.0"}, "0.5")
suite.SetRatioPlan(2, farmingPoolAcc, map[string]string{denom2: "1.0"}, "0.5")

suite.Stake(suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 1000000), sdk.NewInt64Coin(denom2, 1000000)))

suite.AdvanceEpoch()
suite.AdvanceEpoch()

rewards := suite.Rewards(suite.addrs[0])
suite.Require().True(coinsEq(sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000000)), rewards))
}

func (suite *KeeperTestSuite) TestAllocateRewards_FixedAmountPlanOverBalances() {
farmingPoolAcc := simapp.AddTestAddrs(suite.app, suite.ctx, 1, sdk.ZeroInt())[0]
err := simapp.FundAccount(suite.app.BankKeeper, suite.ctx, farmingPoolAcc, sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000000)))
suite.Require().NoError(err)

// The sum of epoch amounts is over the balances the farming pool has,
// so the reward allocation should never happen.
suite.SetFixedAmountPlan(1, farmingPoolAcc, map[string]string{denom1: "1.0"}, map[string]int64{denom3: 700000})
suite.SetFixedAmountPlan(2, farmingPoolAcc, map[string]string{denom2: "1.0"}, map[string]int64{denom3: 400000})

suite.Stake(suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 1000000), sdk.NewInt64Coin(denom2, 1000000)))

suite.AdvanceEpoch()
suite.AdvanceEpoch()

rewards := suite.Rewards(suite.addrs[0])
suite.Require().True(rewards.IsZero())
}

func (suite *KeeperTestSuite) TestAllocateRewards_RatioPlanOverBalances() {
farmingPoolAcc := simapp.AddTestAddrs(suite.app, suite.ctx, 1, sdk.ZeroInt())[0]
err := simapp.FundAccount(suite.app.BankKeeper, suite.ctx, farmingPoolAcc, sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000000)))
suite.Require().NoError(err)

// The sum of epoch ratios is over 1, so the reward allocation should never happen.
suite.SetRatioPlan(1, farmingPoolAcc, map[string]string{denom1: "1.0"}, "0.8")
suite.SetRatioPlan(2, farmingPoolAcc, map[string]string{denom2: "1.0"}, "0.5")

suite.Stake(suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 1000000), sdk.NewInt64Coin(denom2, 1000000)))

suite.AdvanceEpoch()
suite.AdvanceEpoch()

rewards := suite.Rewards(suite.addrs[0])
suite.Require().True(rewards.IsZero())
}

func (suite *KeeperTestSuite) TestOutstandingRewards() {
// The block time here is not important, and has chosen randomly.
suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-09-01T00:00:00Z"))
Expand Down

0 comments on commit cc2de5e

Please sign in to comment.