Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ import (
v1_23 "github.com/scrtlabs/SecretNetwork/app/upgrades/v1.23"
v1_23_1 "github.com/scrtlabs/SecretNetwork/app/upgrades/v1.23.1"
v1_23_2 "github.com/scrtlabs/SecretNetwork/app/upgrades/v1.23.2"
v1_24 "github.com/scrtlabs/SecretNetwork/app/upgrades/v1.24"
v1_4 "github.com/scrtlabs/SecretNetwork/app/upgrades/v1.4"
v1_5 "github.com/scrtlabs/SecretNetwork/app/upgrades/v1.5"
v1_6 "github.com/scrtlabs/SecretNetwork/app/upgrades/v1.6"
Expand Down Expand Up @@ -154,6 +155,7 @@ var (
v1_23.Upgrade,
v1_23_1.Upgrade,
v1_23_2.Upgrade,
v1_24.Upgrade,
}
)

Expand Down
4 changes: 2 additions & 2 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import (
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/params"
mintkeeper "github.com/scrtlabs/SecretNetwork/x/mint/keeper"
minttypes "github.com/scrtlabs/SecretNetwork/x/mint/types"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
Expand Down
6 changes: 3 additions & 3 deletions app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import (
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/gov"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/mint"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/params"
"github.com/scrtlabs/SecretNetwork/x/mint"
minttypes "github.com/scrtlabs/SecretNetwork/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"
Expand Down Expand Up @@ -73,7 +73,7 @@ func Modules(
consensus.NewAppModule(appCodec, app.AppKeepers.ConsensusParamsKeeper),
feegrantmodule.NewAppModule(appCodec, app.AppKeepers.AccountKeeper, *app.AppKeepers.BankKeeper, *app.AppKeepers.FeegrantKeeper, app.GetInterfaceRegistry()),
gov.NewAppModule(appCodec, app.AppKeepers.GovKeeper, app.AppKeepers.AccountKeeper, *app.AppKeepers.BankKeeper, app.AppKeepers.GetSubspace(govtypes.ModuleName)),
mint.NewAppModule(appCodec, *app.AppKeepers.MintKeeper, app.AppKeepers.AccountKeeper, nil, app.AppKeepers.GetSubspace(minttypes.ModuleName)),
mint.NewAppModule(appCodec, *app.AppKeepers.MintKeeper, app.AppKeepers.AccountKeeper, app.AppKeepers.GetSubspace(minttypes.ModuleName)),
slashing.NewAppModule(appCodec, *app.AppKeepers.SlashingKeeper, app.AppKeepers.AccountKeeper, *app.AppKeepers.BankKeeper, *app.AppKeepers.StakingKeeper, app.AppKeepers.GetSubspace(slashingtypes.ModuleName), app.GetInterfaceRegistry()),
distr.NewAppModule(appCodec, *app.AppKeepers.DistrKeeper, app.AppKeepers.AccountKeeper, *app.AppKeepers.BankKeeper, *app.AppKeepers.StakingKeeper, app.AppKeepers.GetSubspace(distrtypes.ModuleName)),
staking.NewAppModule(appCodec, app.AppKeepers.StakingKeeper, app.AppKeepers.AccountKeeper, *app.AppKeepers.BankKeeper, app.AppKeepers.GetSubspace(stakingtypes.ModuleName)),
Expand Down
90 changes: 90 additions & 0 deletions app/upgrades/v1.24/upgrade.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package v1_24

import (
"context"
"fmt"
"os"

"cosmossdk.io/log"
"cosmossdk.io/math"
store "cosmossdk.io/store/types"
upgradetypes "cosmossdk.io/x/upgrade/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
oldminttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/scrtlabs/SecretNetwork/app/keepers"
"github.com/scrtlabs/SecretNetwork/app/upgrades"
minttypes "github.com/scrtlabs/SecretNetwork/x/mint/types"
)

const upgradeName = "v1.24"

var Upgrade = upgrades.Upgrade{
UpgradeName: upgradeName,
CreateUpgradeHandler: createUpgradeHandler,
StoreUpgrades: store.StoreUpgrades{},
}

func createUpgradeHandler(mm *module.Manager, keepers *keepers.SecretAppKeepers, configurator module.Configurator,
) upgradetypes.UpgradeHandler {
return func(ctx context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) {
logger := log.NewLogger(os.Stderr)
logger.Info(` _ _ _____ _____ _____ _____ ______ `)
logger.Info(`| | | | __ \ / ____| __ \ /\ | __ \| ____|`)
logger.Info(`| | | | |__) | | __| |__) | / \ | | | | |__ `)
logger.Info(`| | | | ___/| | |_ | _ / / /\ \ | | | | __| `)
logger.Info(`| |__| | | | |__| | | \ \ / ____ \| |__| | |____ `)
logger.Info(` \____/|_| \_____|_| \_\/_/ \_\_____/|______|`)
logger.Info("")
logger.Info("🔥 SWITCHING TO FIXED BLOCK REWARDS 🔥")
logger.Info("")

logger.Info(fmt.Sprintf("Running module migrations for %s...", upgradeName))

// Migrate mint module parameters from percentage-based to fixed block rewards
logger.Info("Migrating mint module to fixed block rewards...")

// Read existing BlocksPerYear from legacy mint params
// This value is governance-adjustable and should be preserved
sdkCtx := sdk.UnwrapSDKContext(ctx)
mintSubspace := keepers.GetSubspace(oldminttypes.ModuleName)
if !mintSubspace.HasKeyTable() {
mintSubspace.WithKeyTable(oldminttypes.ParamKeyTable())
}
var oldBlocksPerYear uint64
mintSubspace.Get(sdkCtx, oldminttypes.KeyBlocksPerYear, &oldBlocksPerYear)
logger.Info(fmt.Sprintf(" - Existing blocks per year from chain state: %d", oldBlocksPerYear))

// Set new mint parameters with fixed block reward of 4 SCRT (4,000,000 uscrt)
// Preserve BlocksPerYear from existing chain state (governance-adjustable target)
newParams := minttypes.NewParams(
"uscrt", // MintDenom
math.NewInt(4_000_000), // FixedBlockReward: 4 SCRT = 4,000,000 uscrt
oldBlocksPerYear, // BlocksPerYear: preserve existing governance-managed value
)

if err := keepers.MintKeeper.SetParams(ctx, newParams); err != nil {
return nil, fmt.Errorf("failed to set mint params: %w", err)
}

// Initialize minter with annual provisions calculated from fixed block reward
// AnnualProvisions = FixedBlockReward * BlocksPerYear
annualProvisions := math.LegacyNewDecFromInt(newParams.FixedBlockReward).
Mul(math.LegacyNewDec(int64(newParams.BlocksPerYear)))

minter := minttypes.NewMinter(annualProvisions)
if err := keepers.MintKeeper.SetMinter(ctx, minter); err != nil {
return nil, fmt.Errorf("failed to set minter: %w", err)
}

logger.Info(fmt.Sprintf("✅ Mint module migrated successfully:"))
logger.Info(fmt.Sprintf(" - Fixed block reward: %s uscrt (4 SCRT)", newParams.FixedBlockReward.String()))
logger.Info(fmt.Sprintf(" - Blocks per year: %d", newParams.BlocksPerYear))
logger.Info(fmt.Sprintf(" - Annual provisions: %s uscrt (~21M SCRT)", annualProvisions.TruncateInt().String()))
logger.Info(fmt.Sprintf(" - Current inflation will decrease from ~9%% to ~6.2%%"))
logger.Info(fmt.Sprintf(" - Inflation will continue to decrease over time as supply grows"))
logger.Info("")

return mm.RunMigrations(ctx, configurator, vm)
}
}
71 changes: 71 additions & 0 deletions x/mint/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package mint

import (
"context"
"time"

"cosmossdk.io/math"
"github.com/scrtlabs/SecretNetwork/x/mint/keeper"
"github.com/scrtlabs/SecretNetwork/x/mint/types"

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

// BeginBlocker mints new tokens for the previous block.
func BeginBlocker(ctx context.Context, k keeper.Keeper) error {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)

// Fetch stored minter
minter, err := k.GetMinter(ctx)
if err != nil {
return err
}

// Fetch params
params, err := k.GetParams(ctx)
if err != nil {
return err
}

// Calculate annual provisions for informational purposes
// AnnualProvisions = FixedBlockReward * BlocksPerYear
annualProvisions := math.LegacyNewDecFromInt(params.FixedBlockReward).
Mul(math.LegacyNewDec(int64(params.BlocksPerYear)))
minter.AnnualProvisions = annualProvisions

// Save updated minter
if err := k.SetMinter(ctx, minter); err != nil {
return err
}

// Mint coins for this block - FIXED amount regardless of supply
mintedCoin := minter.BlockProvision(params)
mintedCoins := sdk.NewCoins(mintedCoin)

// Mint the coins
if err := k.MintCoins(ctx, mintedCoins); err != nil {
return err
}

// Send minted coins to the fee collector account
if err := k.AddCollectedFees(ctx, mintedCoins); err != nil {
return err
}

sdkCtx := sdk.UnwrapSDKContext(ctx)
if mintedCoin.Amount.IsInt64() {
defer telemetry.ModuleSetGauge(types.ModuleName, float32(mintedCoin.Amount.Int64()), "minted_tokens")
}

sdkCtx.EventManager().EmitEvent(
sdk.NewEvent(
types.ModuleName,
sdk.NewAttribute(types.KeyMintDenom, params.MintDenom),
sdk.NewAttribute(types.KeyFixedBlockReward, params.FixedBlockReward.String()),
sdk.NewAttribute("amount", mintedCoin.Amount.String()),
),
)

return nil
}
127 changes: 127 additions & 0 deletions x/mint/keeper/keeper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package keeper

import (
"context"

"cosmossdk.io/log"
"cosmossdk.io/math"
storetypes "cosmossdk.io/store/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/scrtlabs/SecretNetwork/x/mint/types"
)

// Keeper of the mint store
type Keeper struct {
cdc codec.BinaryCodec
storeService storetypes.KVStoreService
paramSpace paramtypes.Subspace
stakingKeeper types.StakingKeeper
bankKeeper types.BankKeeper
feeCollectorName string
authority string
}

// NewKeeper creates a new mint Keeper instance
func NewKeeper(
cdc codec.BinaryCodec,
storeService storetypes.KVStoreService,
sk types.StakingKeeper,
ak types.AccountKeeper,
bk types.BankKeeper,
feeCollectorName string,
authority string,
) Keeper {
return Keeper{
cdc: cdc,
storeService: storeService,
stakingKeeper: sk,
bankKeeper: bk,
feeCollectorName: feeCollectorName,
authority: authority,
}
}

// SetLegacyParamSubspace sets the param subspace for migration purposes
func (k *Keeper) SetLegacyParamSubspace(ps paramtypes.Subspace) {
k.paramSpace = ps
}

// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx context.Context) log.Logger {
sdkCtx := sdk.UnwrapSDKContext(ctx)
return sdkCtx.Logger().With("module", "x/"+types.ModuleName)
}

// GetMinter returns the minter
func (k Keeper) GetMinter(ctx context.Context) (minter types.Minter, err error) {
store := k.storeService.OpenKVStore(ctx)
b, err := store.Get([]byte(types.MinterKey))
if err != nil {
return minter, err
}
if b == nil {
return minter, nil
}

k.cdc.MustUnmarshal(b, &minter)
return minter, nil
}

// SetMinter sets the minter
func (k Keeper) SetMinter(ctx context.Context, minter types.Minter) error {
store := k.storeService.OpenKVStore(ctx)
b := k.cdc.MustMarshal(&minter)
return store.Set([]byte(types.MinterKey), b)
}

// GetParams returns the total set of minting parameters.
func (k Keeper) GetParams(ctx context.Context) (params types.Params, err error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
if k.paramSpace.HasKeyTable() {
k.paramSpace.GetParamSet(sdkCtx, &params)
return params, nil
}
return params, nil
}

// SetParams sets the total set of minting parameters.
func (k Keeper) SetParams(ctx context.Context, params types.Params) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
k.paramSpace.SetParamSet(sdkCtx, &params)
return nil
}

// StakingTokenSupply implements an alias call to the underlying staking keeper's
// StakingTokenSupply to be used in BeginBlocker.
func (k Keeper) StakingTokenSupply(ctx context.Context) (math.Int, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
return k.stakingKeeper.StakingTokenSupply(sdkCtx), nil
}

// BondedRatio implements an alias call to the underlying staking keeper's
// BondedRatio to be used in BeginBlocker.
func (k Keeper) BondedRatio(ctx context.Context) (math.LegacyDec, error) {
sdkCtx := sdk.UnwrapSDKContext(ctx)
return k.stakingKeeper.BondedRatio(sdkCtx), nil
}

// MintCoins implements an alias call to the underlying supply keeper's
// MintCoins to be used in BeginBlocker.
func (k Keeper) MintCoins(ctx context.Context, newCoins sdk.Coins) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
if newCoins.Empty() {
// skip as no coins need to be minted
return nil
}

return k.bankKeeper.MintCoins(sdkCtx, types.ModuleName, newCoins)
}

// AddCollectedFees implements an alias call to the underlying supply keeper's
// SendCoinsFromModuleToModule to be used in BeginBlocker.
func (k Keeper) AddCollectedFees(ctx context.Context, fees sdk.Coins) error {
sdkCtx := sdk.UnwrapSDKContext(ctx)
return k.bankKeeper.SendCoinsFromModuleToModule(sdkCtx, types.ModuleName, k.feeCollectorName, fees)
}
Loading