From 54d2caa4f125d830c9632aa81f75a7021653326c Mon Sep 17 00:00:00 2001
From: 0g-wh <wenhui.xing@0g.ai>
Date: Wed, 15 Jan 2025 09:33:29 +0000
Subject: [PATCH] v0.5.0 upgrade

---
 app/upgrades.go | 213 ++----------------------------------------------
 go.mod          |   6 +-
 go.sum          |   6 +-
 3 files changed, 15 insertions(+), 210 deletions(-)

diff --git a/app/upgrades.go b/app/upgrades.go
index cf486d04..067bcf73 100644
--- a/app/upgrades.go
+++ b/app/upgrades.go
@@ -3,21 +3,16 @@ package app
 import (
 	"fmt"
 
-	sdkmath "cosmossdk.io/math"
-
-	evmutilkeeper "github.com/0glabs/0g-chain/x/evmutil/keeper"
-	evmutiltypes "github.com/0glabs/0g-chain/x/evmutil/types"
-	precisebankkeeper "github.com/0glabs/0g-chain/x/precisebank/keeper"
-	precisebanktypes "github.com/0glabs/0g-chain/x/precisebank/types"
+	wrappeda0gibasetypes "github.com/0glabs/0g-chain/x/wrapped-a0gi-base/types"
 	storetypes "github.com/cosmos/cosmos-sdk/store/types"
 	sdk "github.com/cosmos/cosmos-sdk/types"
 	"github.com/cosmos/cosmos-sdk/types/module"
-	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
+	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
 	upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
 )
 
 const (
-	UpgradeName_Testnet = "v0.4.0"
+	UpgradeName_Testnet = "v0.5.0"
 )
 
 // RegisterUpgradeHandlers registers the upgrade handlers for the app.
@@ -37,7 +32,7 @@ func (app App) RegisterUpgradeHandlers() {
 	if doUpgrade && !app.upgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
 		storeUpgrades := storetypes.StoreUpgrades{
 			Added: []string{
-				precisebanktypes.ModuleName,
+				wrappeda0gibasetypes.ModuleName,
 			},
 		}
 
@@ -65,204 +60,12 @@ func upgradeHandler(
 			return nil, err
 		}
 
+		app.mintKeeper.InitGenesis(ctx, app.accountKeeper, &minttypes.GenesisState{
+			BondDenom: "ua0gi",
+		})
+
 		logger.Info("completed store migrations")
 
-		// Migration of fractional balances from x/evmutil to x/precisebank
-		if err := MigrateEvmutilToPrecisebank(
-			ctx,
-			app.accountKeeper,
-			app.bankKeeper,
-			app.evmutilKeeper,
-			app.precisebankKeeper,
-		); err != nil {
-			return nil, err
-		}
-
-		logger.Info("completed x/evmutil to x/precisebank migration")
-
 		return versionMap, nil
 	}
 }
