Unverified Commit a54777b5 authored by Adam Tucker's avatar Adam Tucker Committed by GitHub
Browse files

feat(incentives): create gauge and add to gauge fee charge (backport #2227) (#2237)

* feat(incentives)!: create gauge and add to gauge fee charge (#2227)

* feat(incentives)!: create gauge and add to gauge fee charge

* initialize txfees keeper before incentives

* finish TestChargeFee

* refactor to charge fee in message server

* more tests

* clean up

* test balances

* test create gauge fees (#2228)

* test create gauge fees

* add mod account to test

* test create gauge fees

* add mod account to test

* move to msg server

* merge

* add comments

* account keeper comment

* fix TestCreateGaugeFee

* apply appparams.BaseCoinUnit

* remove txfees keeper from incentives and revert order

* clean up

* remove unused keepers fromm incentives keeper

* Update x/incentives/keeper/gauge.go

* Update x/incentives/keeper/gauge.go

* clean up

* fixture names

* chargeFeeIfSufficientFeeDenomBalance test name

* changelog

* comment

* finished tests ...
parent 487f2e0c
Showing with 399 additions and 7 deletions
+399 -7
......@@ -279,6 +279,7 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
appKeepers.BankKeeper,
appKeepers.LockupKeeper,
appKeepers.EpochsKeeper,
appKeepers.DistrKeeper,
)
appKeepers.SuperfluidKeeper = superfluidkeeper.NewKeeper(
......
......@@ -4,6 +4,8 @@ go 1.18
require (
github.com/CosmWasm/wasmd v0.24.0
github.com/CosmWasm/wasmvm v1.0.0
github.com/cosmos/btcutil v1.0.4
github.com/cosmos/cosmos-sdk v0.45.6
github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/iavl v0.17.3
......@@ -41,7 +43,6 @@ require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/BurntSushi/toml v1.1.0 // indirect
github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect
github.com/CosmWasm/wasmvm v1.0.0
github.com/DataDog/zstd v1.4.5 // indirect
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.1.0 // indirect
......@@ -71,7 +72,6 @@ require (
github.com/coinbase/rosetta-sdk-go v0.7.0 // indirect
github.com/confio/ics23/go v0.7.0 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/cosmos/btcutil v1.0.4 // indirect
github.com/cosmos/gorocksdb v1.2.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect
github.com/cosmos/ledger-go v0.9.2 // indirect
......
......@@ -6,8 +6,9 @@ import (
"github.com/osmosis-labs/osmosis/v10/x/incentives/types"
)
func (k Keeper) AddGaugeRefByKey(ctx sdk.Context, key []byte, guageID uint64) error {
return k.addGaugeRefByKey(ctx, key, guageID)
// AddGaugeRefByKey appends the provided gauge ID into an array associated with the provided key.
func (k Keeper) AddGaugeRefByKey(ctx sdk.Context, key []byte, gaugeID uint64) error {
return k.addGaugeRefByKey(ctx, key, gaugeID)
}
func (k Keeper) DeleteGaugeRefByKey(ctx sdk.Context, key []byte, guageID uint64) error {
......@@ -29,3 +30,8 @@ func (k Keeper) MoveUpcomingGaugeToActiveGauge(ctx sdk.Context, gauge types.Gaug
func (k Keeper) MoveActiveGaugeToFinishedGauge(ctx sdk.Context, gauge types.Gauge) error {
return k.moveActiveGaugeToFinishedGauge(ctx, gauge)
}
// ChargeFeeIfSufficientFeeDenomBalance see chargeFeeIfSufficientFeeDenomBalance spec.
func (k Keeper) ChargeFeeIfSufficientFeeDenomBalance(ctx sdk.Context, address sdk.AccAddress, fee sdk.Int, gaugeCoins sdk.Coins) error {
return k.chargeFeeIfSufficientFeeDenomBalance(ctx, address, fee, gaugeCoins)
}
......@@ -6,9 +6,11 @@ import (
"strings"
"time"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/gogo/protobuf/proto"
db "github.com/tendermint/tm-db"
appparams "github.com/osmosis-labs/osmosis/v10/app/params"
epochtypes "github.com/osmosis-labs/osmosis/v10/x/epochs/types"
"github.com/osmosis-labs/osmosis/v10/x/incentives/types"
lockuptypes "github.com/osmosis-labs/osmosis/v10/x/lockup/types"
......@@ -281,3 +283,20 @@ func (k Keeper) GetEpochInfo(ctx sdk.Context) epochtypes.EpochInfo {
params := k.GetParams(ctx)
return k.ek.GetEpochInfo(ctx, params.DistrEpochIdentifier)
}
// chargeFeeIfSufficientFeeDenomBalance charges fee in the base denom on the address if the address has
// balance that is less than fee + amount of the coin from gaugeCoins that is of base denom.
// gaugeCoins might not have a coin of tx base denom. In that case, fee is only compared to balance.
// The fee is sent to the community pool.
// Returns nil on success, error otherwise.
func (k Keeper) chargeFeeIfSufficientFeeDenomBalance(ctx sdk.Context, address sdk.AccAddress, fee sdk.Int, gaugeCoins sdk.Coins) (err error) {
totalCost := gaugeCoins.AmountOf(appparams.BaseCoinUnit).Add(fee)
accountBalance := k.bk.GetBalance(ctx, address, appparams.BaseCoinUnit).Amount
if accountBalance.LT(totalCost) {
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, "account's balance of %s (%s) is less than the total cost of the message (%s)", appparams.BaseCoinUnit, accountBalance, totalCost)
}
if err := k.dk.FundCommunityPool(ctx, sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, fee)), address); err != nil {
return err
}
return nil
}
......@@ -3,6 +3,7 @@ package keeper_test
import (
"time"
appparams "github.com/osmosis-labs/osmosis/v10/app/params"
"github.com/osmosis-labs/osmosis/v10/x/incentives/types"
lockuptypes "github.com/osmosis-labs/osmosis/v10/x/lockup/types"
......@@ -310,3 +311,98 @@ func (suite *KeeperTestSuite) TestGaugesByDenom() {
testGaugeByDenom(true)
testGaugeByDenom(false)
}
func (suite *KeeperTestSuite) TestChargeFeeIfSufficientFeeDenomBalance() {
const baseFee = int64(100)
testcases := map[string]struct {
accountBalanceToFund sdk.Coin
feeToCharge int64
gaugeCoins sdk.Coins
expectError bool
}{
"fee + base denom gauge coin == acount balance, success": {
accountBalanceToFund: sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee)),
feeToCharge: baseFee / 2,
gaugeCoins: sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee/2))),
},
"fee + base denom gauge coin < acount balance, success": {
accountBalanceToFund: sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee)),
feeToCharge: baseFee/2 - 1,
gaugeCoins: sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee/2))),
},
"fee + base denom gauge coin > acount balance, error": {
accountBalanceToFund: sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(baseFee)),
feeToCharge: baseFee/2 + 1,
gaugeCoins: sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee/2))),
expectError: true,
},
"fee + base denom gauge coin < acount balance, custom values, success": {
accountBalanceToFund: sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(11793193112)),
feeToCharge: 55,
gaugeCoins: sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(328812))),
},
"account funded with coins other than base denom, error": {
accountBalanceToFund: sdk.NewCoin("usdc", sdk.NewInt(baseFee)),
feeToCharge: baseFee,
gaugeCoins: sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee/2))),
expectError: true,
},
"fee == account balance, no gauge coins, success": {
accountBalanceToFund: sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee)),
feeToCharge: baseFee,
},
"gauge coins == account balance, no fee, success": {
accountBalanceToFund: sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee)),
gaugeCoins: sdk.NewCoins(sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee))),
},
"fee == account balance, gauge coins in denom other than base, success": {
accountBalanceToFund: sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee)),
feeToCharge: baseFee,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(baseFee*2))),
},
"fee + gauge coins == account balance, multiple gauge coins, one in denom other than base, success": {
accountBalanceToFund: sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee)),
feeToCharge: baseFee / 2,
gaugeCoins: sdk.NewCoins(sdk.NewCoin("usdc", sdk.NewInt(baseFee*2)), sdk.NewCoin(appparams.DefaultBondDenom, sdk.NewInt(baseFee/2))),
},
}
for name, tc := range testcases {
suite.Run(name, func() {
suite.SetupTest()
testAccount := suite.TestAccs[0]
ctx := suite.Ctx
incentivesKeepers := suite.App.IncentivesKeeper
bankKeeper := suite.App.BankKeeper
// Pre-fund account.
suite.FundAcc(testAccount, sdk.NewCoins(tc.accountBalanceToFund))
oldBalanceAmount := bankKeeper.GetBalance(ctx, testAccount, appparams.DefaultBondDenom).Amount
// System under test.
err := incentivesKeepers.ChargeFeeIfSufficientFeeDenomBalance(ctx, testAccount, sdk.NewInt(tc.feeToCharge), tc.gaugeCoins)
// Assertions.
newBalanceAmount := bankKeeper.GetBalance(ctx, testAccount, appparams.DefaultBondDenom).Amount
if tc.expectError {
suite.Require().Error(err)
// check account balance unchanged
suite.Require().Equal(oldBalanceAmount, newBalanceAmount)
} else {
suite.Require().NoError(err)
// check account balance changed.
expectedNewBalanceAmount := oldBalanceAmount.Sub(sdk.NewInt(tc.feeToCharge))
suite.Require().Equal(expectedNewBalanceAmount.String(), newBalanceAmount.String())
}
})
}
}
......@@ -21,9 +21,11 @@ type Keeper struct {
bk types.BankKeeper
lk types.LockupKeeper
ek types.EpochKeeper
dk types.DistrKeeper
}
func NewKeeper(cdc codec.Codec, storeKey sdk.StoreKey, paramSpace paramtypes.Subspace, bk types.BankKeeper, lk types.LockupKeeper, ek types.EpochKeeper) *Keeper {
// NewKeeper returns a new instance of the incentive module keeper struct.
func NewKeeper(cdc codec.Codec, storeKey sdk.StoreKey, paramSpace paramtypes.Subspace, bk types.BankKeeper, lk types.LockupKeeper, ek types.EpochKeeper, dk types.DistrKeeper) *Keeper {
if !paramSpace.HasKeyTable() {
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
}
......@@ -35,6 +37,7 @@ func NewKeeper(cdc codec.Codec, storeKey sdk.StoreKey, paramSpace paramtypes.Sub
bk: bk,
lk: lk,
ek: ek,
dk: dk,
}
}
......
......@@ -30,6 +30,10 @@ func (server msgServer) CreateGauge(goCtx context.Context, msg *types.MsgCreateG
return nil, err
}
if err := server.keeper.chargeFeeIfSufficientFeeDenomBalance(ctx, owner, types.CreateGaugeFee, msg.Coins); err != nil {
return nil, err
}
gaugeID, err := server.keeper.CreateGauge(ctx, msg.IsPerpetual, owner, msg.Coins, msg.DistributeTo, msg.StartTime, msg.NumEpochsPaidOver)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
......@@ -51,6 +55,10 @@ func (server msgServer) AddToGauge(goCtx context.Context, msg *types.MsgAddToGau
if err != nil {
return nil, err
}
if err := server.keeper.chargeFeeIfSufficientFeeDenomBalance(ctx, owner, types.AddToGaugeFee, msg.Rewards); err != nil {
return nil, err
}
err = server.keeper.AddToGaugeRewards(ctx, owner, msg.Rewards, msg.GaugeId)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
......
package keeper_test
import (
"time"
"github.com/stretchr/testify/suite"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
appparams "github.com/osmosis-labs/osmosis/v10/app/params"
"github.com/osmosis-labs/osmosis/v10/x/incentives/keeper"
"github.com/osmosis-labs/osmosis/v10/x/incentives/types"
lockuptypes "github.com/osmosis-labs/osmosis/v10/x/lockup/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
var _ = suite.TestingSuite(nil)
func (suite *KeeperTestSuite) TestCreateGauge_Fee() {
tests := []struct {
name string
accountBalanceToFund sdk.Coins
gaugeAddition sdk.Coins
expectedEndBalance sdk.Coins
isPerpetual bool
isModuleAccount bool
expectErr bool
}{
{
name: "user creates a non-perpetual gauge and fills gauge with all remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(60000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
},
{
name: "user creates a non-perpetual gauge and fills gauge with some remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(70000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
},
{
name: "user with multiple denoms creates a non-perpetual gauge and fills gauge with some remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(70000000)), sdk.NewCoin("foo", sdk.NewInt(70000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
},
{
name: "module account creates a perpetual gauge and fills gauge with some remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(70000000)), sdk.NewCoin("foo", sdk.NewInt(70000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
isPerpetual: true,
isModuleAccount: true,
},
{
name: "user with multiple denoms creates a perpetual gauge and fills gauge with some remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(70000000)), sdk.NewCoin("foo", sdk.NewInt(70000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
isPerpetual: true,
},
{
name: "user tries to create a non-perpetual gauge but does not have enough funds to pay for the create gauge fee",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(40000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
expectErr: true,
},
{
name: "user tries to create a non-perpetual gauge but does not have the correct fee denom",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(60000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000000))),
expectErr: true,
},
{
name: "one user tries to create a gauge, has enough funds to pay for the create gauge fee but not enough to fill the gauge",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(60000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(30000000))),
expectErr: true,
},
}
for _, tc := range tests {
suite.SetupTest()
testAccountPubkey := secp256k1.GenPrivKeyFromSecret([]byte("acc")).PubKey()
testAccountAddress := sdk.AccAddress(testAccountPubkey.Address())
ctx := suite.Ctx
bankKeeper := suite.App.BankKeeper
accountKeeper := suite.App.AccountKeeper
msgServer := keeper.NewMsgServerImpl(suite.App.IncentivesKeeper)
suite.FundAcc(testAccountAddress, tc.accountBalanceToFund)
if tc.isModuleAccount {
modAcc := authtypes.NewModuleAccount(authtypes.NewBaseAccount(testAccountAddress, testAccountPubkey, 1, 0),
"module",
"permission",
)
accountKeeper.SetModuleAccount(ctx, modAcc)
}
suite.SetupManyLocks(1, defaultLiquidTokens, defaultLPTokens, defaultLockDuration)
distrTo := lockuptypes.QueryCondition{
LockQueryType: lockuptypes.ByDuration,
Denom: defaultLPDenom,
Duration: defaultLockDuration,
}
msg := &types.MsgCreateGauge{
IsPerpetual: tc.isPerpetual,
Owner: testAccountAddress.String(),
DistributeTo: distrTo,
Coins: tc.gaugeAddition,
StartTime: time.Now(),
NumEpochsPaidOver: 1,
}
// System under test.
_, err := msgServer.CreateGauge(sdk.WrapSDKContext(ctx), msg)
if tc.expectErr {
suite.Require().Error(err)
} else {
suite.Require().NoError(err)
}
balanceAmount := bankKeeper.GetAllBalances(ctx, testAccountAddress)
if tc.expectErr {
suite.Require().Equal(tc.accountBalanceToFund.String(), balanceAmount.String(), "test: %v", tc.name)
} else {
fee := sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, types.CreateGaugeFee))
accountBalance := tc.accountBalanceToFund.Sub(tc.gaugeAddition)
finalAccountBalance := accountBalance.Sub(fee)
suite.Require().Equal(finalAccountBalance.String(), balanceAmount.String(), "test: %v", tc.name)
}
}
}
func (suite *KeeperTestSuite) TestAddToGauge_Fee() {
tests := []struct {
name string
accountBalanceToFund sdk.Coins
gaugeAddition sdk.Coins
nonexistentGauge bool
isPerpetual bool
isModuleAccount bool
expectErr bool
}{
{
name: "user creates a non-perpetual gauge and fills gauge with all remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(35000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
},
{
name: "user creates a non-perpetual gauge and fills gauge with some remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(70000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
},
{
name: "user with multiple denoms creates a non-perpetual gauge and fills gauge with some remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(70000000)), sdk.NewCoin("foo", sdk.NewInt(70000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
},
{
name: "module account creates a perpetual gauge and fills gauge with some remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(70000000)), sdk.NewCoin("foo", sdk.NewInt(70000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
isPerpetual: true,
isModuleAccount: true,
},
{
name: "user with multiple denoms creates a perpetual gauge and fills gauge with some remaining tokens",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(70000000)), sdk.NewCoin("foo", sdk.NewInt(70000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
isPerpetual: true,
},
{
name: "user tries to create a non-perpetual gauge but does not have enough funds to pay for the create gauge fee",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(20000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(10000000))),
expectErr: true,
},
{
name: "user tries to add to a non-perpetual gauge but does not have the correct fee denom",
accountBalanceToFund: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(60000000))),
gaugeAddition: sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10000000))),
expectErr: true,
},
}
for _, tc := range tests {
suite.SetupTest()
testAccountPubkey := secp256k1.GenPrivKeyFromSecret([]byte("acc")).PubKey()
testAccountAddress := sdk.AccAddress(testAccountPubkey.Address())
ctx := suite.Ctx
bankKeeper := suite.App.BankKeeper
incentivesKeeper := suite.App.IncentivesKeeper
accountKeeper := suite.App.AccountKeeper
msgServer := keeper.NewMsgServerImpl(incentivesKeeper)
suite.FundAcc(testAccountAddress, tc.accountBalanceToFund)
if tc.isModuleAccount {
modAcc := authtypes.NewModuleAccount(authtypes.NewBaseAccount(testAccountAddress, testAccountPubkey, 1, 0),
"module",
"permission",
)
accountKeeper.SetModuleAccount(ctx, modAcc)
}
// System under test.
coins := sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(500000000)))
gaugeID, _, _, _ := suite.SetupNewGauge(true, coins)
if tc.nonexistentGauge {
gaugeID = incentivesKeeper.GetLastGaugeID(ctx) + 1
}
msg := &types.MsgAddToGauge{
Owner: testAccountAddress.String(),
GaugeId: gaugeID,
Rewards: tc.gaugeAddition,
}
_, err := msgServer.AddToGauge(sdk.WrapSDKContext(ctx), msg)
if tc.expectErr {
suite.Require().Error(err)
} else {
suite.Require().NoError(err)
}
bal := bankKeeper.GetAllBalances(ctx, testAccountAddress)
if tc.expectErr {
suite.Require().Equal(tc.accountBalanceToFund.String(), bal.String(), "test: %v", tc.name)
} else {
fee := sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, types.AddToGaugeFee))
accountBalance := tc.accountBalanceToFund.Sub(tc.gaugeAddition)
finalAccountBalance := accountBalance.Sub(fee)
suite.Require().Equal(finalAccountBalance.String(), bal.String(), "test: %v", tc.name)
}
}
}
......@@ -18,6 +18,8 @@ import (
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/simulation"
stakingTypes "github.com/cosmos/cosmos-sdk/x/staking/types"
appparams "github.com/osmosis-labs/osmosis/v10/app/params"
)
// Simulation operation weights constants.
......@@ -116,7 +118,7 @@ func SimulateMsgCreateGauge(ak stakingTypes.AccountKeeper, bk stakingTypes.BankK
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
simAccount, _ := simtypes.RandomAcc(r, accs)
simCoins := bk.SpendableCoins(ctx, simAccount.Address)
if simCoins.Len() <= 0 {
if simCoins.Len() <= 0 || simCoins.AmountOf(appparams.BaseCoinUnit).LT(types.CreateGaugeFee) {
return simtypes.NoOpMsg(
types.ModuleName, types.TypeMsgCreateGauge, "Account have no coin"), nil, nil
}
......@@ -154,7 +156,7 @@ func SimulateMsgAddToGauge(ak stakingTypes.AccountKeeper, bk stakingTypes.BankKe
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
simAccount, _ := simtypes.RandomAcc(r, accs)
simCoins := bk.SpendableCoins(ctx, simAccount.Address)
if simCoins.Len() <= 0 {
if simCoins.Len() <= 0 || simCoins.AmountOf(appparams.BaseCoinUnit).LT(types.AddToGaugeFee) {
return simtypes.NoOpMsg(
types.ModuleName, types.TypeMsgAddToGauge, "Account have no coin"), nil, nil
}
......
......@@ -12,6 +12,7 @@ import (
// BankKeeper defines the expected interface needed to retrieve account balances.
type BankKeeper interface {
GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
HasSupply(ctx sdk.Context, denom string) bool
......@@ -35,3 +36,8 @@ type LockupKeeper interface {
type EpochKeeper interface {
GetEpochInfo(ctx sdk.Context, identifier string) epochstypes.EpochInfo
}
// DistrKeeper defines the contract needed to be fulfilled for distribution keeper.
type DistrKeeper interface {
FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error
}
......@@ -8,6 +8,14 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
var (
// CreateGaugeFee is the fee required to create a new gauge.
CreateGaugeFee = sdk.NewInt(50 * 1_000_000)
// AddToGagugeFee is the fee required to add to gauge.
AddToGaugeFee = sdk.NewInt(25 * 1_000_000)
)
// NewGauge creates a new gauge struct given the required gauge parameters.
func NewGauge(id uint64, isPerpetual bool, distrTo lockuptypes.QueryCondition, coins sdk.Coins, startTime time.Time, numEpochsPaidOver uint64, filledEpochs uint64, distrCoins sdk.Coins) Gauge {
return Gauge{
Id: id,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment