cosmos-sdk/tests/integration/v2/protocolpool/module_test.go

179 lines
6.2 KiB
Go

package protocolpool
import (
"math/rand"
"testing"
"time"
"github.com/stretchr/testify/require"
"cosmossdk.io/depinject"
"cosmossdk.io/log"
"cosmossdk.io/math"
_ "cosmossdk.io/x/accounts" // import as blank for app wiring
_ "cosmossdk.io/x/bank" // import as blank for app wiring
bankkeeper "cosmossdk.io/x/bank/keeper"
_ "cosmossdk.io/x/consensus" // import as blank for app wiring
_ "cosmossdk.io/x/distribution" // import as blank for app wiring
_ "cosmossdk.io/x/mint" // import as blank for app wiring
"cosmossdk.io/x/mint/types"
_ "cosmossdk.io/x/protocolpool" // import as blank for app wiring
protocolpoolkeeper "cosmossdk.io/x/protocolpool/keeper"
protocolpooltypes "cosmossdk.io/x/protocolpool/types"
_ "cosmossdk.io/x/staking" // import as blank for app wiring
stakingkeeper "cosmossdk.io/x/staking/keeper"
"github.com/cosmos/cosmos-sdk/tests/integration/v2"
"github.com/cosmos/cosmos-sdk/testutil/configurator"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
_ "github.com/cosmos/cosmos-sdk/x/auth" // import as blank for app wiring
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import as blank for app wiring
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
_ "github.com/cosmos/cosmos-sdk/x/genutil" // import as blank for app wiring
)
var moduleConfigs = []configurator.ModuleOption{
configurator.AccountsModule(),
configurator.AuthModule(),
configurator.BankModule(),
configurator.StakingModule(),
configurator.TxModule(),
configurator.ValidateModule(),
configurator.ConsensusModule(),
configurator.GenutilModule(),
configurator.MintModule(),
configurator.DistributionModule(),
configurator.ProtocolPoolModule(),
}
type fixture struct {
accountKeeper authkeeper.AccountKeeper
protocolpoolKeeper protocolpoolkeeper.Keeper
bankKeeper bankkeeper.Keeper
stakingKeeper *stakingkeeper.Keeper
}
// TestWithdrawAnytime tests if withdrawing funds many times vs withdrawing funds once
// yield the same end balance.
func TestWithdrawAnytime(t *testing.T) {
res := fixture{}
startupCfg := integration.DefaultStartUpConfig(t)
startupCfg.HeaderService = &integration.HeaderService{}
app, err := integration.NewApp(
depinject.Configs(configurator.NewAppV2Config(moduleConfigs...), depinject.Supply(log.NewNopLogger())),
startupCfg, &res.accountKeeper, &res.protocolpoolKeeper, &res.bankKeeper, &res.stakingKeeper)
require.NoError(t, err)
ctx := app.StateLatestContext(t)
acc := res.accountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName))
require.NotNil(t, acc)
testAddrs := simtestutil.AddTestAddrs(res.bankKeeper, res.stakingKeeper, ctx, 5, math.NewInt(1))
testAddr0Str, err := res.accountKeeper.AddressCodec().BytesToString(testAddrs[0])
require.NoError(t, err)
msgServer := protocolpoolkeeper.NewMsgServerImpl(res.protocolpoolKeeper)
_, err = msgServer.CreateContinuousFund(
ctx,
&protocolpooltypes.MsgCreateContinuousFund{
Authority: res.protocolpoolKeeper.GetAuthority(),
Recipient: testAddr0Str,
Percentage: math.LegacyMustNewDecFromStr("0.5"),
},
)
require.NoError(t, err)
// increase the community pool by a bunch
for i := 0; i < 30; i++ {
_, state := app.Deliver(t, ctx, nil)
_, err = app.Commit(state)
require.NoError(t, err)
headerInfo := integration.HeaderInfoFromContext(ctx)
headerInfo.Time = headerInfo.Time.Add(time.Minute)
ctx = integration.SetHeaderInfo(ctx, headerInfo)
// withdraw funds randomly, but it must always land on the same end balance
if rand.Intn(100) > 50 {
_, err = msgServer.WithdrawContinuousFund(ctx, &protocolpooltypes.MsgWithdrawContinuousFund{
RecipientAddress: testAddr0Str,
})
require.NoError(t, err)
}
}
pool, err := res.protocolpoolKeeper.GetCommunityPool(ctx)
require.NoError(t, err)
require.True(t, pool.IsAllGT(sdk.NewCoins(sdk.NewInt64Coin("stake", 100000))))
_, err = msgServer.WithdrawContinuousFund(ctx, &protocolpooltypes.MsgWithdrawContinuousFund{
RecipientAddress: testAddr0Str,
})
require.NoError(t, err)
endBalance := res.bankKeeper.GetBalance(ctx, testAddrs[0], sdk.DefaultBondDenom)
require.Equal(t, "11883031stake", endBalance.String())
}
// TestExpireInTheMiddle tests if a continuous fund that expires without anyone
// calling the withdraw function, the funds are still distributed correctly.
func TestExpireInTheMiddle(t *testing.T) {
res := fixture{}
startupCfg := integration.DefaultStartUpConfig(t)
startupCfg.HeaderService = &integration.HeaderService{}
app, err := integration.NewApp(
depinject.Configs(configurator.NewAppV2Config(moduleConfigs...), depinject.Supply(log.NewNopLogger())),
startupCfg, &res.accountKeeper, &res.protocolpoolKeeper, &res.bankKeeper, &res.stakingKeeper)
require.NoError(t, err)
ctx := app.StateLatestContext(t)
acc := res.accountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.ModuleName))
require.NotNil(t, acc)
testAddrs := simtestutil.AddTestAddrs(res.bankKeeper, res.stakingKeeper, ctx, 5, math.NewInt(1))
testAddr0Str, err := res.accountKeeper.AddressCodec().BytesToString(testAddrs[0])
require.NoError(t, err)
msgServer := protocolpoolkeeper.NewMsgServerImpl(res.protocolpoolKeeper)
headerInfo := integration.HeaderInfoFromContext(ctx)
expirationTime := headerInfo.Time.Add(time.Minute * 2)
_, err = msgServer.CreateContinuousFund(
ctx,
&protocolpooltypes.MsgCreateContinuousFund{
Authority: res.protocolpoolKeeper.GetAuthority(),
Recipient: testAddr0Str,
Percentage: math.LegacyMustNewDecFromStr("0.1"),
Expiry: &expirationTime,
},
)
require.NoError(t, err)
// increase the community pool by a bunch
for i := 0; i < 30; i++ {
_, state := app.Deliver(t, ctx, nil)
_, err = app.Commit(state)
require.NoError(t, err)
headerInfo := integration.HeaderInfoFromContext(ctx)
headerInfo.Time = headerInfo.Time.Add(time.Minute)
ctx = integration.SetHeaderInfo(ctx, headerInfo)
require.NoError(t, err)
}
_, err = msgServer.WithdrawContinuousFund(ctx, &protocolpooltypes.MsgWithdrawContinuousFund{
RecipientAddress: testAddr0Str,
})
require.NoError(t, err)
endBalance := res.bankKeeper.GetBalance(ctx, testAddrs[0], sdk.DefaultBondDenom)
require.Equal(t, "237661stake", endBalance.String())
}