-
-// MigrateEvmutilToPrecisebank migrates all required state from x/evmutil to
-// x/precisebank and ensures the resulting state is correct.
-// This migrates the following state:
-// - Fractional balances
-// - Fractional balance reserve
-// Initializes the following state in x/precisebank:
-// - Remainder amount
-func MigrateEvmutilToPrecisebank(
-	ctx sdk.Context,
-	accountKeeper evmutiltypes.AccountKeeper,
-	bankKeeper bankkeeper.Keeper,
-	evmutilKeeper evmutilkeeper.Keeper,
-	precisebankKeeper precisebankkeeper.Keeper,
-) error {
-	logger := ctx.Logger()
-
-	aggregateSum, err := TransferFractionalBalances(
-		ctx,
-		evmutilKeeper,
-		precisebankKeeper,
-	)
-	if err != nil {
-		return fmt.Errorf("fractional balances transfer: %w", err)
-	}
-	logger.Info(
-		"fractional balances transferred from x/evmutil to x/precisebank",
-		"aggregate sum", aggregateSum,
-	)
-
-	remainder := InitializeRemainder(ctx, precisebankKeeper, aggregateSum)
-	logger.Info("remainder amount initialized in x/precisebank", "remainder", remainder)
-
-	// Migrate fractional balances, reserve, and ensure reserve fully backs all
-	// fractional balances.
-	if err := TransferFractionalBalanceReserve(
-		ctx,
-		accountKeeper,
-		bankKeeper,
-		precisebankKeeper,
-	); err != nil {
-		return fmt.Errorf("reserve transfer: %w", err)
-	}
-
-	return nil
-}
-
-// TransferFractionalBalances migrates fractional balances from x/evmutil to
-// x/precisebank. It sets the fractional balance in x/precisebank and deletes
-// the account from x/evmutil. Returns the aggregate sum of all fractional
-// balances.
-func TransferFractionalBalances(
-	ctx sdk.Context,
-	evmutilKeeper evmutilkeeper.Keeper,
-	precisebankKeeper precisebankkeeper.Keeper,
-) (sdkmath.Int, error) {
-	aggregateSum := sdkmath.ZeroInt()
-
-	var iterErr error
-
-	evmutilKeeper.IterateAllAccounts(ctx, func(acc evmutiltypes.Account) bool {
-		// Set account balance in x/precisebank
-		precisebankKeeper.SetFractionalBalance(ctx, acc.Address, acc.Balance)
-
-		// Delete account from x/evmutil
-		iterErr := evmutilKeeper.SetAccount(ctx, evmutiltypes.Account{
-			Address: acc.Address,
-			// Set balance to 0 to delete it
-			Balance: sdkmath.ZeroInt(),
-		})
-
-		// Halt iteration if there was an error
-		if iterErr != nil {
-			return true
-		}
-
-		// Aggregate sum of all fractional balances
-		aggregateSum = aggregateSum.Add(acc.Balance)
-
-		// Continue iterating
-		return false
-	})
-
-	return aggregateSum, iterErr
-}
-
-// InitializeRemainder initializes the remainder amount in x/precisebank. It
-// calculates the remainder amount that is needed to ensure that the sum of all
-// fractional balances is a multiple of the conversion factor. The remainder
-// amount is stored in the store and returned.
-func InitializeRemainder(
-	ctx sdk.Context,
-	precisebankKeeper precisebankkeeper.Keeper,
-	aggregateSum sdkmath.Int,
-) sdkmath.Int {
-	// Extra fractional coins that exceed the conversion factor.
-	// This extra + remainder should equal the conversion factor to ensure
-	// (sum(fBalances) + remainder) % conversionFactor = 0
-	extraFractionalAmount := aggregateSum.Mod(precisebanktypes.ConversionFactor())
-	remainder := precisebanktypes.ConversionFactor().
-		Sub(extraFractionalAmount).
-		// Mod conversion factor to ensure remainder is valid.
-		// If extraFractionalAmount is a multiple of conversion factor, the
-		// remainder is 0.
-		Mod(precisebanktypes.ConversionFactor())
-
-	// Panics if the remainder is invalid. In a correct chain state and only
-	// mint/burns due to transfers, this would be 0.
-	precisebankKeeper.SetRemainderAmount(ctx, remainder)
-
-	return remainder
-}
-
-// TransferFractionalBalanceReserve migrates the fractional balance reserve from
-// x/evmutil to x/precisebank. It transfers the reserve balance from x/evmutil
-// to x/precisebank and ensures that the reserve fully backs all fractional
-// balances. It mints or burns coins to back the fractional balances exactly.
-func TransferFractionalBalanceReserve(
-	ctx sdk.Context,
-	accountKeeper evmutiltypes.AccountKeeper,
-	bankKeeper bankkeeper.Keeper,
-	precisebankKeeper precisebankkeeper.Keeper,
-) error {
-	logger := ctx.Logger()
-
-	// Transfer x/evmutil reserve to x/precisebank.
-	evmutilAddr := accountKeeper.GetModuleAddress(evmutiltypes.ModuleName)
-	reserveBalance := bankKeeper.GetBalance(ctx, evmutilAddr, precisebanktypes.IntegerCoinDenom)
-
-	if err := bankKeeper.SendCoinsFromModuleToModule(
-		ctx,
-		evmutiltypes.ModuleName,     // from x/evmutil
-		precisebanktypes.ModuleName, // to x/precisebank
-		sdk.NewCoins(reserveBalance),
-	); err != nil {
-		return fmt.Errorf("failed to transfer reserve from x/evmutil to x/precisebank: %w", err)
-	}
-
-	logger.Info(fmt.Sprintf("transferred reserve balance: %s", reserveBalance))
-
-	// Ensure x/precisebank reserve fully backs all fractional balances.
-	totalFractionalBalances := precisebankKeeper.GetTotalSumFractionalBalances(ctx)
-
-	// Does NOT ensure state is correct, total fractional balances should be a
-	// multiple of conversion factor but is not guaranteed due to the remainder.
-	// Remainder initialization is handled by InitializeRemainder.
-
-	// Determine how much the reserve is off by, e.g. unbacked amount
-	expectedReserveBalance := totalFractionalBalances.Quo(precisebanktypes.ConversionFactor())
-
-	// If there is a remainder (totalFractionalBalances % conversionFactor != 0),
-	// then expectedReserveBalance is rounded up to the nearest integer.
-	if totalFractionalBalances.Mod(precisebanktypes.ConversionFactor()).IsPositive() {
-		expectedReserveBalance = expectedReserveBalance.Add(sdkmath.OneInt())
-	}
-
-	unbackedAmount := expectedReserveBalance.Sub(reserveBalance.Amount)
-	logger.Info(fmt.Sprintf("total account fractional balances: %s", totalFractionalBalances))
-
-	// Three possible cases:
-	// 1. Reserve is not enough, mint coins to back the fractional balances
-	// 2. Reserve is too much, burn coins to back the fractional balances exactly
-	// 3. Reserve is exactly enough, no action needed
-	if unbackedAmount.IsPositive() {
-		coins := sdk.NewCoins(sdk.NewCoin(precisebanktypes.IntegerCoinDenom, unbackedAmount))
-		if err := bankKeeper.MintCoins(ctx, precisebanktypes.ModuleName, coins); err != nil {
-			return fmt.Errorf("failed to mint extra reserve coins: %w", err)
-		}
-
-		logger.Info(fmt.Sprintf("unbacked amount minted to reserve: %s", unbackedAmount))
-	} else if unbackedAmount.IsNegative() {
-		coins := sdk.NewCoins(sdk.NewCoin(precisebanktypes.IntegerCoinDenom, unbackedAmount.Neg()))
-		if err := bankKeeper.BurnCoins(ctx, precisebanktypes.ModuleName, coins); err != nil {
-			return fmt.Errorf("failed to burn extra reserve coins: %w", err)
-		}
-
-		logger.Info(fmt.Sprintf("extra reserve amount burned: %s", unbackedAmount.Neg()))
-	} else {
-		logger.Info("reserve exactly backs fractional balances, no mint/burn needed")
-	}
-
-	return nil
-}
diff --git a/go.mod b/go.mod
index 4fd1eac0..f26169f0 100644
--- a/go.mod
+++ b/go.mod
@@ -9,6 +9,7 @@ require (
 	cosmossdk.io/simapp v0.0.0-20231127212628-044ff4d8c015
 	github.com/Kava-Labs/opendb v0.0.0-20240719173129-a2f11f6d7e51
 	github.com/cenkalti/backoff/v4 v4.1.3
+	github.com/cockroachdb/errors v1.11.1
 	github.com/cometbft/cometbft v0.37.9
 	github.com/cometbft/cometbft-db v0.9.1
 	github.com/coniks-sys/coniks-go v0.0.0-20180722014011-11acf4819b71
@@ -28,6 +29,7 @@ require (
 	github.com/golang/protobuf v1.5.4
 	github.com/gorilla/mux v1.8.0
 	github.com/grpc-ecosystem/grpc-gateway v1.16.0
+	github.com/huandu/skiplist v1.2.0
 	github.com/linxGnu/grocksdb v1.8.13
 	github.com/pelletier/go-toml/v2 v2.1.0
 	github.com/shopspring/decimal v1.4.0
@@ -76,7 +78,6 @@ require (
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/chzyer/readline v1.5.1 // indirect
 	github.com/cockroachdb/apd/v2 v2.0.2 // indirect
-	github.com/cockroachdb/errors v1.11.1 // indirect
 	github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
 	github.com/cockroachdb/pebble v1.1.0 // indirect
 	github.com/cockroachdb/redact v1.1.5 // indirect
@@ -146,7 +147,6 @@ require (
 	github.com/hdevalence/ed25519consensus v0.1.0 // indirect
 	github.com/holiman/bloomfilter/v2 v2.0.3 // indirect
 	github.com/holiman/uint256 v1.2.1 // indirect
-	github.com/huandu/skiplist v1.2.0 // indirect
 	github.com/huin/goupnp v1.0.3 // indirect
 	github.com/iancoleman/orderedmap v0.2.0 // indirect
 	github.com/improbable-eng/grpc-web v0.15.0 // indirect
@@ -242,7 +242,7 @@ replace (
 	github.com/cometbft/cometbft-db => github.com/kava-labs/cometbft-db v0.9.1-kava.2
 	// Use cosmos-sdk fork with backported fix for unsafe-reset-all, staking transfer events, and custom tally handler support
 	// github.com/cosmos/cosmos-sdk => github.com/0glabs/cosmos-sdk v0.46.11-kava.3
-	github.com/cosmos/cosmos-sdk => github.com/0glabs/cosmos-sdk v0.47.10-0glabs.9
+	github.com/cosmos/cosmos-sdk => github.com/0glabs/cosmos-sdk v0.47.10-0glabs.10
 	github.com/cosmos/iavl => github.com/kava-labs/iavl v1.2.0-kava.1
 	// See https://github.com/cosmos/cosmos-sdk/pull/13093
 	github.com/dgrijalva/jwt-go => github.com/golang-jwt/jwt/v4 v4.4.2
diff --git a/go.sum b/go.sum
index a59d63a5..a56db589 100644
--- a/go.sum
+++ b/go.sum
@@ -211,8 +211,10 @@ git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFN
 git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA=
 github.com/0glabs/cometbft v0.37.9-0glabs.1 h1:KQJG17Y21suKP3QNICLto4b5Ak73XbSmKxeLbg0ZM68=
 github.com/0glabs/cometbft v0.37.9-0glabs.1/go.mod h1:j0Q3RqrCd+cztWCugs3obbzC4NyHGBPZZjtm/fWV00I=
-github.com/0glabs/ethermint v0.21.0-0g.v3.1.8 h1:/jxCtO5B8amXgGZ0MWcoIH32PmoU9Z+WfPxA8nLaZI8=
-github.com/0glabs/ethermint v0.21.0-0g.v3.1.8/go.mod h1:1GrxH8zkhO/x8sinIxaFtolK50spzSAZISbdP1MDLy8=
+github.com/0glabs/cosmos-sdk v0.47.10-0glabs.10 h1:NJp0RwczHBO4EvrQdDxxftHOgUDBtNh7M/vpaG7wFtQ=
+github.com/0glabs/cosmos-sdk v0.47.10-0glabs.10/go.mod h1:KskIVnhXTFqrw7CDccMvx7To5KzUsOomIsQV7sPGOog=
+github.com/0glabs/ethermint v0.21.0-0g.v3.1.9 h1:oTHp7tSAqoML7D/+RXsBzA9DsbZ80MX93VJYjR/Akh4=
+github.com/0glabs/ethermint v0.21.0-0g.v3.1.9/go.mod h1:6e/gOcDLhvlDWK3JLJVBgki0gD6H4E1eG7l9byocgWA=
 github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs=
 github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4=
 github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM=