package app import ( "fmt" sdkmath "cosmossdk.io/math" storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" ) const ( UpgradeName_Mainnet = "v0.25.0" UpgradeName_Testnet = "v0.25.0-alpha.0" UpgradeName_E2ETest = "v0.25.0-testing" ) var ( // KAVA to ukava - 6 decimals kavaConversionFactor = sdk.NewInt(1000_000) secondsPerYear = sdk.NewInt(365 * 24 * 60 * 60) // 10 Million KAVA per year in staking rewards, inflation disable time 2024-01-01T00:00:00 UTC // CommunityParams_Mainnet = communitytypes.NewParams( // time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC), // // before switchover // sdkmath.LegacyZeroDec(), // // after switchover - 10M KAVA to ukava per year / seconds per year // sdkmath.LegacyNewDec(10_000_000). // MulInt(kavaConversionFactor). // QuoInt(secondsPerYear), // ) // Testnet -- 15 Trillion KAVA per year in staking rewards, inflation disable time 2023-11-16T00:00:00 UTC // CommunityParams_Testnet = communitytypes.NewParams( // time.Date(2023, 11, 16, 0, 0, 0, 0, time.UTC), // // before switchover // sdkmath.LegacyZeroDec(), // // after switchover // sdkmath.LegacyNewDec(15_000_000). // MulInt64(1_000_000). // 15M * 1M = 15T // MulInt(kavaConversionFactor). // QuoInt(secondsPerYear), // ) // CommunityParams_E2E = communitytypes.NewParams( // time.Now().Add(10*time.Second).UTC(), // relative time for testing // sdkmath.LegacyNewDec(0), // stakingRewardsPerSecond // sdkmath.LegacyNewDec(1000), // upgradeTimeSetstakingRewardsPerSecond // ) // ValidatorMinimumCommission is the new 5% minimum commission rate for validators ValidatorMinimumCommission = sdk.NewDecWithPrec(5, 2) ) // RegisterUpgradeHandlers registers the upgrade handlers for the app. func (app App) RegisterUpgradeHandlers() { // app.upgradeKeeper.SetUpgradeHandler( // UpgradeName_Mainnet, // upgradeHandler(app, UpgradeName_Mainnet, CommunityParams_Mainnet), // ) // app.upgradeKeeper.SetUpgradeHandler( // UpgradeName_Testnet, // upgradeHandler(app, UpgradeName_Testnet, CommunityParams_Testnet), // ) // app.upgradeKeeper.SetUpgradeHandler( // UpgradeName_E2ETest, // upgradeHandler(app, UpgradeName_Testnet, CommunityParams_E2E), // ) upgradeInfo, err := app.upgradeKeeper.ReadUpgradeInfoFromDisk() if err != nil { panic(err) } doUpgrade := upgradeInfo.Name == UpgradeName_Mainnet || upgradeInfo.Name == UpgradeName_Testnet || upgradeInfo.Name == UpgradeName_E2ETest if doUpgrade && !app.upgradeKeeper.IsSkipHeight(upgradeInfo.Height) { storeUpgrades := storetypes.StoreUpgrades{ Added: []string{ // x/community added store // communitytypes.ModuleName, }, } // configure store loader that checks if version == upgradeHeight and applies store upgrades app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) } } // upgradeHandler returns an UpgradeHandler for the given upgrade parameters. func upgradeHandler( app App, name string, // communityParams communitytypes.Params, ) upgradetypes.UpgradeHandler { return func( ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap, ) (module.VersionMap, error) { app.Logger().Info(fmt.Sprintf("running %s upgrade handler", name)) toVM, err := app.mm.RunMigrations(ctx, app.configurator, fromVM) if err != nil { return toVM, err } // // Staking validator minimum commission // UpdateValidatorMinimumCommission(ctx, app) // // Community Params // // app.communityKeeper.SetParams(ctx, communityParams) // app.Logger().Info( // "initialized x/community params", // "UpgradeTimeDisableInflation", communityParams.UpgradeTimeDisableInflation, // "StakingRewardsPerSecond", communityParams.StakingRewardsPerSecond, // "UpgradeTimeSetStakingRewardsPerSecond", communityParams.UpgradeTimeSetStakingRewardsPerSecond, // ) // // Kavadist gov grant // // msgGrant, err := authz.NewMsgGrant( // app.accountKeeper.GetModuleAddress(kavadisttypes.ModuleName), // granter // app.accountKeeper.GetModuleAddress(govtypes.ModuleName), // grantee // authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktypes.MsgSend{})), // authorization // nil, // expiration // ) // if err != nil { // return toVM, err // } // _, err = app.authzKeeper.Grant(ctx, msgGrant) // if err != nil { // return toVM, err // } // app.Logger().Info("created gov grant for kavadist funds") // // Gov Quorum // govTallyParams := app.govKeeper.GetTallyParams(ctx) oldQuorum := govTallyParams.Quorum govTallyParams.Quorum = sdkmath.LegacyMustNewDecFromStr("0.2").String() app.govKeeper.SetTallyParams(ctx, govTallyParams) app.Logger().Info(fmt.Sprintf("updated tally quorum from %s to %s", oldQuorum, govTallyParams.Quorum)) // // Incentive Params // UpdateIncentiveParams(ctx, app) return toVM, nil } } // UpdateValidatorMinimumCommission updates the commission rate for all // validators to be at least the new min commission rate, and sets the minimum // commission rate in the staking params. func UpdateValidatorMinimumCommission( ctx sdk.Context, app App, ) { resultCount := make(map[stakingtypes.BondStatus]int) // Iterate over *all* validators including inactive app.stakingKeeper.IterateValidators( ctx, func(index int64, validator stakingtypes.ValidatorI) (stop bool) { // Skip if validator commission is already >= 5% if validator.GetCommission().GTE(ValidatorMinimumCommission) { return false } val, ok := validator.(stakingtypes.Validator) if !ok { panic("expected stakingtypes.Validator") } // Set minimum commission rate to 5%, when commission is < 5% val.Commission.Rate = ValidatorMinimumCommission val.Commission.UpdateTime = ctx.BlockTime() // Update MaxRate if necessary if val.Commission.MaxRate.LT(ValidatorMinimumCommission) { val.Commission.MaxRate = ValidatorMinimumCommission } if err := app.stakingKeeper.BeforeValidatorModified(ctx, val.GetOperator()); err != nil { panic(fmt.Sprintf("failed to call BeforeValidatorModified: %s", err)) } app.stakingKeeper.SetValidator(ctx, val) // Keep track of counts just for logging purposes switch val.GetStatus() { case stakingtypes.Bonded: resultCount[stakingtypes.Bonded]++ case stakingtypes.Unbonded: resultCount[stakingtypes.Unbonded]++ case stakingtypes.Unbonding: resultCount[stakingtypes.Unbonding]++ } return false }, ) app.Logger().Info( "updated validator minimum commission rate for all existing validators", stakingtypes.BondStatusBonded, resultCount[stakingtypes.Bonded], stakingtypes.BondStatusUnbonded, resultCount[stakingtypes.Unbonded], stakingtypes.BondStatusUnbonding, resultCount[stakingtypes.Unbonding], ) stakingParams := app.stakingKeeper.GetParams(ctx) stakingParams.MinCommissionRate = ValidatorMinimumCommission app.stakingKeeper.SetParams(ctx, stakingParams) app.Logger().Info( "updated x/staking params minimum commission rate", "MinCommissionRate", stakingParams.MinCommissionRate, ) } // UpdateIncentiveParams modifies the earn rewards period for bkava to be 600K KAVA per year. func UpdateIncentiveParams( ctx sdk.Context, app App, ) { // incentiveParams := app.incentiveKeeper.GetParams(ctx) // bkava annualized rewards: 600K KAVA // newAmount := sdkmath.LegacyNewDec(600_000). // MulInt(kavaConversionFactor). // QuoInt(secondsPerYear). // TruncateInt() // for i := range incentiveParams.EarnRewardPeriods { // if incentiveParams.EarnRewardPeriods[i].CollateralType != "bkava" { // continue // } // // Update rewards per second via index // incentiveParams.EarnRewardPeriods[i].RewardsPerSecond = sdk.NewCoins( // sdk.NewCoin("ukava", newAmount), // ) // } // app.incentiveKeeper.SetParams(ctx, incentiveParams) }