diff --git a/testutil/keeper/arkeo.go b/testutil/keeper/arkeo.go index b4fccf2a..33ea51c2 100644 --- a/testutil/keeper/arkeo.go +++ b/testutil/keeper/arkeo.go @@ -80,6 +80,7 @@ func ArkeoKeeper(t testing.TB) (cosmos.Context, keeper.Keeper) { stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, types.ModuleName: {authtypes.Minter, authtypes.Burner}, + types.ReserveName: {authtypes.Minter, authtypes.Burner}, types.ProviderName: {}, types.ContractName: {}, minttypes.ModuleName: {authtypes.Minter}, diff --git a/testutil/keeper/claim.go b/testutil/keeper/claim.go index 0ba2044b..98c1cfce 100644 --- a/testutil/keeper/claim.go +++ b/testutil/keeper/claim.go @@ -105,6 +105,7 @@ func CreateTestClaimKeepers(t testing.TB) (TestKeepers, sdk.Context) { stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, types.ModuleName: {authtypes.Minter}, + arkeotypes.ReserveName: {authtypes.Minter}, arkeotypes.ProviderName: {}, arkeotypes.ContractName: {}, }, diff --git a/x/arkeo/keeper/keeper.go b/x/arkeo/keeper/keeper.go index cf465e41..bb9fbdb4 100644 --- a/x/arkeo/keeper/keeper.go +++ b/x/arkeo/keeper/keeper.go @@ -8,16 +8,13 @@ import ( "cosmossdk.io/errors" "cosmossdk.io/log" "cosmossdk.io/math" - sdkmath "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" - disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" minttypes "github.com/cosmos/cosmos-sdk/x/mint/keeper" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper" @@ -66,10 +63,6 @@ type Keeper interface { GetActiveValidators(ctx cosmos.Context) ([]stakingtypes.Validator, error) GetAccount(ctx cosmos.Context, addr cosmos.AccAddress) cosmos.Account StakingSetParams(ctx cosmos.Context, params stakingtypes.Params) error - MintAndDistributeTokens(ctx cosmos.Context, newlyMinted sdk.DecCoin) (sdk.DecCoin, error) - GetCirculatingSupply(ctx cosmos.Context, denom string) (sdk.DecCoin, error) - GetInflationRate(ctx cosmos.Context) (math.LegacyDec, error) - MoveTokensFromDistributionToFoundationPoolAccount(ctx cosmos.Context) error AllocateTokensToValidator(ctx context.Context, val stakingtypes.ValidatorI, tokens sdk.DecCoins) error SendToCommunityPool(ctx context.Context, amount sdk.Coins, sender sdk.AccAddress) error @@ -385,172 +378,6 @@ func (k KVStore) GetAuthority() string { return k.authority } -func (k KVStore) GetCirculatingSupply(ctx cosmos.Context, denom string) (sdk.DecCoin, error) { - // Get Total Supply - fullTokenSupply, err := k.coinKeeper.SupplyOf(ctx, &banktypes.QuerySupplyOfRequest{Denom: configs.Denom}) - if err != nil { - k.Logger().Error("Failed to get full token supply data", err) - return sdk.NewDecCoin(denom, sdkmath.NewInt(0)), err - } - totalSupply := fullTokenSupply.GetAmount().Amount - - k.Logger().Info(fmt.Sprintf("TotalSupply %v", totalSupply)) - - // Get the account addresses whose balances need to be exempted - devAccountAddress, err := k.getFoundationDevAccountAddress() - if err != nil { - return sdk.NewDecCoin(denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) - } - - communityAccountAddress, err := k.getFoundationCommunityAccountAddress() - if err != nil { - return sdk.NewDecCoin(denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) - } - - grantAccountAddress, err := k.getFoundationGrantsAccountAddress() - if err != nil { - return sdk.NewDecCoin(denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) - } - - k.Logger().Info(fmt.Sprintf("Community address :%s", k.GetModuleAccAddress(disttypes.ModuleName))) - - // Account Address for which the circulating supply should be exempted - addressToExempt := []sdk.AccAddress{ - devAccountAddress, - communityAccountAddress, - grantAccountAddress, - k.stakingKeeper.GetBondedPool(ctx).GetAddress(), - k.GetModuleAccAddress("claimarkeo"), - k.GetModuleAccAddress(types.ModuleName), - } - - exemptBalance := cosmos.NewInt(0) - - k.Logger().Info("Starting to calculate exempt balances") - - // Range over the module accounts to create exempt balances - for _, address := range addressToExempt { - moduleBalance := k.coinKeeper.GetBalance(ctx, address, denom) - k.Logger().Info(fmt.Sprintf("Module address: %v, Balance: %v %v", address.String(), moduleBalance.Amount, denom)) - - if !moduleBalance.IsZero() { - exemptBalance = exemptBalance.Add(moduleBalance.Amount) - } else { - k.Logger().Info(fmt.Sprintf("Module address: %v has zero balance for denom: %v", address.String(), denom)) - } - } - - circulatingSupply := totalSupply.Sub(exemptBalance) - k.Logger().Info(fmt.Sprintf("TotalSupply=%v Foundation Accounts Exempted Balance=%v, Circulating Supply=%v", totalSupply, exemptBalance, circulatingSupply)) - - return sdk.NewDecCoin(denom, circulatingSupply), nil -} - -func (k KVStore) MintAndDistributeTokens(ctx cosmos.Context, newlyMinted sdk.DecCoin) (sdk.DecCoin, error) { - params := k.GetParams(ctx) - newlyMintedAmount := newlyMinted.Amount - - devFundAmount := newlyMintedAmount.Mul(params.DevFundPercentage) - communityPoolAmount := newlyMintedAmount.Mul(params.CommunityPoolPercentage) - grantFundAmount := newlyMintedAmount.Mul(params.GrantFundPercentage) - - devAccountAddress, err := k.getFoundationDevAccountAddress() - if err != nil { - k.Logger().Error(fmt.Sprintf("failed to fetch foundational account %s", err)) - return sdk.NewDecCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) - } - - communityAccountAddress, err := k.getFoundationCommunityAccountAddress() - if err != nil { - k.Logger().Error(fmt.Sprintf("failed to fetch foundational account %s", err)) - return sdk.NewDecCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) - } - - grantAccountAddress, err := k.getFoundationGrantsAccountAddress() - if err != nil { - k.Logger().Error(fmt.Sprintf("failed to fetch foundational account %s", err)) - return sdk.NewDecCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("failed to fetch foundational account %s", err) - } - - if !devFundAmount.IsZero() { - if err := k.MintAndSendToAccount(ctx, devAccountAddress, cosmos.NewCoin(newlyMinted.Denom, devFundAmount.RoundInt())); err != nil { - k.Logger().Error(fmt.Sprintf("failed to send amount to Dev foundational account %s", err)) - return sdk.NewDecCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("error sending amount to module %s", err) - } - } - - if !communityPoolAmount.IsZero() { - if err := k.MintAndSendToAccount(ctx, communityAccountAddress, cosmos.NewCoin(newlyMinted.Denom, communityPoolAmount.RoundInt())); err != nil { - k.Logger().Error(fmt.Sprintf("failed to send amount to Community foundational account %s", err)) - return sdk.NewDecCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("error sending amount to module %s", err) - } - } - - if !grantFundAmount.IsZero() { - if err := k.MintAndSendToAccount(ctx, grantAccountAddress, cosmos.NewCoin(newlyMinted.Denom, grantFundAmount.RoundInt())); err != nil { - k.Logger().Error(fmt.Sprintf("failed to send amount to Grant foundational account %s", err)) - return sdk.NewDecCoin(newlyMinted.Denom, sdkmath.NewInt(0)), fmt.Errorf("error sending amount to module %s", err) - } - } - - balance := newlyMintedAmount.Sub(devFundAmount).Sub(communityPoolAmount).Sub(grantFundAmount) - return sdk.NewDecCoin(newlyMinted.Denom, balance.RoundInt()), nil -} - -func (k KVStore) GetInflationRate(ctx cosmos.Context) (math.LegacyDec, error) { - params := k.GetParams(ctx) - - bondedRatio, err := k.stakingKeeper.BondedRatio(ctx) - if err != nil { - ctx.Logger().Error(fmt.Sprintf("failed to get bonded ration %s", err.Error())) - return math.LegacyNewDec(0), err - } - - inflationRateChangePerYear := math.LegacyOneDec().Sub(bondedRatio.Quo(params.GoalBonded)).Mul(params.InflationChangePercentage) - - inflationRateChange := inflationRateChangePerYear.Quo(sdkmath.LegacyNewDec(int64(params.BlockPerYear))) - - inflationRate := inflation.Add(inflationRateChange) - - if inflationRate.GT(params.InflationMax) { - inflationRate = params.InflationMax - } - if inflation.LT(params.InflationMin) { - inflationRate = params.InflationMin - } - - return inflationRate, nil -} - -// transfer tokens form the Distribution to Foundation Community Pool -func (k KVStore) MoveTokensFromDistributionToFoundationPoolAccount(ctx cosmos.Context) error { - // get pool balance - pool, err := k.distributionKeeper.FeePool.Get(ctx) - if err != nil { - return err - } - amount := pool.CommunityPool.AmountOf(configs.Denom) - - communityAccountAddress, err := k.getFoundationCommunityAccountAddress() - if err != nil { - return fmt.Errorf("failed to fetch foundational account %s", err) - } - - if !amount.IsZero() { - if err := k.distributionKeeper.DistributeFromFeePool(ctx, cosmos.NewCoins(cosmos.NewCoin(configs.Denom, amount.RoundInt())), communityAccountAddress); err != nil { - if err.Error() == "community pool does not have sufficient coins to distribute" { - ctx.Logger().Info(fmt.Sprintf("%s", err)) - return nil - } else { - ctx.Logger().Error(fmt.Sprintf("failed to distribute from community pool %s", err)) - return err - } - } - } - - return nil -} - func (k KVStore) getFoundationDevAccountAddress() (cosmos.AccAddress, error) { return sdk.AccAddressFromBech32(types.FoundationDevAccount) } diff --git a/x/arkeo/keeper/keeper_test.go b/x/arkeo/keeper/keeper_test.go index 498e06f9..909b84e4 100644 --- a/x/arkeo/keeper/keeper_test.go +++ b/x/arkeo/keeper/keeper_test.go @@ -105,6 +105,7 @@ func SetupKeeper(t testing.TB) (cosmos.Context, Keeper) { stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, types.ModuleName: {authtypes.Minter, authtypes.Burner}, + types.ReserveName: {authtypes.Minter, authtypes.Burner}, types.ProviderName: {}, types.ContractName: {}, minttypes.ModuleName: {authtypes.Minter}, @@ -225,17 +226,15 @@ func SetupKeeperWithStaking(t testing.TB) (cosmos.Context, Keeper, stakingkeeper runtime.NewKVStoreService(keyAcc), authtypes.ProtoBaseAccount, map[string][]string{ - distrtypes.ModuleName: {authtypes.Minter}, - stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, - stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, - types.ModuleName: {authtypes.Minter, authtypes.Burner}, - types.ProviderName: {}, - types.ContractName: {}, - govtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, - types.FoundationDevAccount: {authtypes.Minter, authtypes.Burner}, - types.FoundationGrantsAccount: {authtypes.Minter, authtypes.Burner}, - types.FoundationCommunityAccount: {authtypes.Minter, authtypes.Burner}, - minttypes.ModuleName: {authtypes.Minter}, + distrtypes.ModuleName: {authtypes.Minter}, + stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, + stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking}, + types.ModuleName: {authtypes.Minter, authtypes.Burner}, + types.ReserveName: {authtypes.Minter, authtypes.Burner}, + types.ProviderName: {}, + types.ContractName: {}, + govtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + minttypes.ModuleName: {authtypes.Minter}, }, authcodec.NewBech32Codec(sdk.GetConfig().GetBech32AccountAddrPrefix()), sdk.Bech32PrefixAccAddr, diff --git a/x/arkeo/keeper/manager_test.go b/x/arkeo/keeper/manager_test.go index 06c1adbe..947664ed 100644 --- a/x/arkeo/keeper/manager_test.go +++ b/x/arkeo/keeper/manager_test.go @@ -5,8 +5,6 @@ import ( abci "github.com/cometbft/cometbft/abci/types" simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims" - sdk "github.com/cosmos/cosmos-sdk/types" - disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" @@ -289,22 +287,6 @@ func TestParamsRewardsPercentage(t *testing.T) { require.Equal(t, params.CommunityPoolPercentage, sdkmath.LegacyMustNewDecFromStr("0.100000000000000000")) } -func TestCommunityPoolDistributionToFoundationCommunityPool(t *testing.T) { - ctx, k, sk := SetupKeeperWithStaking(t) - mgr := NewManager(k, sk) - - require.NoError(t, k.MintToModule(ctx, disttypes.ModuleName, getCoin(common.Tokens(200000)))) - - err := mgr.keeper.MoveTokensFromDistributionToFoundationPoolAccount(ctx) - require.NoError(t, err) - - address, err := sdk.AccAddressFromBech32(types.FoundationCommunityAccount) - require.NoError(t, err) - - bal := mgr.keeper.GetBalance(ctx, address).AmountOf(configs.Denom) - - require.Equal(t, bal, sdkmath.NewInt(10000)) -} func TestBlockRewardCalculation(t *testing.T) { ctx, k, sk := SetupKeeperWithStaking(t) @@ -407,7 +389,7 @@ func TestValidatorPayouts(t *testing.T) { require.NoError(t, sk.SetDelegation(ctx, del3)) // Mint initial funds to the reserve - require.NoError(t, k.MintToModule(ctx, types.ModuleName, getCoin(common.Tokens(200000)))) + require.NoError(t, k.MintToModule(ctx, types.ReserveName, getCoin(common.Tokens(200000)))) ctx = ctx.WithBlockHeight(mgr.FetchConfig(ctx, configs.ValidatorPayoutCycle)) @@ -424,49 +406,31 @@ func TestValidatorPayouts(t *testing.T) { BlockIdFlag: 2, } } - balanceDistribution, err := mgr.keeper.MintAndDistributeTokens(ctx, blockReward) - if err != nil { - ctx.Logger().Error("unable to mint and distribute tokens", "error", err) - } - devAccountAddress, err := sdk.AccAddressFromBech32(types.FoundationDevAccount) - require.NoError(t, err) - grantAccountAddress, err := sdk.AccAddressFromBech32(types.FoundationGrantsAccount) - require.NoError(t, err) + moduleBalance := k.GetBalanceOfModule(ctx, types.ReserveName, configs.Denom) + require.Equal(t, moduleBalance.Int64(), int64(20000000000000)) - communityAccountAddress, err := sdk.AccAddressFromBech32(types.FoundationCommunityAccount) + reserveSupply, err := mgr.reserveSupply(ctx) require.NoError(t, err) - devAccountBal := k.GetBalance(ctx, devAccountAddress).AmountOf(configs.Denom) - require.Equal(t, devAccountBal, sdkmath.NewInt(400000)) - - grantAccountBal := k.GetBalance(ctx, grantAccountAddress).AmountOf(configs.Denom) - require.Equal(t, grantAccountBal, sdkmath.NewInt(0)) - - communityAccountBal := k.GetBalance(ctx, communityAccountAddress).AmountOf(configs.Denom) - require.Equal(t, communityAccountBal, sdkmath.NewInt(200000)) - - moduleBalance := k.GetBalanceOfModule(ctx, types.ModuleName, configs.Denom) - require.Equal(t, moduleBalance.Int64(), int64(20000000000000)) - - require.NoError(t, mgr.ValidatorPayout(ctx, votes, balanceDistribution)) + require.NoError(t, mgr.ValidatorPayout(ctx, votes, reserveSupply)) totalBal := cosmos.ZeroInt() // Check balances of validators 7 - checkBalance(ctx, t, k, acc1, configs.Denom, 164541, &totalBal) - checkBalance(ctx, t, k, acc2, configs.Denom, 328753, &totalBal) - checkBalance(ctx, t, k, acc3, configs.Denom, 819411, &totalBal) + checkBalance(ctx, t, k, acc1, configs.Denom, 2350588235294, &totalBal) + checkBalance(ctx, t, k, acc2, configs.Denom, 4696470588235, &totalBal) + checkBalance(ctx, t, k, acc3, configs.Denom, 11705882352941, &totalBal) // Check balances of delegates - checkBalance(ctx, t, k, delAcc1, configs.Denom, 16455, &totalBal) - checkBalance(ctx, t, k, delAcc2, configs.Denom, 32875, &totalBal) - checkBalance(ctx, t, k, delAcc3, configs.Denom, 32776, &totalBal) + checkBalance(ctx, t, k, delAcc1, configs.Denom, 235058823529, &totalBal) + checkBalance(ctx, t, k, delAcc2, configs.Denom, 469647058823, &totalBal) + checkBalance(ctx, t, k, delAcc3, configs.Denom, 468235294117, &totalBal) - require.Equal(t, totalBal.ToLegacyDec(), sdkmath.LegacyNewDec(1394811)) + require.Equal(t, totalBal.ToLegacyDec(), sdkmath.LegacyNewDec(19925882352939)) - moduleBalance = k.GetBalanceOfModule(ctx, types.ModuleName, configs.Denom) - require.Equal(t, moduleBalance.ToLegacyDec().RoundInt64(), int64(20000000000000)) + moduleBalance = k.GetBalanceOfModule(ctx, types.ReserveName, configs.Denom) + require.Equal(t, moduleBalance.ToLegacyDec().RoundInt64(), int64(0)) } func checkBalance(ctx cosmos.Context, t *testing.T, k Keeper, acc cosmos.AccAddress, denom string, expectedAmt int64, total *sdkmath.Int) { bal := k.GetBalance(ctx, acc)