diff --git a/app/upgrades/v20/constants.go b/app/upgrades/v20/constants.go new file mode 100644 index 0000000000..68ec7e5f3b --- /dev/null +++ b/app/upgrades/v20/constants.go @@ -0,0 +1,11 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package v20 + +const ( + // UpgradeName is the shared upgrade plan name for mainnet + UpgradeName = "v20.0.0" + // UpgradeInfo defines the binaries that will be used for the upgrade + UpgradeInfo = `'{"binaries":{"darwin/amd64":"https://github.com/evmos/evmos/releases/download/v20.0.0/evmos_20.0.0_Darwin_arm64.tar.gz","darwin/x86_64":"https://github.com/evmos/evmos/releases/download/v20.0.0/evmos_20.0.0_Darwin_x86_64.tar.gz","linux/arm64":"https://github.com/evmos/evmos/releases/download/v20.0.0/evmos_20.0.0_Linux_arm64.tar.gz","linux/amd64":"https://github.com/evmos/evmos/releases/download/v20.0.0/evmos_20.0.0_Linux_amd64.tar.gz","windows/x86_64":"https://github.com/evmos/evmos/releases/download/v20.0.0/evmos_20.0.0_Windows_x86_64.zip"}}'` +) diff --git a/app/upgrades/v20/convert.go b/app/upgrades/v20/convert.go new file mode 100644 index 0000000000..0931eb6e17 --- /dev/null +++ b/app/upgrades/v20/convert.go @@ -0,0 +1,252 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package v20 + +import ( + "encoding/json" + "fmt" + "math/big" + "os" + "slices" + "time" + + "github.com/cometbft/cometbft/libs/log" + sdk "github.com/cosmos/cosmos-sdk/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + fixes "github.com/evmos/evmos/v18/app/upgrades/v20/fixes" + erc20keeper "github.com/evmos/evmos/v18/x/erc20/keeper" + erc20types "github.com/evmos/evmos/v18/x/erc20/types" + evmkeeper "github.com/evmos/evmos/v18/x/evm/keeper" +) + +// storeKey contains the slot in which the balance is stored in the evm. +var storeKey []byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2} +var storeKeyWevmos []byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3} + +type parseTokenPairs = []common.Address + +// BalanceResult contains the data needed to perform the balance conversion +type BalanceResult struct { + address sdk.AccAddress + balanceBytes []byte + id int +} + +// ExportResult holds the data +// to be exported to a json file +type ExportResult struct { + Address string + Balance string + Erc20 string +} + +// executeConversion receives the whole set of adress with erc20 balances +// it sends the equivalent coin from the escrow address into the holder address +// it doesnt need to burn the erc20 balance, because the evm storage will be deleted later +func executeConversion( + ctx sdk.Context, + results []BalanceResult, + bankKeeper bankkeeper.Keeper, + erc20Keeper erc20keeper.Keeper, + wrappedEvmosAddr common.Address, + nativeTokenPairs []erc20types.TokenPair, + fromSnapshot bool, +) error { + wevmosAccount := sdk.AccAddress(wrappedEvmosAddr.Bytes()) + // Go trough every address with an erc20 balance + for _, result := range results { + if fromSnapshot && erc20Keeper.HasSTRv2Address(ctx, result.address) { + continue + } + + tokenPair := nativeTokenPairs[result.id] + + // The conversion is different for Evmos/WEVMOS and IBC-coins + // Convert balance Bytes into Big Int + balance := new(big.Int).SetBytes(result.balanceBytes) + if balance.Sign() <= 0 { + continue + } + // Create the coin + coins := sdk.Coins{sdk.Coin{Denom: tokenPair.Denom, Amount: sdk.NewIntFromBigInt(balance)}} + + // If its Wevmos + if tokenPair.Erc20Address == wrappedEvmosAddr.Hex() { + // Withdraw the balance from the contract + // Unescrow coins and send to holder account + err := bankKeeper.SendCoinsFromAccountToModule(ctx, wevmosAccount, erc20types.ModuleName, coins) + if err != nil { + return err + } + } + + err := bankKeeper.SendCoinsFromModuleToAccount(ctx, erc20types.ModuleName, result.address, coins) + if err != nil { + return err + } + } + return nil +} + +// ConvertERC20Coins generates the list of address-erc20 balance that need to be migrated +// It takes some steps to generate this list (parallel) +// - Divide all the accounts into smaller batches +// - Have parallel workers query the db for erc20 balance +// - Consolidate all the balances on the same array +// +// Once the list is generated, it does three things (serialized) +// - Save the result into a file +// - Actually move all the balances from erc20 to bank +// - Check that all the balances has been moved. +func ConvertERC20Coins( + ctx sdk.Context, + logger log.Logger, + accountKeeper authkeeper.AccountKeeper, + bankKeeper bankkeeper.Keeper, + erc20Keeper erc20keeper.Keeper, + evmKeeper evmkeeper.Keeper, + wrappedAddr common.Address, + nativeTokenPairs []erc20types.TokenPair, +) error { + timeBegin := time.Now() // control the time of the execution + + // simplify the list of erc20 token pairs to handle less data + tokenPairs := make(parseTokenPairs, len(nativeTokenPairs)) + for i := range nativeTokenPairs { + tokenPairs[i] = nativeTokenPairs[i].GetERC20Contract() + } + + modifiedBalancesAccounts := erc20Keeper.GetAllSTRV2Address(ctx) + var modifiedBalancesWallets = make([]string, len(modifiedBalancesAccounts)) + for i, addr := range modifiedBalancesAccounts { + modifiedBalancesWallets[i] = addr.String() + } + + // Need to filter only uniques accounts + missingWallets := fixes.GetMissingWalletsFromAuthModule(ctx, accountKeeper) + combinedWallets := append(missingWallets, modifiedBalancesWallets...) + slices.Sort(combinedWallets) + combinedWallets = slices.Compact(combinedWallets) + + // Convert to accounts + allAccounts := make([]sdk.AccAddress, len(combinedWallets)) + for i, wallet := range combinedWallets { + allAccounts[i] = sdk.MustAccAddressFromBech32(wallet) + } + + wevmosId := 0 + tokenPairStores := make([]sdk.KVStore, len(tokenPairs)) + for i, pair := range tokenPairs { + tokenPairStores[i] = evmKeeper.GetStoreDummy(ctx, pair) + if wrappedAddr.Hex() == pair.Hex() { + wevmosId = i + } + } + + resultsCol := []BalanceResult{} + for _, account := range allAccounts { + concatBytes := append(common.LeftPadBytes(account.Bytes(), 32), storeKey...) + key := crypto.Keccak256Hash(concatBytes) + + concatBytesWevmos := append(common.LeftPadBytes(account.Bytes(), 32), storeKeyWevmos...) + keyWevmos := crypto.Keccak256Hash(concatBytesWevmos) + var value []byte + for tokenId, store := range tokenPairStores { + if tokenId == wevmosId { + value = store.Get(keyWevmos.Bytes()) + if len(value) == 0 { + continue + } + } else { + value = store.Get(key.Bytes()) + if len(value) == 0 { + continue + } + } + + resultsCol = append(resultsCol, BalanceResult{address: account, balanceBytes: value, id: tokenId}) + } + } + + err := executeConversion(ctx, resultsCol, bankKeeper, erc20Keeper, wrappedAddr, nativeTokenPairs, false) + if err != nil { + panic(err) + } + + userHomeDir, err := os.UserHomeDir() + if err != nil { + panic(err) + } + + // Store in file + // file, _ := json.MarshalIndent(jsonExport, "", " ") + file, err := os.ReadFile(fmt.Sprint(userHomeDir, "/results-full.json")) + if err != nil { + panic(err) + } + + var readResults []ExportResult + err = json.Unmarshal(file, &readResults) + fmt.Println("Finalized results: ", len(readResults)) + if err != nil { + panic("Failed to unmarshal") + } + + erc20Map := make(map[string]int) + for i, erc20 := range nativeTokenPairs { + erc20Map[erc20.Erc20Address] = i + } + + // Generate the json to store in the file + var finalizedResults []BalanceResult = make([]BalanceResult, len(readResults)) + for i, result := range readResults { + b, _ := new(big.Int).SetString(result.Balance, 10) + finalizedResults[i] = BalanceResult{ + address: sdk.MustAccAddressFromBech32(result.Address), + balanceBytes: b.Bytes(), + id: erc20Map[result.Erc20], + } + } + // execute the actual conversion. + err = executeConversion(ctx, finalizedResults, bankKeeper, erc20Keeper, wrappedAddr, nativeTokenPairs, true) + if err != nil { + panic(err) + } + + // NOTE: if there are tokens left in the ERC-20 module account + // we return an error because this implies that the migration of native + // coins to ERC-20 tokens was not fully completed. + erc20ModuleAccountAddress := authtypes.NewModuleAddress(erc20types.ModuleName) + balances := bankKeeper.GetAllBalances(ctx, erc20ModuleAccountAddress) + if !balances.IsZero() { + return fmt.Errorf("there are still tokens in the erc-20 module account: %s", balances.String()) + } + duration := time.Since(timeBegin) + logger.Info(fmt.Sprintf("STR v2 migration took %s\n", duration)) + return nil +} + +// getNativeTokenPairs returns the token pairs that are registered for native Cosmos coins. +func getNativeTokenPairs( + ctx sdk.Context, + erc20Keeper erc20keeper.Keeper, +) []erc20types.TokenPair { + var nativeTokenPairs []erc20types.TokenPair + + erc20Keeper.IterateTokenPairs(ctx, func(tokenPair erc20types.TokenPair) bool { + // NOTE: here we check if the token pair contains an IBC coin. For now, we only want to convert those. + if !tokenPair.IsNativeCoin() { + return false + } + + nativeTokenPairs = append(nativeTokenPairs, tokenPair) + return false + }) + + return nativeTokenPairs +} diff --git a/app/upgrades/v20/erc20.go b/app/upgrades/v20/erc20.go new file mode 100644 index 0000000000..b5b7413432 --- /dev/null +++ b/app/upgrades/v20/erc20.go @@ -0,0 +1,57 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package v20 + +import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + erc20keeper "github.com/evmos/evmos/v18/x/erc20/keeper" + "github.com/evmos/evmos/v18/x/erc20/types" + evmkeeper "github.com/evmos/evmos/v18/x/evm/keeper" +) + +// RegisterERC20Extensions registers the ERC20 precompiles with the EVM. +func RegisterERC20Extensions( + ctx sdk.Context, + erc20Keeper erc20keeper.Keeper, + evmKeeper *evmkeeper.Keeper, +) error { + precompiles := make([]common.Address, 0) + evmParams := evmKeeper.GetParams(ctx) + + var err error + erc20Keeper.IterateTokenPairs(ctx, func(tokenPair types.TokenPair) bool { + address := tokenPair.GetERC20Contract() + + // skip registration if token is native or if it has already been registered + // NOTE: this should handle failure during the selfdestruct + if !tokenPair.IsNativeCoin() || + evmKeeper.IsAvailableDynamicPrecompile(&evmParams, address) { + return false + } + + // try to self-destruct the old ERC20 contract + // NOTE(@fedekunze): From now on, the contract address will map to a precompile instead + // of the ERC20MinterBurner contract. We try to force a self-destruction to remove the unnecessary + // code and storage from the state machine. + // In any case, the precompiles are handled in the EVM + // before the regular contracts so not removing them doesn't create any issues in the implementation. + err = evmKeeper.DeleteAccount(ctx, address) + if err != nil { + err = errorsmod.Wrapf(err, "failed to selfdestruct account %s", address) + return true + } + + precompiles = append(precompiles, address) + return false + }) + + if err != nil { + return err + } + + // add the ERC20s to the EVM active and available precompiles + return evmKeeper.EnableDynamicPrecompiles(ctx, precompiles...) +} diff --git a/app/upgrades/v20/erc20_test.go b/app/upgrades/v20/erc20_test.go new file mode 100644 index 0000000000..257c7736ea --- /dev/null +++ b/app/upgrades/v20/erc20_test.go @@ -0,0 +1,180 @@ +package v20_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + v20 "github.com/evmos/evmos/v18/app/upgrades/v20" + erc20precompile "github.com/evmos/evmos/v18/precompiles/erc20" + testkeyring "github.com/evmos/evmos/v18/testutil/integration/evmos/keyring" + testnetwork "github.com/evmos/evmos/v18/testutil/integration/evmos/network" + utiltx "github.com/evmos/evmos/v18/testutil/tx" + "github.com/evmos/evmos/v18/utils" + "github.com/evmos/evmos/v18/x/erc20/types" + evmkeeper "github.com/evmos/evmos/v18/x/evm/keeper" + "github.com/stretchr/testify/require" +) + +// SetupNetwork sets up a new test network and returns the network and the grpc handler. +func SetupNetwork() *testnetwork.UnitTestNetwork { + keyring := testkeyring.New(1) + + return testnetwork.NewUnitTestNetwork( + testnetwork.WithPreFundedAccounts(keyring.GetAllAccAddrs()...), + ) +} + +func TestRegisterERC20Extensions(t *testing.T) { + var network *testnetwork.UnitTestNetwork + + ibcDenom := utils.ComputeIBCDenom("transfer", "channel-0", "uosmo") + ibcTokenPair := types.NewTokenPair(utiltx.GenerateAddress(), ibcDenom, types.OWNER_MODULE) + nativeTokenPair := types.NewTokenPair(utiltx.GenerateAddress(), "test", types.OWNER_MODULE) + otherNativeTokenPair := types.NewTokenPair(utiltx.GenerateAddress(), "other", types.OWNER_MODULE) + externalTokenPair := types.NewTokenPair(utiltx.GenerateAddress(), "uext", types.OWNER_EXTERNAL) + + testcases := []struct { + name string + malleate func() + expPass bool + errContains string + postCheck func() + }{ + { + name: "pass - no token pairs in ERC20 keeper", + expPass: true, + postCheck: func() { + requireActiveDynamicPrecompiles(t, network.GetContext(), network.App.EvmKeeper, []string{}) + }, + }, + { + name: "pass - native token pair", + malleate: func() { + network.App.Erc20Keeper.SetTokenPair(network.GetContext(), nativeTokenPair) + }, + expPass: true, + postCheck: func() { + // Check that the precompile is set as active + requireActiveDynamicPrecompiles( + t, network.GetContext(), network.App.EvmKeeper, + []string{nativeTokenPair.Erc20Address}, + ) + }, + }, + { + name: "pass - IBC token pair", + malleate: func() { + network.App.Erc20Keeper.SetTokenPair(network.GetContext(), ibcTokenPair) + }, + expPass: true, + postCheck: func() { + // Check that the precompile is set as active + requireActiveDynamicPrecompiles( + t, network.GetContext(), network.App.EvmKeeper, + []string{ibcTokenPair.Erc20Address}, + ) + }, + }, + { + name: "pass - external token pair is skipped", + malleate: func() { + network.App.Erc20Keeper.SetTokenPair(network.GetContext(), externalTokenPair) + network.App.Erc20Keeper.SetTokenPair(network.GetContext(), otherNativeTokenPair) + }, + expPass: true, + postCheck: func() { + // Check that active precompiles are unchanged + requireActiveDynamicPrecompiles( + t, network.GetContext(), network.App.EvmKeeper, + []string{otherNativeTokenPair.Erc20Address}, + ) + }, + }, + { + // TODO: this is not failing anymore in the new implementation? Is that what we want? + name: "no-op - already registered precompile", + malleate: func() { + network.App.Erc20Keeper.SetTokenPair(network.GetContext(), nativeTokenPair) + network.App.Erc20Keeper.SetTokenPair(network.GetContext(), otherNativeTokenPair) + + tokenPrecompile, err := erc20precompile.NewPrecompile( + nativeTokenPair, network.App.BankKeeper, network.App.AuthzKeeper, network.App.TransferKeeper, + ) + require.NoError(t, err, "expected no error creating precompile") + + // NOTE: We are adding this in the malleate function, so it is already present before + // the real test case. + err = network.App.EvmKeeper.AddDynamicPrecompiles(network.GetContext(), tokenPrecompile) + require.NoError(t, err, "expected no error adding precompile") + }, + expPass: true, + postCheck: func() { + // Check that active precompiles contain the already registered precompile only once + requireActiveDynamicPrecompiles( + t, network.GetContext(), network.App.EvmKeeper, + []string{nativeTokenPair.Erc20Address, otherNativeTokenPair.Erc20Address}, + ) + }, + }, + { + name: "pass - evm denomination deploys erc20 contract", + malleate: func() { + params := network.App.EvmKeeper.GetParams(network.GetContext()) + params.EvmDenom = nativeTokenPair.Denom + err := network.App.EvmKeeper.SetParams(network.GetContext(), params) + require.NoError(t, err, "expected no error setting EVM params") + + network.App.Erc20Keeper.SetTokenPair(network.GetContext(), nativeTokenPair) + }, + expPass: true, + postCheck: func() { + // Check that the precompile was registered + requireActiveDynamicPrecompiles( + t, network.GetContext(), network.App.EvmKeeper, + []string{nativeTokenPair.Erc20Address}, + ) + }, + }, + } + + for _, tc := range testcases { + tc := tc + + t.Run(tc.name, func(t *testing.T) { + network = SetupNetwork() + + if tc.malleate != nil { + tc.malleate() + } + + err := v20.RegisterERC20Extensions( + network.GetContext(), + network.App.Erc20Keeper, + network.App.EvmKeeper, + ) + + if tc.expPass { + require.NoError(t, err, "expected no error registering ERC20 extensions") + } else { + require.Error(t, err, "expected an error registering ERC20 extensions") + require.ErrorContains(t, err, tc.errContains, "expected different error message") + } + + if tc.postCheck != nil { + tc.postCheck() + } + }) + } +} + +// requireActiveDynamicPrecompiles checks that the active dynamic precompiles +// in the EVM keeper match the expected precompiles. +func requireActiveDynamicPrecompiles( + t *testing.T, ctx sdk.Context, evmKeeper *evmkeeper.Keeper, expPrecompiles []string, +) { + activeDynamicPrecompiles := evmKeeper.GetParams(ctx).ActiveDynamicPrecompiles + require.ElementsMatch( + t, expPrecompiles, activeDynamicPrecompiles, + "expected active precompiles to match", + ) +} diff --git a/app/upgrades/v20/fixes/atom.go b/app/upgrades/v20/fixes/atom.go new file mode 100644 index 0000000000..071da445fe --- /dev/null +++ b/app/upgrades/v20/fixes/atom.go @@ -0,0 +1,136 @@ +package fixes + +func AddMissingWalletsATOM(wallets []string) []string { + wallets = append(wallets, "0x50ea3b46c7ac3dc6fb08c26143f57f438e86b834") + wallets = append(wallets, "0x53d051fc3fdb970f12c97ad784da8c2e6a653c4a") + wallets = append(wallets, "0x8feb6d9bdba2a8084a1174a46e7bbafb37c9778f") + wallets = append(wallets, "0xdf5fb94e1fd49b3e1d9bfa2593fe23354d71305d") + wallets = append(wallets, "0x2e8cb781f8bc2290428fe7f9c2d818a0bff1cffb") + wallets = append(wallets, "0x7199a6b41602d4a2394d30fed7f53cc9d4415275") + wallets = append(wallets, "0x7ccde3a8b22858313c1d67db74c4b298adaff18c") + wallets = append(wallets, "0x336204b0b03f85807b040688637b1228fa6eae0d") + wallets = append(wallets, "0x2a21de2ae2ff1a14f66d523baaa8822a9c9640a5") + wallets = append(wallets, "0x6e3596006e4014c74fd0277adcee7ad13a762858") + wallets = append(wallets, "0xa7015e48baaa2648d41f4db553b0af3ec565422a") + wallets = append(wallets, "0x1233b9af0bf71c50e036ed8ba66f8c7277e3df36") + wallets = append(wallets, "0xa9763f7c353486d67f2ef2c9084d41a8f1d148ba") + wallets = append(wallets, "0x122c0ce2dd972ea2f73cc3404ca7586b2ef39ad0") + wallets = append(wallets, "0x6dc0a4b6b36c885309dd72fc32372ef874f35902") + wallets = append(wallets, "0x54353aedc15714c843327102b244dd0f3104348a") + wallets = append(wallets, "0xa8c8611c0a2f8e2bd95cf475f2ad58c08d495dd7") + wallets = append(wallets, "0x0b0b605c0bcf926b1c545b737e4a6ed80f582558") + wallets = append(wallets, "0xd8ced29a897b8bab6d7c702138c4209376c92549") + wallets = append(wallets, "0xa4c6aa2bce5ae18e15621435668cbbd07e1ac827") + wallets = append(wallets, "0x2c3d5a0aa63da3f3140c8a3d17b015bb8c97ce4d") + wallets = append(wallets, "0x3fdfbdc299e4b2bfdb4119be4ba1edad53305298") + wallets = append(wallets, "0x320c0bc2d60baa4d7f39579699f469daa1cc4d20") + wallets = append(wallets, "0x6b3c58d53643ae7c2dea5f01eb34f68e9858f0cd") + wallets = append(wallets, "0xf9b0daaa10664a1b6ad26747225780c129450a19") + wallets = append(wallets, "0x9962aa55973f88ba59d57ebd486625dd52e26bea") + wallets = append(wallets, "0xfa22001e9b6abcf3907659c96684fe7f500bbd9b") + wallets = append(wallets, "0x1a6be5f050a22f5dfd66529ec0226d2ea7b466c5") + wallets = append(wallets, "0xa86e428c73832b5b4f2ff2c3010dff81f15740b7") + wallets = append(wallets, "0xf5496f4fc9bda4625e1d47bc138dc3898c8a4166") + wallets = append(wallets, "0x0776643aebe5e77c4c582eecade2758475ac982c") + wallets = append(wallets, "0xd97cb79933f1ac305547902efd11139b00b62390") + wallets = append(wallets, "0xe7d6b71f216584c065157998619debb2ac552b1d") + wallets = append(wallets, "0xdb754d78f0aadbc99d9fa553de43651fcba967cc") + wallets = append(wallets, "0x1d5648056319856d656be25ef82ed0a939abf40b") + wallets = append(wallets, "0x8237eba1329db5f3c35eaddabc066b9c04ef8c91") + wallets = append(wallets, "0x16737008d81b168f4421509f9dc9a0e1747c7dc5") + wallets = append(wallets, "0x3b061acca3aac31531cbab53ec3d0f1b309c1104") + wallets = append(wallets, "0xb27bf00e49c92263df61a1d305386396d6a222d9") + wallets = append(wallets, "0x23b2d63af1d570f37c7fa7f0e90c8461eaab9399") + wallets = append(wallets, "0xa3931582ffa1bf2c57f082ff1b4716052e62b116") + wallets = append(wallets, "0xc3ab7116458b6f0a21ea0f70388a050c3c42d06e") + wallets = append(wallets, "0xf2c988a0381d48a9540ee366eecbbdf542265ab6") + wallets = append(wallets, "0x2198d9210bf4333b613b48baec34d5e9d31f155c") + wallets = append(wallets, "0x1c2fb74a66d858c83ae25f1425c814fa43b521d3") + wallets = append(wallets, "0x4a226b9674974958063d9b8d544c133907afdf46") + wallets = append(wallets, "0x4fe1c3f6da0c98da991c89c13a63e97d982dfc81") + wallets = append(wallets, "0x2e0553b0f5e6114ab6ec4962a225b43fe32b7e5e") + wallets = append(wallets, "0x168824be9ea7606506420029760258be2f8c6752") + wallets = append(wallets, "0x6f781bf07eeda3d853eb8edb76dcc874cdc161c7") + wallets = append(wallets, "0xf981b7c7580c167aa1bbda78a32fb65df3b86385") + wallets = append(wallets, "0x28ca217c8088e4e0195a7286be7ab2a2d0555a56") + wallets = append(wallets, "0x77d5f451a8f9a0b89377f7ee8c028a453d3386c3") + wallets = append(wallets, "0xec505dc418f902f6826b70fa9166cdf5e0d84c4c") + wallets = append(wallets, "0x3ad740f5e141fdb1f77f84450d5e95347cc41025") + wallets = append(wallets, "0x341cbda04e1b4329a849427d1d8b0c8413486d89") + wallets = append(wallets, "0x18b48ff1680c910cbbe6d231f65a06815ce0dd77") + wallets = append(wallets, "0x158502c2623c84012735a18c7b395757db031801") + wallets = append(wallets, "0xaccb457dd2f693899fc5361d6ee4feed0473def2") + wallets = append(wallets, "0xfe65a9d596c006b8f33b00baa815043319b054e6") + wallets = append(wallets, "0xb6dcbf84ece9370f9421e4bd7b55598e7b555e7c") + wallets = append(wallets, "0xfc87b6b9347e56b36a90e00115b3efe629f182ca") + wallets = append(wallets, "0x019614e4495ae9f35e4a8b8056581ce7121be9ae") + wallets = append(wallets, "0xf1928d1d659e65a2438dd42ee00dec4a5d804467") + wallets = append(wallets, "0xeaa8dbc883ff8c4f78aba840d8547eb519b7ec90") + wallets = append(wallets, "0x63570e8347336f0c832e754924468a405f0e3481") + wallets = append(wallets, "0x6a8ee16b7e98248a14bf26d0a01c4c4bb49d2e9b") + wallets = append(wallets, "0x65851145eb7c1103d719e15198a5ab4ce7dc6352") + wallets = append(wallets, "0xe53db325115cbafb27e38f519c0e2c2bd1599931") + wallets = append(wallets, "0x8f0f311c0d168b2f8ba26fc54e34760b031cac48") + wallets = append(wallets, "0x193fd48ee0a70d78c880122f150bf87815f3290f") + wallets = append(wallets, "0xc9e7e84e9b5a2f2b9b75212bb360b8d7494b820c") + wallets = append(wallets, "0x927febd5152fb1ba84b16d2bb1f483d32c54ca2d") + wallets = append(wallets, "0x0f9adaaccd7caecc5019194e15ad19624fed95fa") + wallets = append(wallets, "0x931b6d6855194ae24b7f4cb471d0c8537be6275d") + wallets = append(wallets, "0x3ab1af76c1c965c513e4e5042c9fa799f122b308") + wallets = append(wallets, "0xf4de67bfc24f796ce4519dfe9420bdfcdce9f095") + wallets = append(wallets, "0x75cbe0ea9d63e2ff5ffd749fc3d40d4c895fc21a") + wallets = append(wallets, "0xd7a9a026887085d86a31a103801ccef2fbca88d4") + wallets = append(wallets, "0xf2af4df52b0e0c66fb2dc4e7cf036c85d933b5ed") + wallets = append(wallets, "0xd59323dc0b1c2253c77d98e3b513dcb6a60fb75d") + wallets = append(wallets, "0x67769dc6a774efc6cc9c89d9ea3494600cbb284c") + wallets = append(wallets, "0x5a352b05acfbe3024ac8f4b07b5bcf1d1278246c") + wallets = append(wallets, "0x2c8db089fea64c31437cd1f75a65e49ecbb2f7b6") + wallets = append(wallets, "0x7dfa8bb13fc2079e59c81fca18450fd300c94e1d") + wallets = append(wallets, "0x1b2d4b548870d57d169df323de58d5b6698be8fd") + wallets = append(wallets, "0xe2bcbbad1b644306e4b00067368978b7f45a0b64") + wallets = append(wallets, "0xe0568365a57a08cf066fc00e4512cdf7b0fe87e0") + wallets = append(wallets, "0x563315a0ab7f319a6293613d3a0d10413beca4e1") + wallets = append(wallets, "0xf4013518c4a50111b16fed6391647f714ceabb4c") + wallets = append(wallets, "0xc42807d20f5042304426e2e1fbd935ecbf366457") + wallets = append(wallets, "0x9bb8a65946ff85dae62361d5c4f323914ca2d956") + wallets = append(wallets, "0x54898610e68d5823e708b9f2958643b0ddc70cfe") + wallets = append(wallets, "0xa0dfcd873350b8ee0850d6ab1db19ff6207a3ed4") + wallets = append(wallets, "0x2896aaab6b6b22584e725e8c12968beeb7f41a2d") + wallets = append(wallets, "0xfa27271571524ce659b3fa765e2140bb23eb7a59") + wallets = append(wallets, "0x58b54f94624919fab3aca05426d7ad99603f87e7") + wallets = append(wallets, "0x1e3712ccb1874da92008cb571012085490fee960") + wallets = append(wallets, "0x2785d3fc7db4f3e12959c2afeeb58add3be71fed") + wallets = append(wallets, "0x47bd3ce19c97868f9d2cc5540b68c35d0201dc8a") + wallets = append(wallets, "0x1f12b79311b65c3ef06f2f1c3689759f1f57da6c") + wallets = append(wallets, "0xbdbb117b381b1b35e7e4881b769927b40969a182") + wallets = append(wallets, "0xd3da64a4eb1d9906056eab5a33fba03c3b424b16") + wallets = append(wallets, "0x81d01cca738c23cd50041ad469c2f256bdba2119") + wallets = append(wallets, "0xe1bb30874a0e0c95dc899fce2bc51faea8506fc6") + wallets = append(wallets, "0x2c7f67e0597ab55a78619c200f6841de078cc625") + wallets = append(wallets, "0xbef8d34930f437123411afaa76fd0cef10a7ab56") + wallets = append(wallets, "0x531313191bdd26e9c26f0c31004509eb6f7af0f6") + wallets = append(wallets, "0xe892f464c2bb24176242c99fe77cac4456ab405f") + wallets = append(wallets, "0x78b4733fef7ee3a5e233d9d7840ac7af174ca2ad") + wallets = append(wallets, "0xf151a72f8771b74cfd3305664fae65665687456f") + wallets = append(wallets, "0x4805bcc6efaaedcf7003626da7b4e10900ac5884") + wallets = append(wallets, "0xc6b93ae8f2219c6e86c4ecfb4325da707b690b51") + wallets = append(wallets, "0x98e72bafb250e402a792e86fcf2aee8098e64fb4") + wallets = append(wallets, "0xfad72582ead34adb914c55b1ea89a16f89f5197d") + wallets = append(wallets, "0x3e63a201c6ea7bfb0ea9f0d6b52bd8c2da5f4be2") + wallets = append(wallets, "0xc75276a94348e4edc5a8ecc8461e89236f96ced6") + wallets = append(wallets, "0x41794b8644ff1c170f843fc697b38e24d7355e24") + wallets = append(wallets, "0x0009aeda83031d10d12c006e70baab6fb5d3ea4f") + wallets = append(wallets, "0x4a92560c84e522819d9785a13d6adc44cddefac7") + wallets = append(wallets, "0xfdfb3cfba09dd468292d070e3fe41881f403fc75") + wallets = append(wallets, "0x869e512e18de67c4a621480291925149569b6f31") + wallets = append(wallets, "0x7dccc722fc4e735339e3ba21440db15b22e0c162") + wallets = append(wallets, "0xb10e80ecd16274b778522f9e0f603e799649c9f8") + wallets = append(wallets, "0xfbefce6921280ace471e575c0f763550deaa2cdd") + wallets = append(wallets, "0x69f7cb0494e03512aa3f9174bb9b83d586956fec") + wallets = append(wallets, "0x525e3011f77019595bfb954a11876c02c0929b10") + wallets = append(wallets, "0xfab3ae8d5fc9e1ca8d7e04415d0bfcdff0c4493f") + wallets = append(wallets, "0x4fb2e0afa34fa2033405ffcf6d84fce6b3dd433a") + wallets = append(wallets, "0x8bd63b729f236bee124d02bc9783caf92660f6df") + wallets = append(wallets, "0x05dc0570b0c5c24d4971b7a2aa45e276508f5c9d") + return wallets +} diff --git a/app/upgrades/v20/fixes/daia.go b/app/upgrades/v20/fixes/daia.go new file mode 100644 index 0000000000..e7d062dd89 --- /dev/null +++ b/app/upgrades/v20/fixes/daia.go @@ -0,0 +1,35 @@ +package fixes + +func AddMissingWalletsDaiG(wallets []string) []string { + wallets = append(wallets, "0xf144b018f64b3bf343511362376bebe366de6af7") + wallets = append(wallets, "0x14f446a9ac7a7ee9b8240f1abde4feebe04fb485") + wallets = append(wallets, "0x869e512e18de67c4a621480291925149569b6f31") + wallets = append(wallets, "0x0c881cd49d7ed845b48f345695f3c153071b646e") + wallets = append(wallets, "0xe431610b57aa6d8b4d959d86ae8410ae2a970b14") + wallets = append(wallets, "0xbd654d605d149f7a8bdf4d48971d67c3063664d3") + wallets = append(wallets, "0x820498afabfa9734b25d4c12a2bf954fe7c11d27") + wallets = append(wallets, "0x5c379f83d3d07126d6af369f54e960feadd14c02") + wallets = append(wallets, "0x1d5b33c83e284b7894c073fed950d95f8384dd05") + wallets = append(wallets, "0xd954a8efff9fb88ef13321c32b1b89245c173996") + wallets = append(wallets, "0x69ccbe7591d191eb875f66b9a2a3260b4f0e4fb9") + wallets = append(wallets, "0x6a606a5efd89ebe41e2cb304d2373515f8565cea") + wallets = append(wallets, "0x5caf11880cc35ec13c5a50d891a97a672dccc0a5") + wallets = append(wallets, "0x32515491a6994ef5cf42d062d79f65452448efb0") + wallets = append(wallets, "0x7e94100d7a169cf9c03a5aa99b1b68318adfbe32") + wallets = append(wallets, "0xb804224f45da11fdc2aed1b136b6aab24e3a416c") + wallets = append(wallets, "0xe2a36ceea3c16349ed991a52bcf5fa74f041c132") + wallets = append(wallets, "0x08e8d5a485d25cd9e6f4e09a92fb7e6f02dad4af") + wallets = append(wallets, "0x6d39dbfe15aefd0e697b892371be9b23d38bcc19") + wallets = append(wallets, "0x50cc722a55f6699b00477e47b0e34b9c199f6b01") + wallets = append(wallets, "0xb4e7494c986ed4bfdb6cb966a4403a6557753985") + wallets = append(wallets, "0x66046266e73e9aa7b91eff66c61c931fc69f9ce8") + wallets = append(wallets, "0x6ff56eb310d8f32452b9c42be434fefee2a5e315") + wallets = append(wallets, "0x2406690c1513b0e9f6fb5084d8c956b0d9fc6d08") + wallets = append(wallets, "0xfcd2ce20ef8ed3d43ab4f8c2da13bbf1c6d9512f") + wallets = append(wallets, "0xc3ef6458b92a6ebfade52b74e451c861cce73b9c") + wallets = append(wallets, "0xcb4b45d5d3ff1910e91116af5c8c4408d0d2a32e") + wallets = append(wallets, "0x5b86ec47d360bcdb5623856c8bc528717308c596") + wallets = append(wallets, "0xf5bf6743d0882a1bac982eeb6deb5a5147f95064") + wallets = append(wallets, "0xdf1a7f5a513abdd51f0669c3797261d5a5749523") + return wallets +} diff --git a/app/upgrades/v20/fixes/graviton.go b/app/upgrades/v20/fixes/graviton.go new file mode 100644 index 0000000000..b6f4218ecd --- /dev/null +++ b/app/upgrades/v20/fixes/graviton.go @@ -0,0 +1,121 @@ +package fixes + +func AddMissingWalletsGraviton(wallets []string) []string { + wallets = append(wallets, "0xc19168ebff0d6af1c77c2a39d8723aa305389f42") + wallets = append(wallets, "0xcd1ae66689229afb16aeb67d8aa40f23fd400aec") + wallets = append(wallets, "0x1e6999a5466bc1102e2fdfde7edce4eb7fa56ab5") + wallets = append(wallets, "0x61dc9d1e33dce953e11bf33b5c8f98efb007d8e9") + wallets = append(wallets, "0xb9155f50aef813ca1adc0f6518bb98c27642522a") + wallets = append(wallets, "0x95d24fb39ebd4730e6412972f046db229e925605") + wallets = append(wallets, "0x5a352b05acfbe3024ac8f4b07b5bcf1d1278246c") + wallets = append(wallets, "0xc42587d4ca9ffced65115b4c5e25127379c82299") + wallets = append(wallets, "0xe3c9b5d16fc22dd86c22415d918b6945f4a5f123") + wallets = append(wallets, "0x2c299d53ec142366342b0726861798e4eef5020e") + wallets = append(wallets, "0x6f7b5ab424eae43be8f751ec7f6358e831ca3fff") + wallets = append(wallets, "0x7a5f3e1eef70766351d38ce4eb08d854a8e13a5b") + wallets = append(wallets, "0x869e512e18de67c4a621480291925149569b6f31") + wallets = append(wallets, "0xc59a0ca431216f10cd5c11831b9628182fa3ac3e") + wallets = append(wallets, "0x9404edca6201a45805c98aaa625c977405ccb308") + wallets = append(wallets, "0xc2871545088781378c6f3c27a732733c8b30b1da") + wallets = append(wallets, "0x13089ecddd446b4af44f08f33829df2f854c9c69") + wallets = append(wallets, "0x8881898ab018738c7ce955f1e677a924330a5a7e") + wallets = append(wallets, "0x86a0e49250d4a1c3b675f5faf77dbd6fd85bbf98") + wallets = append(wallets, "0x9345b21e4b04b1b05231565e15748bfe46e1b7d5") + wallets = append(wallets, "0x5439927defaa31ac1a3992ae5cab4908b6f751a8") + wallets = append(wallets, "0x0d82735e0ea93f1de338e0d913ea4eac944f7b4e") + wallets = append(wallets, "0xd6cccc18603aedcc33a95e3754791c025b631659") + wallets = append(wallets, "0xdff371e1b813a506ffd64c56f97f2fbd58c8d2c0") + wallets = append(wallets, "0x945e6bc0d80420f9eb4a70f7d7b00ea8b0651e9b") + wallets = append(wallets, "0xc3aadd74976a6ca763ec21d2c3252ad7cf3eb5a0") + wallets = append(wallets, "0xb143f858d6a9b1df49aa3b2151f1cde93b419ae6") + wallets = append(wallets, "0x1991a6b734e5275233f4e0c675b7e48254988d57") + wallets = append(wallets, "0x605b9b8bb82ccff12946b89e5b416b5a4f6cb42a") + wallets = append(wallets, "0x964828786385cbc0443303b3a20c6ab8f51515f3") + wallets = append(wallets, "0x471d0f69e9beee118b26df912ad5784f49a0985f") + wallets = append(wallets, "0x8e5291f30ca5e45a9877aa76dec3f4469309a087") + wallets = append(wallets, "0xe878ddd1e687c211ce3cde90021cf8d0dddbffdd") + wallets = append(wallets, "0x69ccbe7591d191eb875f66b9a2a3260b4f0e4fb9") + wallets = append(wallets, "0xc7fe05a0aa0b5553a84e28c6aaf089ed7bf6afe7") + wallets = append(wallets, "0x6cfe788cc6421456f8487776587db31eb175a56d") + wallets = append(wallets, "0x06bf9f42e7275fc59162c32e22aacb8b0b2531db") + wallets = append(wallets, "0x2c28ed87ac8030f6413dbc8ff9ffefa62925cf3f") + wallets = append(wallets, "0xf0724a3b204e82f0c02dea5376233cc6116eb877") + wallets = append(wallets, "0xd954a8efff9fb88ef13321c32b1b89245c173996") + wallets = append(wallets, "0x51c529ca0a8fadc3f0138c5c4e8cbf1539722716") + wallets = append(wallets, "0xde0734aa6a66f7c5d25ee07fccde0b35ea4ccc4b") + wallets = append(wallets, "0x861bbc8c3eddf4b3d900df9e2d8e4d10d9acfdd8") + wallets = append(wallets, "0xd14ab343e7f750311af62b82aea5481f13480605") + wallets = append(wallets, "0xcaba2926977dd0680123620b2745a85bad14b816") + wallets = append(wallets, "0xf1e0e48641881d9845d23a52207fa5dd359708db") + wallets = append(wallets, "0x16f04722feeb47799749b711ed9dd6bdf6f46328") + wallets = append(wallets, "0xbca2621fd7b9c18b3dc3133a0187ba6a11d97c63") + wallets = append(wallets, "0x8803ca3934e75208a25c92fade26ca02b5eb18ac") + wallets = append(wallets, "0xb9babfbe65146d7661de980be5995bdd1fcf6cbe") + wallets = append(wallets, "0xd5fdc7790ca6a881e5067bc0d73406de1e2dc59e") + wallets = append(wallets, "0xfae879edb88fc045664c363dfabbe4540438805b") + wallets = append(wallets, "0xbbdd4849f37fb1c4720f5192477517618d738431") + wallets = append(wallets, "0x899a1bcbb0009d26ff0715375ff25a9cda9b4cec") + wallets = append(wallets, "0xaad790034f58862a300986d2d859641c62df4ebf") + wallets = append(wallets, "0xadc8b15a7bd8d3b4b73708bc839be2fd2e5b05b1") + wallets = append(wallets, "0x1165cc27da7a4606692dbdae20bb12d638db7db5") + wallets = append(wallets, "0x0cb63719d7fbb807f82423ca42cc3506a5aedc10") + wallets = append(wallets, "0xac3a94da16b99622744d39eabfa8a50787d91cc4") + wallets = append(wallets, "0x1ffdad3de4d0541ed5561ddf6590df17f205c733") + wallets = append(wallets, "0x22bffe416c2f21c7bd901c9e56d4f71c76e41f57") + wallets = append(wallets, "0x12676c89f5081ed94e1125e85b82d6b59f36ec18") + wallets = append(wallets, "0xae7ee3e3ab06c55179fd529a512f3188b1e4e074") + wallets = append(wallets, "0xbd7373b3fd1210adcf2b1b5d2df2a936aa79334e") + wallets = append(wallets, "0x5362fd4056bffea276abf67fbdeb99e64873c715") + wallets = append(wallets, "0x47f186d4a7567df0fac30369270f131892d5efa3") + wallets = append(wallets, "0x35fbb1befa203760e857688fe9221f8150ec3ee1") + wallets = append(wallets, "0x56fc062fe2aff42dd7456b0ecf4a2f9ff225c434") + wallets = append(wallets, "0x697cde59ac9916a6891560d4bd16a83808f4ef8e") + wallets = append(wallets, "0xf556a555817a106ce3930c61f65bcdacc5f37b9b") + wallets = append(wallets, "0x3337613c7a83ec2b4287aa0999cf801f8f683846") + wallets = append(wallets, "0x32b43363375dd364f938bcf3996776f4c4f22197") + wallets = append(wallets, "0x21fbcde968d472ca8ffedef3ef4bafd61e1eb19c") + wallets = append(wallets, "0x1b658411b71a22f03947d134104a3a890cdc4e7d") + wallets = append(wallets, "0xdb0132c875ea7a00c4a6283da592ae6500205396") + wallets = append(wallets, "0x0752fc3c2d0c57e9d8b64740c99d72ff5e38cbb5") + wallets = append(wallets, "0xdeeef701c02bbfcc685fcd32c5f29361ea4a3b14") + wallets = append(wallets, "0xdddd5af8b69a75bfc0d62b412e97b0fceb58cd2d") + wallets = append(wallets, "0x10d1a68de901955b684fb1d55fcf306ccdc430e9") + wallets = append(wallets, "0xcd5561b1be55c1fa4bba4749919a03219497b6ef") + wallets = append(wallets, "0xf92ffc1f68f6e092c73db3602fd918ac96b5b41b") + wallets = append(wallets, "0xfe77f7efa0f3da316bae80b5ac55b2046d058db5") + wallets = append(wallets, "0x18233f548849786d7e467ca0fe7f9863e61bdfc4") + wallets = append(wallets, "0xc8fe7f624c0236b8b0ee16dca68d444949f0484f") + wallets = append(wallets, "0x3e63a201c6ea7bfb0ea9f0d6b52bd8c2da5f4be2") + wallets = append(wallets, "0x382b5fea05feb98ecb8d708026b91514197826fe") + wallets = append(wallets, "0x688c7fa4921c889508111610d484e7e51f8c7dc3") + wallets = append(wallets, "0xd8c84eac995150662cc052e6ac76ec184fcf1122") + wallets = append(wallets, "0x7b0062dbe18a9427db8739f6000bd707765ceda9") + wallets = append(wallets, "0xbb6e38d4b912f7e2945090e6dca3dc6dc337d7b0") + wallets = append(wallets, "0x525e3011f77019595bfb954a11876c02c0929b10") + wallets = append(wallets, "0x3690934a774758c73bbcb99b7704b3a4848fd1bf") + wallets = append(wallets, "0x8c84b51cc60af077c1b5b339a43841bffb5a1902") + wallets = append(wallets, "0x5fb56612bd54da76fcd95f0618c314116b9e7b72") + wallets = append(wallets, "0x82d5f8e1fbc73e1e2a8e074b8934bd997c6a17c8") + wallets = append(wallets, "0xfcd2ce20ef8ed3d43ab4f8c2da13bbf1c6d9512f") + wallets = append(wallets, "0x6c2693f5a936f37ed03cfa8465bf2d8beff19a0f") + wallets = append(wallets, "0xd3c1292e294f77286735a29e7cdb3ae1845a904f") + wallets = append(wallets, "0xc3da629c518404860c8893a66ce3bb2e16bea6ec") + wallets = append(wallets, "0x6f0a7775892ba5ba123fea65289faa5808d19b70") + wallets = append(wallets, "0x02899e083dcb403ba1a1e325c95551c5fe0da817") + wallets = append(wallets, "0xdd8b5bdf603da498af17afadc56aadc4cd7152fd") + wallets = append(wallets, "0x869e512e18de67c4a621480291925149569b6f31") + wallets = append(wallets, "0x46a20e5e0ceb64ed58f5d29233479d8337408bd3") + wallets = append(wallets, "0xfe36fa1294009c6c0abd1f7f1f4e0face79f5891") + wallets = append(wallets, "0x9a49575d906cf471a72a26bacc5ecd550bdf8c4a") + wallets = append(wallets, "0x38a08fcd1d06dfcc53672a1abfed1e99b3856712") + wallets = append(wallets, "0x9db3f35966f046763404eaff6b4de979ae94b481") + wallets = append(wallets, "0x272568528a7361e61c121033fbcd91f98430c1cd") + wallets = append(wallets, "0xb9248d897239aee554ac509acc73760375ddd33d") + wallets = append(wallets, "0xd301193a0d39e7c70ae74ac604f1d001698439a5") + wallets = append(wallets, "0x365bdad878285b34000d285d0533178f9c51b8e8") + wallets = append(wallets, "0x6f7b5ab424eae43be8f751ec7f6358e831ca3fff") + wallets = append(wallets, "0xc2871545088781378c6f3c27a732733c8b30b1da") + wallets = append(wallets, "0xc59a0ca431216f10cd5c11831b9628182fa3ac3e") + wallets = append(wallets, "0x7a5f3e1eef70766351d38ce4eb08d854a8e13a5b") + return wallets +} diff --git a/app/upgrades/v20/fixes/missingWallets.go b/app/upgrades/v20/fixes/missingWallets.go new file mode 100644 index 0000000000..e6ea0032ea --- /dev/null +++ b/app/upgrades/v20/fixes/missingWallets.go @@ -0,0 +1,135 @@ +package fixes + +import ( + "fmt" + "slices" + + sdk "github.com/cosmos/cosmos-sdk/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + "github.com/ethereum/go-ethereum/common" +) + +func GetAllMissingWallets() []string { + var wallets []string + // DAI-AXELAR + wallets = append(wallets, "0xf3c623b226331ee73b14e7b2b2025bd8be85db92") + + // TORI + wallets = append(wallets, "0xfd729ccb71863f3ff7e2aa92acb6940a21d64911") + wallets = append(wallets, "0x73668ef732b66f1841c8b8ef4fd16bb9570ef038") + + // WETH-AXELAR + wallets = append(wallets, "0xf1f007c47d5afb09d327c1edc8c9c63a027f6f66") + + // Wormhole Bitcoin + wallets = append(wallets, "0x440a1ef3c8e25475f4f3d546172ecaca0ddf62bc") + + // Axelar + wallets = append(wallets, "0x3edcdf87403200b14ad117b24b9de6777751d3a4") + wallets = append(wallets, "0xaec7342c2cf450f5538e91125566f2a77a851595") + wallets = append(wallets, "0x6433a9e9834e004cf129a73992e2ca70625162f2") + wallets = append(wallets, "0xdee2a06e21336152d089ced6699efb0d7bdc0dc3") + wallets = append(wallets, "0x4c42bd1f74b3e93873c54d8116571ec33184704b") + wallets = append(wallets, "0x34b5eba8cfc392634ec292886121c23c2cc420fe") + + // USDC Axelar + wallets = AddMissingWalletsUSDCA(wallets) + + // Graivity USDC + wallets = AddMissingWalletsUSDCG(wallets) + + // WETH G + wallets = AddMissingWalletsWETHG(wallets) + + // Graviton + wallets = AddMissingWalletsGraviton(wallets) + + // USDT Kava + wallets = append(wallets, "0x75656beebb6213709bab9ecb2a9f5191a781e3e5") + wallets = append(wallets, "0xb97ee67e5f3fd3e2c22ded8ed6ca19693181d72d") + wallets = append(wallets, "0xbb4d2dcaa5412040c59de4a1ff576289da83f9a3") + wallets = append(wallets, "0xc71c9bed735b6e6423624b8c17099e553367a474") + wallets = append(wallets, "0xe0568365a57a08cf066fc00e4512cdf7b0fe87e0") + wallets = append(wallets, "0xd499b248b8ee592b424fbbeac115b9a5733e2508") + wallets = append(wallets, "0x23c1e98ed321b41ab6592ef6f08d2f506d02b1a4") + wallets = append(wallets, "0x77ee032a4c0dca739512191e2f2a4fbd54738853") + wallets = append(wallets, "0x18233f548849786d7e467ca0fe7f9863e61bdfc4") + wallets = append(wallets, "0x22922f2086edd7b2ee47673409c4c1dd3403a503") + wallets = append(wallets, "0x67c301eda4e11cce806cf0cda323aa556004b851") + wallets = append(wallets, "0x028f17575aa7f6b98da6661473b9488d6ce9dddb") + wallets = append(wallets, "0x028f17575aa7f6b98da6661473b9488d6ce9dddb") + wallets = append(wallets, "0x2406690c1513b0e9f6fb5084d8c956b0d9fc6d08") + wallets = append(wallets, "0x2406690c1513b0e9f6fb5084d8c956b0d9fc6d08") + wallets = append(wallets, "0x9c0f498d69df554682e8bd8c0ec1d71fac76ec91") + wallets = append(wallets, "0x272c35eed0e96c0bf05d0d4071545e1e92d5206a") + wallets = append(wallets, "0x02899e083dcb403ba1a1e325c95551c5fe0da817") + wallets = append(wallets, "0x6a31c8b9a783aece03426efb5b29984fea16cb3c") + wallets = append(wallets, "0x7c7f3837d43d9af9a2a3b5ac082178173bd4d708") + wallets = append(wallets, "0x57d539ad75e1ae12ece5a405d898916a6fb68faa") + wallets = append(wallets, "0xca282181defb61269dbbfb183c554a7d4a4a204e") + wallets = append(wallets, "0xc3ef6458b92a6ebfade52b74e451c861cce73b9c") + wallets = append(wallets, "0x769249dce2065e677699a94b9c0bb46f079a90ac") + wallets = append(wallets, "0x19fb3225b9512090a3b2d35cc516af77249fb650") + wallets = append(wallets, "0x9c0f498d69df554682e8bd8c0ec1d71fac76ec91") + wallets = append(wallets, "0xafc86dd630a8814f9650cd2312217eb4617fb9b7") + wallets = append(wallets, "0x0c0d535f1683e78dcacf1a7702132853ec9d7d67") + wallets = append(wallets, "0x14cba0298c152d9cd1cd70008a45dbf3708eaafa") + wallets = append(wallets, "0x5e5577032c0aa883d8ea401d64606c07dacaf338") + wallets = append(wallets, "0x4cff6ac23f7b51b0569bc6b8abca43f98f74cbfc") + wallets = append(wallets, "0xb6e2be59dff3b394ad77508527f375a257a4738e") + wallets = append(wallets, "0x18233f548849786d7e467ca0fe7f9863e61bdfc4") + wallets = append(wallets, "0x6a1d542fe756394fb27b724d22dc1b288ad241c6") + wallets = append(wallets, "0x4c3914ce2381d1f8cafb4efc363325fd54ee5ee3") + wallets = append(wallets, "0xaf06613e7d5e58458e647d9da6780cf481887900") + wallets = append(wallets, "0x886435885f29353c5b32583b50ebe4233ada0808") + wallets = append(wallets, "0xc00c068d8f98997ecb8f2080f427c4c9466b9317") + wallets = append(wallets, "0x1afd31627170607657224ed4ae701470209c4b2e") + wallets = append(wallets, "0x0c1d72fbb8b8c19440c4d96b3b1b2e8d4aa5dfb4") + wallets = append(wallets, "0x028f17575aa7f6b98da6661473b9488d6ce9dddb") + wallets = append(wallets, "0x67c301eda4e11cce806cf0cda323aa556004b851") + wallets = append(wallets, "0x22922f2086edd7b2ee47673409c4c1dd3403a503") + wallets = append(wallets, "0x6302f228a9cecbd771d1875060d378cc1797487a") + wallets = append(wallets, "0x235177452a2b37d2770c35ff9b669a8fe894accd") + wallets = append(wallets, "0x2406690c1513b0e9f6fb5084d8c956b0d9fc6d08") + + // ATOM + wallets = AddMissingWalletsATOM(wallets) + // !IMPORTANT: transaction found using the finder binary + wallets = append(wallets, "0x22cbe6caf10f40bc143a7762e2b4c007c95f6c16") + + // StEvmos + wallets = AddMissingWalletsStEvmos(wallets) + + // TetherG + wallets = AddMissingWalletsTetherG(wallets) + + // Osmosis + wallets = AddMissingWalletsOsmosis(wallets) + + // TetherA + wallets = AddMissingWalletsTetherA(wallets) + + // DaiG + wallets = AddMissingWalletsDaiG(wallets) + + // Unique filter + slices.Sort(wallets) + wallets = slices.Compact(wallets) + return wallets +} + +func GetMissingWalletsFromAuthModule(ctx sdk.Context, + accountKeeper authkeeper.AccountKeeper) (Addresses []string) { + missingWallets := GetAllMissingWallets() + for _, wallet := range missingWallets { + ethAddr := common.HexToAddress(wallet) + addr := sdk.AccAddress(ethAddr.Bytes()) + if accountKeeper.HasAccount(ctx, addr) { + fmt.Println("Account existed") + continue + } + Addresses = append(Addresses, addr.String()) + } + + return Addresses +} diff --git a/app/upgrades/v20/fixes/osmosis.go b/app/upgrades/v20/fixes/osmosis.go new file mode 100644 index 0000000000..7528479470 --- /dev/null +++ b/app/upgrades/v20/fixes/osmosis.go @@ -0,0 +1,538 @@ +package fixes + +func AddMissingWalletsOsmosis(wallets []string) []string { + wallets = append(wallets, "0x17c949a0b34bc3a7bf61741bf094808dd000444a") + wallets = append(wallets, "0xef31007a5adfca8769d8ab4fcf63940798606442") + wallets = append(wallets, "0xfee78cb84e811ec4820efe679c0106bb4638d8ec") + wallets = append(wallets, "0x2798f2d3661f59d8ce21e8595320372dcc2ca12a") + wallets = append(wallets, "0x1214672ec404d3978b59014d5094ac4d8bb96023") + wallets = append(wallets, "0x1e43f962d66d87565cc9d367503e9a9f131e4ae5") + wallets = append(wallets, "0xce9162606c2d4c0c32c2f3ade6a8fdddd914f070") + wallets = append(wallets, "0x0b792043406ac25af11f6af7d06555683bd0e375") + wallets = append(wallets, "0x0b792043406ac25af11f6af7d06555683bd0e375") + wallets = append(wallets, "0x43f29bc790dc90a6d4e98f31459d0628d8dbecc9") + wallets = append(wallets, "0xd8168ee3c37c36248ab892c28ed104a387a5aea2") + wallets = append(wallets, "0x5c24891bdd7f781e598d5f8a6d1086850c721caf") + wallets = append(wallets, "0xef3ef24f2766dbc6768533531e74d017da7fadc3") + wallets = append(wallets, "0x92692d78f4857b02066aa9e1e9f99a4820fbcdc3") + wallets = append(wallets, "0x13154b52ae46326d013e6c33e3b0c2242ccf754a") + wallets = append(wallets, "0x8676deb61f9f890e2acb6b2aa8d15a482614a331") + wallets = append(wallets, "0x14f446a9ac7a7ee9b8240f1abde4feebe04fb485") + wallets = append(wallets, "0xe878ddd1e687c211ce3cde90021cf8d0dddbffdd") + wallets = append(wallets, "0x1279206c9705dd06c6ac23fa4622803652bbe75e") + wallets = append(wallets, "0xed0c5634cdd468f1831d514724e6394db251f9f2") + wallets = append(wallets, "0x53d19237a7973bed1eff2b242ca940abce1c36f3") + wallets = append(wallets, "0x90b85e24230f31a2dddd4c75c6cc64ac7ff3f1fb") + wallets = append(wallets, "0xdf3e0247e76d90c3fd5aca3464698bd46385bbc2") + wallets = append(wallets, "0xecf35b37771f2362f97feb37ccfecd9253df007b") + wallets = append(wallets, "0x9ed50f22a1a392f014946319792b09765ac067b1") + wallets = append(wallets, "0x034d0266bf0708d8f02fb2a2f92be0dfaab23dc2") + wallets = append(wallets, "0x63675c6b100041eb99c8d0472db77c463b78ea0e") + wallets = append(wallets, "0xdb561cfba7f207c9af722e4cc65e4b52353b394b") + wallets = append(wallets, "0x700278f088115db20c3727790e17fd2a2bfb6fd6") + wallets = append(wallets, "0x7e94100d7a169cf9c03a5aa99b1b68318adfbe32") + wallets = append(wallets, "0x58addbb787ac7e7cc38358f6f3c2756c0608d876") + wallets = append(wallets, "0x807051d3e89a7eca0af16e2330828076c85060b1") + wallets = append(wallets, "0x22da864d1333f781caed3ff59a2000c5ba1533b8") + wallets = append(wallets, "0xefc236f130330dde3b10bbcf790450060f9fbbe0") + wallets = append(wallets, "0x52dda904b261bb4cb2f4b3c6b8aec6e049b29d04") + wallets = append(wallets, "0x542cf37c74b0d14016ac38c89ead959487c21d2b") + wallets = append(wallets, "0x51977d5cde42fbcf9f153faf5a916740caf78ae1") + wallets = append(wallets, "0x4f26c2a118c265fe4120b92c2ca097da60ca164e") + wallets = append(wallets, "0x11589ec22c36f0e7a378fa4d8673f0663b6b8143") + wallets = append(wallets, "0x394c23b891147c1b0b1ff2c97de17f3f60117910") + wallets = append(wallets, "0x72a2f0ad40ab76fa9d3252c2778d5fd2537f7a0d") + wallets = append(wallets, "0x961639f5aa0a7e23ee8eee007ed365de97bccc5e") + wallets = append(wallets, "0xbec9dba14f406675f6f4c0cfa046bd79d3c823ee") + wallets = append(wallets, "0x7b3eafdbb00574ca1e8e92bb7db0b1e2414e84bf") + wallets = append(wallets, "0xfa2abe5898a38833fd65b94c113bae2e01a38732") + wallets = append(wallets, "0x1ff7ac8dfcef62c4fb7cfaf0692893dc41dd2856") + wallets = append(wallets, "0xbc41544e6a96ee34658eb63a9312bf242468bb52") + wallets = append(wallets, "0xf51d0ed6cdd83312bd5282cfbc7b5f21e36bd33f") + wallets = append(wallets, "0xd33aa395dade083db7c017635dad7d5af425c507") + wallets = append(wallets, "0x60a6ebd1b9a2f8a04aacf7fea5afcf45a2b75886") + wallets = append(wallets, "0x80157ac05d7d1a8e1136222be3d10d52114e9d80") + wallets = append(wallets, "0x0c690440720f274d7567efcee42663d93b0b79a7") + wallets = append(wallets, "0x034d0266bf0708d8f02fb2a2f92be0dfaab23dc2") + wallets = append(wallets, "0x6a26b9076271072e58eead064d900919bc36f2e3") + wallets = append(wallets, "0x807051d3e89a7eca0af16e2330828076c85060b1") + wallets = append(wallets, "0xbb58200d12023653b062d483961a91e35dda2bf1") + wallets = append(wallets, "0x58addbb787ac7e7cc38358f6f3c2756c0608d876") + wallets = append(wallets, "0x0044b1e3c03f589fec419218507dc0fa4709c1a9") + wallets = append(wallets, "0x63675c6b100041eb99c8d0472db77c463b78ea0e") + wallets = append(wallets, "0xbfa79f14ba349bee3edd0fef0d4277fae6c6e865") + wallets = append(wallets, "0xdb561cfba7f207c9af722e4cc65e4b52353b394b") + wallets = append(wallets, "0x9b5fbf37752d8e3a49828123ba144ad4c09c7357") + wallets = append(wallets, "0x54f2d5c298c991ed63836671fbcff3102ab8bba1") + wallets = append(wallets, "0x5fb0668f35130fd1688fc89b494b535632d4f059") + wallets = append(wallets, "0x700278f088115db20c3727790e17fd2a2bfb6fd6") + wallets = append(wallets, "0x7e94100d7a169cf9c03a5aa99b1b68318adfbe32") + wallets = append(wallets, "0x8562839b30d694c442b146f1d28bb100d2ca0963") + wallets = append(wallets, "0xd07810b083597f2d286784de347e4366b83ca134") + wallets = append(wallets, "0x22da864d1333f781caed3ff59a2000c5ba1533b8") + wallets = append(wallets, "0x488507cd54508d191fd98cbfe8b747e49af32462") + wallets = append(wallets, "0xefc236f130330dde3b10bbcf790450060f9fbbe0") + wallets = append(wallets, "0xd063b3401932766b0541611b92cc748da8dbdcba") + wallets = append(wallets, "0x11589ec22c36f0e7a378fa4d8673f0663b6b8143") + wallets = append(wallets, "0xd0c83c8e00ecea3f676b31037ceef97c3609d04b") + wallets = append(wallets, "0xe29384756fc54ddd2a275ab8836bbd35346a1bc2") + wallets = append(wallets, "0xdb3de0a35e9562312889d979a8160af72520fe13") + wallets = append(wallets, "0x394c23b891147c1b0b1ff2c97de17f3f60117910") + wallets = append(wallets, "0x10c40d50fee34a75252491447079a568b6ebdaf7") + wallets = append(wallets, "0xbec9dba14f406675f6f4c0cfa046bd79d3c823ee") + wallets = append(wallets, "0xaeac1f8ac5d1073c9c131ff13607e7e80d00dab8") + wallets = append(wallets, "0xbc41544e6a96ee34658eb63a9312bf242468bb52") + wallets = append(wallets, "0xbfd32d0c787b1c1015ee400fd3bad975736edbb0") + wallets = append(wallets, "0xf51d0ed6cdd83312bd5282cfbc7b5f21e36bd33f") + wallets = append(wallets, "0xf097d113c8b1474115fc9c95ea2ac0d0745643a2") + wallets = append(wallets, "0xd33aa395dade083db7c017635dad7d5af425c507") + wallets = append(wallets, "0x80157ac05d7d1a8e1136222be3d10d52114e9d80") + wallets = append(wallets, "0x1adcf07389b1f6605c44a7683c50a5243829a92c") + wallets = append(wallets, "0x0920b97181144c313775cc454b75904c98ee7645") + wallets = append(wallets, "0x1ffdad3de4d0541ed5561ddf6590df17f205c733") + wallets = append(wallets, "0xbb1651d1ca72ea586c64656acf92de6451f146c9") + wallets = append(wallets, "0xdb3e98b2714206fc01bbbc99aa9464cd2bb8466c") + wallets = append(wallets, "0x024e1e0b63c788e344c1a044547d0fb98e68718a") + wallets = append(wallets, "0x083eef848a202f3a60798d8374426d47da1aba3b") + wallets = append(wallets, "0x9b138f5f01ed38cfb506d2f0a15f65d53d200ae7") + wallets = append(wallets, "0x7c279e31b848b620dcf91196c0b9703e1ff66cd9") + wallets = append(wallets, "0x158677285d3a751fc7828d595fb3dd682cae4b60") + wallets = append(wallets, "0xbdc80be16ab79785ba8bc1b451359eda45accdbb") + wallets = append(wallets, "0x559911156971f5057853a278b05aa870ef3528de") + wallets = append(wallets, "0x79a8d023650424927c2f10ec0722e5f938388f4f") + wallets = append(wallets, "0x79b487b1a88a42913007a02940086cc2f0066dba") + wallets = append(wallets, "0xd3dcd6062a9b8723cc0c6918899eac01f6c69dac") + wallets = append(wallets, "0x026574ba7c1c59d42df787920dedd1a96fb5a524") + wallets = append(wallets, "0x2452ad7b3267a16714736b97c580b0eaf08e704e") + wallets = append(wallets, "0x03840eb0e9e11777ff1cba8b58d0c245ecc43cc6") + wallets = append(wallets, "0x43fc1f21f4c849559c4125cd4252dfc7fe526818") + wallets = append(wallets, "0x48fa020c33341cf7139fba1ec283a658a7ba786f") + wallets = append(wallets, "0x66ac1521d49ee47a8a55e2534ebdd5a9991a9808") + wallets = append(wallets, "0xf309ecc934ee311d11baa10f022f6b4d85cf9f1c") + wallets = append(wallets, "0xe1d0f89af41484d56c4c583e54a96c06558cc924") + wallets = append(wallets, "0xc07cdba2403b161459384850f21e85ad38a474d3") + wallets = append(wallets, "0x2e89ab73f725b0467d0951e1e86fd0b8f45cde30") + wallets = append(wallets, "0xb9cf332531766b6eaa3299e05229bca2ff4269c5") + wallets = append(wallets, "0xf1a7ecce1f30546a7dd3b9007ef6e0964fec1a86") + wallets = append(wallets, "0x2282b24c89f1d92ffba894bd9f18ab55a2872194") + wallets = append(wallets, "0xe272a25b3b30a6c76ab15224f24eaaeed24abed9") + wallets = append(wallets, "0x7c279e31b848b620dcf91196c0b9703e1ff66cd9") + wallets = append(wallets, "0x158677285d3a751fc7828d595fb3dd682cae4b60") + wallets = append(wallets, "0xbdc80be16ab79785ba8bc1b451359eda45accdbb") + wallets = append(wallets, "0x79a8d023650424927c2f10ec0722e5f938388f4f") + wallets = append(wallets, "0xb03aa9957acbbc17568050c244b4b9d532c1f6f8") + wallets = append(wallets, "0x79b487b1a88a42913007a02940086cc2f0066dba") + wallets = append(wallets, "0x81b1e05b70310035f0190b2fadd9ab185ab61925") + wallets = append(wallets, "0xd3dcd6062a9b8723cc0c6918899eac01f6c69dac") + wallets = append(wallets, "0x3d8f7505857dd43af35dc67682ecab35f405a6eb") + wallets = append(wallets, "0x2452ad7b3267a16714736b97c580b0eaf08e704e") + wallets = append(wallets, "0x616a02740f5688a3d6ffcdfa4446f4e51e305370") + wallets = append(wallets, "0x03840eb0e9e11777ff1cba8b58d0c245ecc43cc6") + wallets = append(wallets, "0xfdcc14bd5e1c712cd7bda0b11c28b024d9257da4") + wallets = append(wallets, "0x66ac1521d49ee47a8a55e2534ebdd5a9991a9808") + wallets = append(wallets, "0xcde1026445750ac25d07c1378fff1e81c0848152") + wallets = append(wallets, "0x071a563f71c9df832bc53b79e10dea1839672f94") + wallets = append(wallets, "0x2322ae80d2a6887ae0e265a33877d4d701235fdd") + wallets = append(wallets, "0xe81f4d3c0f3bd9f60a025fc05cc0c9a3c13d00e4") + wallets = append(wallets, "0x80ca9f51bdf0c4e82fbaa1d3acc1862905065eae") + wallets = append(wallets, "0xcea2a2ca9c2383ee57cf458b985b38c955b94d2c") + wallets = append(wallets, "0x9ed28c9a528918c1cf0a9f884edd0686dec06374") + wallets = append(wallets, "0x14daa7def2d5b0129d26b54b68dd48f54b1a27f4") + wallets = append(wallets, "0xa061e7856e358859183c372f1c6c510d7b387268") + wallets = append(wallets, "0x96ed7364c53243bb3d16c0cfd1454e38d506680d") + wallets = append(wallets, "0x9915a95c82ae274764fa9e527d7b5dc0c191ec6d") + wallets = append(wallets, "0x632769d478aaa18238d8517ea365cb5865934a6a") + wallets = append(wallets, "0xedd832310c3381232b43d78718fcb732445b8d62") + wallets = append(wallets, "0xd7a9b931e2e2534ec6d6079e6f57912e909d3e50") + wallets = append(wallets, "0xc09fbb2180a4712095c6d673784fff2569389501") + wallets = append(wallets, "0x936053f4e0c32ec9b4fd9a39279a60413ae15f5a") + wallets = append(wallets, "0x8b6e8f5bd0127fad7ae023828cfa0a0a2d14fc81") + wallets = append(wallets, "0x9cdf2f40854abb8ed636f82e3d7db727ebebd0bb") + wallets = append(wallets, "0x2ae52f6e93872a9eb38be09c80b78db3bb128d73") + wallets = append(wallets, "0x4104d9dce3b5f9897241b2563919207abd5ac1ca") + wallets = append(wallets, "0xbfdb7518d080cc62dddd616dad624159ac5ff66e") + wallets = append(wallets, "0x5571821a8242b997fecfbf6c982dc3c46e8a4475") + wallets = append(wallets, "0xae3bbffec01179af99403718d74bfb8c3d0e403c") + wallets = append(wallets, "0xd3d2f7704fe3836c7ce3b91e45e727368361d911") + wallets = append(wallets, "0xbe1a501375252683483ea591cf7165229d9d8f02") + wallets = append(wallets, "0x3d6bed68d14253bda1018113ce01d0d9513a95d1") + wallets = append(wallets, "0xbcc13edc9da83bbc4bdd41f3e3a791fb2f3b2882") + wallets = append(wallets, "0x2ae52f6e93872a9eb38be09c80b78db3bb128d73") + wallets = append(wallets, "0x4104d9dce3b5f9897241b2563919207abd5ac1ca") + wallets = append(wallets, "0xb11343a3eac84158da755b7d176539c975de7a5f") + wallets = append(wallets, "0x57a3acb7c91ddfc3398a5ed45008ec8bd397c6c0") + wallets = append(wallets, "0xbfdb7518d080cc62dddd616dad624159ac5ff66e") + wallets = append(wallets, "0x5571821a8242b997fecfbf6c982dc3c46e8a4475") + wallets = append(wallets, "0xae3bbffec01179af99403718d74bfb8c3d0e403c") + wallets = append(wallets, "0xbe1a501375252683483ea591cf7165229d9d8f02") + wallets = append(wallets, "0x5939236d7658be17280df143e011d6d436ea4f98") + wallets = append(wallets, "0x9707223a2bed68b72e470ed02ef92c15d553688d") + wallets = append(wallets, "0xec11d7988659c7b58a8b11851a21b1eb8ab2d8e6") + wallets = append(wallets, "0xfbd2ac59b033fd299b048f300a1a297696b98d12") + wallets = append(wallets, "0x04048986afc09a8a18b5cc0cd8c4160c4ad7c144") + wallets = append(wallets, "0x3b02ef2f57b7d8ee9ccbb2ef2bd9073a1e081d50") + wallets = append(wallets, "0x995a5f8eddac88ee4ce89f4a319e800814938039") + wallets = append(wallets, "0x40e87b64d29777bc7c4c7b0572cba7d24fd5b95c") + wallets = append(wallets, "0x42659a4a4b147c184dfaf35a467a7745b9cf20bf") + wallets = append(wallets, "0x775712e9d159672be99a1b39a49e2ebd5ac35ec4") + wallets = append(wallets, "0x70189663d9d82ce5db28b4fdc41ba0b8d3788bd3") + wallets = append(wallets, "0x4792b46552ff43695c7b52fa111d293523521d8c") + wallets = append(wallets, "0x7540ca8906357dcaf518d0e78b6f354268a0c736") + wallets = append(wallets, "0xc910cb5af2e92b8fc361946ae427c5b37367b81c") + wallets = append(wallets, "0x48e3626232fdf39c9b3e08b5deac2a17326feb05") + wallets = append(wallets, "0xfaf3c2965475c42de10e76c1b428f3dcbdc2c4b8") + wallets = append(wallets, "0x5146e8a27fb68c5ece6971632b1f41a5173f3bf9") + wallets = append(wallets, "0xc3e6827cbb90db9e3b28fd06f801a921c18c1ed4") + wallets = append(wallets, "0x0238a5787669c0e0155b68dff7e035cd27a25483") + wallets = append(wallets, "0xb6d475aa4baec2055c66a1255d5bb9ec394a39b0") + wallets = append(wallets, "0x11aa807ba40992765e2544af075a713f8b4a3b42") + wallets = append(wallets, "0x02e4e3e08efbb6a934040f8354c8c42906ddc9ef") + wallets = append(wallets, "0xe98eedd31a0a6aff02bd304ca2cae44a7bcd6e98") + wallets = append(wallets, "0x13c31fad312d3f7d3e52a29032f2c936ae34d93f") + wallets = append(wallets, "0x24ca41a2f44c7b35448743ecb5d31ae6147a7d07") + wallets = append(wallets, "0x8c567dbdeef7ff087e697d04dbe6f7e8e6bf90ed") + wallets = append(wallets, "0x3ddf47806191cda68969679bee7df6f05a58ad76") + wallets = append(wallets, "0x2bc3ca92d876b1e9c728113f5b5828e80e4d53cd") + wallets = append(wallets, "0xc8fe7f624c0236b8b0ee16dca68d444949f0484f") + wallets = append(wallets, "0x33e6e690a77e5d49584a6b91fe3632fb66f8d750") + wallets = append(wallets, "0x9105b14e096580b4f3aada24f1e2799370b2d0b9") + wallets = append(wallets, "0xc2be160c1dbee67a268d87402c55402fd33e0e2c") + wallets = append(wallets, "0xfd8a005082e406215c9e85e712a88167ba691792") + wallets = append(wallets, "0xf21205cddcb5fd31aa9962ee57064cf5ccd0b4ca") + wallets = append(wallets, "0x2c6fd882e87f0263958015ed36c47d7fa838f8cc") + wallets = append(wallets, "0x5701c9c250c2d0f83f558b7a2d5add6c7c430f75") + wallets = append(wallets, "0x1141c59a573b52725a219545c456190739fed131") + wallets = append(wallets, "0xd4d16fdd50889c1d717e2ca10c8839020724a461") + wallets = append(wallets, "0xa9372adce121b60ff8fc7fe36991c81bc8fd8092") + wallets = append(wallets, "0x50c9779b3906b2e644c45b858d1c615c4de1735e") + wallets = append(wallets, "0xa1b195284871334f58e0717d76dcdea0ebed1089") + wallets = append(wallets, "0x0a778f8808c41f4ac71c1a0c708e673dff6b90f0") + wallets = append(wallets, "0xec2275eb25f6403619c858fdadc31e0bd76faf3f") + wallets = append(wallets, "0xb96d138874ed22a90befbc2d919402f1e9b3a942") + wallets = append(wallets, "0xdbd0d56895408a9ec391bf07df2562fe9842f86c") + wallets = append(wallets, "0x1daad627ad95026bfdb4d767f428321778d01c8a") + wallets = append(wallets, "0xcbd1fd614a7dc5e894f77688a9674ce1cf00d30f") + wallets = append(wallets, "0x3cc5ff41b0e3920ceed1bc846aeab09bc70bc03f") + wallets = append(wallets, "0xc2c735899a45b3946e3a3649c8febf4eafc69a9d") + wallets = append(wallets, "0x269f50b7639ae38f729b06d967fe4fe765c7c62f") + wallets = append(wallets, "0xe5d0eac34d4d972c10c46a910890d28eabd3adff") + wallets = append(wallets, "0xfa38f38faadb43f23612155bed51bf99fe1a0f61") + wallets = append(wallets, "0xec6275175c2dd7bfd9d629cc7f26c636e921adf6") + wallets = append(wallets, "0xa5a625aa7c0d2ac7c5b94bb1d4e901127ae927a8") + wallets = append(wallets, "0xadb59a7507c0c2887f295cbb3b96999e9b8a7cf8") + wallets = append(wallets, "0xd4ac1f50ca3808c6d85dc123631fbe7d50140252") + wallets = append(wallets, "0xc21bec5125c63a523272d506ca43a58762b41b4b") + wallets = append(wallets, "0xfa1ae9a0b1c9b6d4cad91a3d00f5b6f9562c294c") + wallets = append(wallets, "0x9fc5f551e8513bcc6bf151e1612531babcc71fb2") + wallets = append(wallets, "0xde0734aa6a66f7c5d25ee07fccde0b35ea4ccc4b") + wallets = append(wallets, "0xa179a0be4db9454ea18df50d26014b9da6e98674") + wallets = append(wallets, "0x122cc9202228c561fc04cd0450bbd89fa5ad7514") + wallets = append(wallets, "0x5fda464a15df52b2a947aa4807036f3b331c81ac") + wallets = append(wallets, "0xd395c5e4dc62d54f699dce186f2dd89bc540be85") + wallets = append(wallets, "0x926784b1e8facd2dbb564b00cefe3e53643adfc2") + wallets = append(wallets, "0x83af626f2ad579e1d2de6709e3a73b5e614a36c1") + wallets = append(wallets, "0xe945bbce84c1962d5de68a68fc114b6e1998c68d") + wallets = append(wallets, "0xd954a8efff9fb88ef13321c32b1b89245c173996") + wallets = append(wallets, "0xaef9fc4f400a6804de8f2601489d1c6f65843cf1") + wallets = append(wallets, "0xe8016b9dd356b7f24da71592e2c2b40bd393c728") + wallets = append(wallets, "0x67b8beadc6b5a7b05aca502ac22e4dfc8f5ea9ac") + wallets = append(wallets, "0x35c5bacbdb311f9ab80fa08b4bf7fbf7b5a9142d") + wallets = append(wallets, "0x613c5cd67120bc1637616495f8e54487d4a25085") + wallets = append(wallets, "0x0a33f60b4c62ea86aecae388319f57dc161a9f8e") + wallets = append(wallets, "0xcfd806f3afc385ba9a3c41365c9f573376e60886") + wallets = append(wallets, "0x6ce3f087f60595abff0ee6f6122f03882a978800") + wallets = append(wallets, "0xd22ddb29a1abae5a5dd4d3cdf7ddb4016c248f5a") + wallets = append(wallets, "0xcfdd66ffa8d8e0aceb02d0719f4319baac0c9ee4") + wallets = append(wallets, "0x6e48428d22f9e7c9de30eaba9dc8ab415c27b5c5") + wallets = append(wallets, "0xdc8f405daf7decc6e4ac59449f72e1666bc4ea05") + wallets = append(wallets, "0x43aa6b8a502ecec9d707bf405b0875d7a422cfc6") + wallets = append(wallets, "0x6f7e02049b13f0f0ef041d8589c607f441790c57") + wallets = append(wallets, "0x229fd64c932e5689a8b1927cfb194bfdac7a5979") + wallets = append(wallets, "0x96e957eaa0048ef57578997205fb856f1c2ac780") + wallets = append(wallets, "0xfedae7f7652543da467188e67d95c881197f9db7") + wallets = append(wallets, "0x4496cf90bfcff428598e5b3e8a32ee0f0b82bbae") + wallets = append(wallets, "0x73e65b0106060066788ca95760c727e48621ff68") + wallets = append(wallets, "0xe8231771ff6ab5fafa24b30a8163da69c2d259e1") + wallets = append(wallets, "0x6fbb7ac34ee8cbe6f3651f411081dd4e25acf939") + wallets = append(wallets, "0xa8413b6debe69e2b15eedda879a4acf535a1ec70") + wallets = append(wallets, "0x8e5291f30ca5e45a9877aa76dec3f4469309a087") + wallets = append(wallets, "0xb441158577d256ae79e8a56085572fd9ed8d8d71") + wallets = append(wallets, "0xc700694ed60d5f9d20d3d6b5a1da0ef92ec2a64a") + wallets = append(wallets, "0xd99a4f96bca46dc34c51700192e78f8532103a8d") + wallets = append(wallets, "0x4abcb969c55e63a5b6d12f6b468da6d35a2eec31") + wallets = append(wallets, "0x7d13f61fa98ab057c58afe602830c72beb5a128c") + wallets = append(wallets, "0xa13d2da02ac6aa2361cb5a5e56608aaa36a5cc5f") + wallets = append(wallets, "0x5b92e3a13f52dd97ed8d5d1e0383ba537f6ab50d") + wallets = append(wallets, "0x9767549c8941f7ee6dc85ee03f114a071e392774") + wallets = append(wallets, "0xd1619af5d8c55fb425d332f5678e5640985d948f") + wallets = append(wallets, "0x613de6647eb62f65656e2015f395a020f4d98af6") + wallets = append(wallets, "0xcdf747f054e25f4dc2e4c431ba845e4d1a7aaaa0") + wallets = append(wallets, "0x7a9a4c920a69b4418101964ebc57e84236f613bd") + wallets = append(wallets, "0xb381a2b980b2b9ff2c79dff9be13e066c865d61d") + wallets = append(wallets, "0xe7e37da9e8e3f783849b80796b5c811d2213f6a9") + wallets = append(wallets, "0x2f1bdb3eb6f40a5b5376cab148d2e75b342f2faf") + wallets = append(wallets, "0x66c44144d030e7b23c4b5f2b177f473746ad1e74") + wallets = append(wallets, "0xd9807fc6611be8f3c24df6fc06a202d80a521c86") + wallets = append(wallets, "0x8d1509e0240eba23cccd58941fa2b5d7ff1fc70f") + wallets = append(wallets, "0xc2552747697ad2eea67dd75e10f7933a62ceb64c") + wallets = append(wallets, "0x3418d7d519442a8890b7ce75d6d206be62a564af") + wallets = append(wallets, "0x08d2c744fd60f2dca8c1885d3aa03ff6d3fa5d11") + wallets = append(wallets, "0x5925fae4fc9fc087ce117aae58a1cac732371a25") + wallets = append(wallets, "0x48706176617eabb33e504240d473820de62fb06d") + wallets = append(wallets, "0xa4f6b087d1b1e1b5e6052a19499cc62418509152") + wallets = append(wallets, "0x3337137166a76d2bddefa54adfed7b44fc2c812e") + wallets = append(wallets, "0x7d11a1dce951de5c6b2292bad583244df8028f8d") + wallets = append(wallets, "0x4a1dff8f8a84461da17554a0135829a24e7972c5") + wallets = append(wallets, "0x583efa869e4c14cf972e84daa724bf9dc7f9c440") + wallets = append(wallets, "0x99113537601b087788bf89a70787aae25636c344") + wallets = append(wallets, "0x902d842b4fe45db9d8ed0abbde7053e7ee142232") + wallets = append(wallets, "0xdf4868f3387fe0efa63e99aef55b38edd28e5c2d") + wallets = append(wallets, "0xb4a37162249b8bb2099dcda2b73160a0d5000650") + wallets = append(wallets, "0x7aae86ef246a1a93ae5f1455fae8eae4830f6aa8") + wallets = append(wallets, "0xe1690f5153ad0bbc683964aa81645c49b3cf6567") + wallets = append(wallets, "0x057d74ff27e8e59eb1817a56c106d50fc7c2b79e") + wallets = append(wallets, "0xf90a01af91468f5418cda5ed6b19c51550eb5352") + wallets = append(wallets, "0x5440afc3ef2b0af19c358f9d519657a6cc5909e5") + wallets = append(wallets, "0x9037f3d4b0e22247f16de615dae2487656552b8f") + wallets = append(wallets, "0x98e6269f33d3191b6e6dedd01e93c51cc14257d3") + wallets = append(wallets, "0x0969eb4b80cf3920cc9d0069ff9af8ac5f301712") + wallets = append(wallets, "0x22f726908e50bd10f32fe270b7d11130196f0111") + wallets = append(wallets, "0xac40b43838a8b5ca91a1d7e3e000526207aef935") + wallets = append(wallets, "0x45df6a48d823fce185ffb11067e8f6733731e8ca") + wallets = append(wallets, "0x4849bb5bb9e3892b4a93035c43705054352d45f9") + wallets = append(wallets, "0xf470afb25c10b0a638954d1ff7db20861511bf37") + wallets = append(wallets, "0xdc300ddff0ef04e8c9bffa629f63fb9383c6206e") + wallets = append(wallets, "0x144aae52e64866927b4ae57bc8ba1560d788ea73") + wallets = append(wallets, "0x458ee879e7e551cc46ce39b09fb3661063d9a5c9") + wallets = append(wallets, "0x9f914156f4ef42ae375e77270dc452e9b364db4b") + wallets = append(wallets, "0x07c797092c9a6baff2536f3834d6ad10e34f0ec0") + wallets = append(wallets, "0x2af98fed86c717ec283ba9dc4cc8a9b3b227efe5") + wallets = append(wallets, "0x8fb560121a8ddaeeca7ff898b602b147be6ad15b") + wallets = append(wallets, "0x3615719229d6c3a5d7ec7cc6c3072499d23cd06b") + wallets = append(wallets, "0x8338b6515848049d904ecb71ac45c7361c5340b9") + wallets = append(wallets, "0xcb7baf1baa65a2dab21800c9ae42748b384025f9") + wallets = append(wallets, "0x638e21dc5089b7b0bdbd0d61cbdbe43e781b83c1") + wallets = append(wallets, "0xc6117911641959de0dd2ca867b7ebfb987adf02c") + wallets = append(wallets, "0x40023deb422ab808a2258f2b4655bc629a86b62f") + wallets = append(wallets, "0x886ff9ca67d8fbcad2b75f252c4e26cd610044ce") + wallets = append(wallets, "0xf4311c8ac42bd5d9fe7d0de1458749a5932eb92a") + wallets = append(wallets, "0x4063cac2d9fe9dab041e0d5407954d2a177d7fb7") + wallets = append(wallets, "0x97056b5dedad9da66f1982ebb26e57fb225db7cb") + wallets = append(wallets, "0x9b20e577e7ef078d79c25c43eada8f7da18af5f2") + wallets = append(wallets, "0xe73998c33b58d0b9b7fc67ea56299886884e1316") + wallets = append(wallets, "0x4df2460c239661486af8e2dbdb1d767d1f9b78ae") + wallets = append(wallets, "0xdaa914dd16cbb6fefcce34dff7e9a88f8531744a") + wallets = append(wallets, "0x22d4a892a740654157c7c3bca1cb8dab39681983") + wallets = append(wallets, "0x8e5e7109123bffb990b9a8280b309ca06b37a80f") + wallets = append(wallets, "0xd03bddb81f5c0656dc7637a42f40bea765a03cd6") + wallets = append(wallets, "0xbbfcd5c87ed4163b62b7033c69f754301ddce1a4") + wallets = append(wallets, "0x4590ef0b1649a0ceb8923e137e886c248f9c69ff") + wallets = append(wallets, "0x6ad2ca5afc4703d96eb3d1ecd753566591418ecc") + wallets = append(wallets, "0x375fa68c3698dc05cc9882f47c75d418be524aec") + wallets = append(wallets, "0x5cba75e03f88d08b8f7c64fd274e5b1cb60b99fa") + wallets = append(wallets, "0xd5212cb08b86779f61a5bbf38ee9e36f307b5c03") + wallets = append(wallets, "0xfd634a01b4f9262cbeb23eb4c1326826067f481c") + wallets = append(wallets, "0x2e7a872698dabdbeac57905a7c81c0cc3902e9f3") + wallets = append(wallets, "0x710fd6e84bbd947d000c7300506b46f03b748f45") + wallets = append(wallets, "0x8c1c02b422d5011ccd7450cf0b6dafabe1e1a196") + wallets = append(wallets, "0x9b1b8a21c32737712ca4d000c66429b4eb70e2f5") + wallets = append(wallets, "0xd507e9ae6d884f6850b249c04353cde87472355e") + wallets = append(wallets, "0x2406690c1513b0e9f6fb5084d8c956b0d9fc6d08") + wallets = append(wallets, "0xbe715ce8c2540039fbefecf4f5ab32d49e1cf3be") + wallets = append(wallets, "0x37fdf97612fc5c7d1471e80c3a1493f1c645c288") + wallets = append(wallets, "0x5c75d91cfffc2a75ab187ef1324f15eeee7faf5b") + wallets = append(wallets, "0x878c95c94204dc5d5801f16968edb9e2a91609ba") + wallets = append(wallets, "0xc254b302feaf3c9c697b4c1f67aeebb36d7b8f00") + wallets = append(wallets, "0x28abd48c0b494d967c5c62d39839cbf9c98bd924") + wallets = append(wallets, "0x4fa96d31dd15ce27537130d4b56caee0cb436051") + wallets = append(wallets, "0x7514a2d67d3a3d0647285b0313640b8cb3bf1b6e") + wallets = append(wallets, "0x91705bc893e6a8962fecce677937a005490ac911") + wallets = append(wallets, "0xe07850f6769d44bc90d83b3ed88c3a57f84629be") + wallets = append(wallets, "0xe0f324d5e4f6343552241652f6bfe73219960c2a") + wallets = append(wallets, "0x8c2e4c5f20b0a0cce314aad725a390e254577bd0") + wallets = append(wallets, "0x175ea1544bc6ead95840231a6ed4d001b60ad1db") + wallets = append(wallets, "0x82a0881606647c75ed5f50fc4d487dc7944fbc27") + wallets = append(wallets, "0xbfafd2965668478540a78bb8edd261dcf132ea51") + wallets = append(wallets, "0xa830dea7dd905c7e0b1e9a3d0db292406c480180") + wallets = append(wallets, "0xbad10a76aced02c71978da944789236b1bed9278") + wallets = append(wallets, "0x0cc754de8f487b1f5e2172f9cde6cc256e9d2f20") + wallets = append(wallets, "0xf1650051e75dcffa4f2fbf1371452eb399891c68") + wallets = append(wallets, "0xec413be767c9af41f8ad515c653731135a41029a") + wallets = append(wallets, "0xa277eae71507b94dc3b171696cf0d5e712409edf") + wallets = append(wallets, "0xc2569d6354e22e0e957047b0e3c178d86d689d3c") + wallets = append(wallets, "0x9e00abe3f59677100ada3a89884431529052d392") + wallets = append(wallets, "0xf4acf34677f18e12ef1bcfea77f53a242bda8ad0") + wallets = append(wallets, "0x5849ca3cde9d7e8d53d5a24fd5a466b4184e5700") + wallets = append(wallets, "0xfcd903e0c689dd15470197d968b81347a8908f01") + wallets = append(wallets, "0x866cd2842c13ce72248aab1b7bd45d71261eccd2") + wallets = append(wallets, "0x398e1a7ad06250351a8b174ff0e1de9fa8a050c6") + wallets = append(wallets, "0xf55bbd9ea04a64fe6dd7a7ee546b11c035ae5276") + wallets = append(wallets, "0x525e3011f77019595bfb954a11876c02c0929b10") + wallets = append(wallets, "0x7d98e0c9cf39f26154547f2877a42044228598df") + wallets = append(wallets, "0x35d47e8c693975a231ad146bc58f801307f45206") + wallets = append(wallets, "0x303c3d4393293e10db2b153a9c7ef8fc5aaf226f") + wallets = append(wallets, "0xd4d9c2ab83154d82136928db9a98dcaeda262bf6") + wallets = append(wallets, "0x146d6311fe6ac773cfde755d87145de732362e77") + wallets = append(wallets, "0x510a2f6087f72ee3e1cb15144499a2e9ef599fce") + wallets = append(wallets, "0xae93aa85584f5271bd304b0d3e7efc902c91ece8") + wallets = append(wallets, "0xb23535557f6c5de6a8da876371340b7733794d00") + wallets = append(wallets, "0x2251224bbc6387bf57ef69f9b4039230afab290b") + wallets = append(wallets, "0x0d126dc10c22cabc2a5220bd1113eda7e4a38fbd") + wallets = append(wallets, "0xf7dce38b0a9b831269a73073f386d70aba9051e5") + wallets = append(wallets, "0x04bdd823a64cbbaec574e149b131b63b98a89f20") + wallets = append(wallets, "0x94f4c409dc5514624b9c83f6f5f1c5cb00f9e273") + wallets = append(wallets, "0xa1e5f97b5bd410487b96f7aa9b78b9ceb9fd23f9") + wallets = append(wallets, "0x1702d1fc5ef328fe370b2f817487902e35f2f8e9") + wallets = append(wallets, "0x050087c12c537c88f13cf041a9065a74e624d704") + wallets = append(wallets, "0x788d245051645438e4fed7f7b6b63e3c9e070948") + wallets = append(wallets, "0x8eda5b6280b62cdd0f8e61558af4d2cf9cf6ce19") + wallets = append(wallets, "0xec302185ecdd556e9a5290e702d69b7c76390a56") + wallets = append(wallets, "0x38cfc869ac6067f1951440231478f6b8f2b3242c") + wallets = append(wallets, "0x0a12c9ba0d92d8e67762a06998aaa4fb6eac67cb") + wallets = append(wallets, "0x081ad9b41357ec4d79ea245fc582ae3dc74148bb") + wallets = append(wallets, "0x5c693d2e48deabeb1920902446115fededd0fa65") + wallets = append(wallets, "0x886c9f5b3b3efacf68d8c5c78ba13905bf113458") + wallets = append(wallets, "0xa20a92163f3984c9ba94260b1551e1e6dbde9b3e") + wallets = append(wallets, "0x1cce2bb4ef35c8f3b8ae07b266d1ea2ce2eba079") + wallets = append(wallets, "0x9b47a5962065186ef211e9e392e69961ede88d9a") + wallets = append(wallets, "0x6b4a7390597515f044cc3216f628536607baf5ed") + wallets = append(wallets, "0x7edaf229400f118e777893d5362d1f3bde5bfd8c") + wallets = append(wallets, "0xab837b6013a33ecf166e13f5d8c5b5480692a249") + wallets = append(wallets, "0xaa57c4932a93cc50a68653396544a72a5c43d050") + wallets = append(wallets, "0x816f92e24b293eddf6e0a48a5c03690079e76065") + wallets = append(wallets, "0xd66685b74c277ec6544c58f7635724085171b5f7") + wallets = append(wallets, "0x61587de6e9f16df9f7b56ee070976f98ee943182") + wallets = append(wallets, "0xa0ea44b026dfa75dacd0da98e41e0de1ed4ef83e") + wallets = append(wallets, "0xf23b567de98e37552761067e2f6793842784c647") + wallets = append(wallets, "0x5bc3053c3af87587f316cb7527a3fc0601a01639") + wallets = append(wallets, "0x1add4d42646fe5b504dd9505802642df54000b46") + wallets = append(wallets, "0x0695a70d3a19b06df3cf1c9a29a47543cd165d02") + wallets = append(wallets, "0x55e00c8dd4ffca463b099ad3429ac3205552a9ee") + wallets = append(wallets, "0x04a63bbe946d8d47ce1ffb1fde4ef435726dfca7") + wallets = append(wallets, "0xbbcc28f4cda2221fe5a8a19d4a5f2b46dd93cf06") + wallets = append(wallets, "0x64b422c5855f2ddca968e67cf714b5541d7af72c") + wallets = append(wallets, "0x26124e94fe64de733cc42c244010c6b57a1aa6db") + wallets = append(wallets, "0xde4df4cff287cf05ac6b258db81976b524a17e7a") + wallets = append(wallets, "0xb8964fe9055af230d3067681206eb37c2e65dcb4") + wallets = append(wallets, "0xf6e28e1a9e75a82025ec1c76dab702b47ee499e0") + wallets = append(wallets, "0xfac597072546fd466c4dda3f12e7f42bcc741ed9") + wallets = append(wallets, "0xce8060d4b10e53d2b092fc5e2c6b3d43223056ff") + wallets = append(wallets, "0xf3ddb3072454b4b92aa1cf30f95a10a9a27ba9b0") + wallets = append(wallets, "0x435b4f7f61d03199f1ef8ed63d74ad448f185c9e") + wallets = append(wallets, "0x10097c6b0766d24ff7993b8534eaff813bbab9d9") + wallets = append(wallets, "0xba9eb1d9954c4ddbd26ae95c65b278afd24432f0") + wallets = append(wallets, "0xd04533b218fac83ab705c6b9981a424b7a002c6a") + wallets = append(wallets, "0xddf959c8f8e32576fe3ba7ad43f55917f891d4e5") + wallets = append(wallets, "0xb8da225696af43edf4be05b5489745d455bc1beb") + wallets = append(wallets, "0x1c834ec89043aae099ec75c692325fada5717556") + wallets = append(wallets, "0xa2e5bcd5253889f3e2a1c5d7bba5f90ed0d929d0") + wallets = append(wallets, "0x268c869251a97e7775f6b6b74d2c0c593461f5f6") + wallets = append(wallets, "0xda2299c732860d9dc37b71cbfce67c6e38f3b58b") + wallets = append(wallets, "0x3cb4dc6fec6b94f0955635858f8cd03552cb4d80") + wallets = append(wallets, "0x3d532149c8d18395e1ab9135a32836a8c3bd01d3") + wallets = append(wallets, "0x3e1f25906d6a4828f71da2ee8b63feed829a7598") + wallets = append(wallets, "0xec7f73eecd6f7dc3eed659d927527dfd2bd329b5") + wallets = append(wallets, "0xbfca6f261d37908f1b025319eb116c149a4f7e74") + wallets = append(wallets, "0xf51be8615d985515c9f63e48d6d4801dadea4f4d") + wallets = append(wallets, "0xb9db40269351dfcfd1dddd0fc4c3397dab754795") + wallets = append(wallets, "0x13abf9062237ec43ebd596fb2f475c418fc2b4b7") + wallets = append(wallets, "0x7d8432c62752e023f67d21e37fe22c80c350ff1c") + wallets = append(wallets, "0x7bec24370a4e612b1c9c895a7726bb54cb162b04") + wallets = append(wallets, "0x17d8be034d22303c22a6937a54a0d8a595895111") + wallets = append(wallets, "0x71f30adcb6b31dd2983684f2781390f775d91d18") + wallets = append(wallets, "0x21c4dcaea2b0ebaba56127006b9c49e6bc8babf3") + wallets = append(wallets, "0x29c3f6e61cb145700a097499dd8b338ebd291f51") + wallets = append(wallets, "0xd43ccc7f0aeea609a5fd55f68249430d6dde1c6b") + wallets = append(wallets, "0xec26ce8bc76b9ab9465939a7b7fc414ac67dbee5") + wallets = append(wallets, "0xfee12a0a25e236914b736b76bc51900a48565cb4") + wallets = append(wallets, "0x5411581c03b56398ce1d9eb2d54da3c78046c678") + wallets = append(wallets, "0xc926d433bd6b51e1accd7c1f1e7ce3101c03d3a0") + wallets = append(wallets, "0x308f10c01e2d2834bf9cbc5e3abc415451a5f170") + wallets = append(wallets, "0x71fc9f2bd2585b2517c9d32ca57e84b4b4da263b") + wallets = append(wallets, "0xd61b79b7c2b1e8375f5f5f8bee1473ffbe4b4eb8") + wallets = append(wallets, "0xc2871545088781378c6f3c27a732733c8b30b1da") + wallets = append(wallets, "0xcfdd66ffa8d8e0aceb02d0719f4319baac0c9ee4") + wallets = append(wallets, "0xd22ddb29a1abae5a5dd4d3cdf7ddb4016c248f5a") + wallets = append(wallets, "0x6ce3f087f60595abff0ee6f6122f03882a978800") + wallets = append(wallets, "0xcfd806f3afc385ba9a3c41365c9f573376e60886") + wallets = append(wallets, "0x0a33f60b4c62ea86aecae388319f57dc161a9f8e") + wallets = append(wallets, "0x613c5cd67120bc1637616495f8e54487d4a25085") + wallets = append(wallets, "0x35c5bacbdb311f9ab80fa08b4bf7fbf7b5a9142d") + wallets = append(wallets, "0x67b8beadc6b5a7b05aca502ac22e4dfc8f5ea9ac") + wallets = append(wallets, "0xe8016b9dd356b7f24da71592e2c2b40bd393c728") + wallets = append(wallets, "0xaef9fc4f400a6804de8f2601489d1c6f65843cf1") + wallets = append(wallets, "0xd954a8efff9fb88ef13321c32b1b89245c173996") + wallets = append(wallets, "0xe945bbce84c1962d5de68a68fc114b6e1998c68d") + wallets = append(wallets, "0x83af626f2ad579e1d2de6709e3a73b5e614a36c1") + wallets = append(wallets, "0x926784b1e8facd2dbb564b00cefe3e53643adfc2") + wallets = append(wallets, "0xd395c5e4dc62d54f699dce186f2dd89bc540be85") + wallets = append(wallets, "0x5fda464a15df52b2a947aa4807036f3b331c81ac") + wallets = append(wallets, "0x122cc9202228c561fc04cd0450bbd89fa5ad7514") + wallets = append(wallets, "0xa179a0be4db9454ea18df50d26014b9da6e98674") + wallets = append(wallets, "0xde0734aa6a66f7c5d25ee07fccde0b35ea4ccc4b") + wallets = append(wallets, "0x9fc5f551e8513bcc6bf151e1612531babcc71fb2") + wallets = append(wallets, "0xfa1ae9a0b1c9b6d4cad91a3d00f5b6f9562c294c") + wallets = append(wallets, "0xc21bec5125c63a523272d506ca43a58762b41b4b") + wallets = append(wallets, "0xd4ac1f50ca3808c6d85dc123631fbe7d50140252") + wallets = append(wallets, "0xadb59a7507c0c2887f295cbb3b96999e9b8a7cf8") + wallets = append(wallets, "0xa5a625aa7c0d2ac7c5b94bb1d4e901127ae927a8") + wallets = append(wallets, "0xec6275175c2dd7bfd9d629cc7f26c636e921adf6") + wallets = append(wallets, "0xfa38f38faadb43f23612155bed51bf99fe1a0f61") + wallets = append(wallets, "0xe5d0eac34d4d972c10c46a910890d28eabd3adff") + wallets = append(wallets, "0x269f50b7639ae38f729b06d967fe4fe765c7c62f") + wallets = append(wallets, "0xc2c735899a45b3946e3a3649c8febf4eafc69a9d") + wallets = append(wallets, "0x3cc5ff41b0e3920ceed1bc846aeab09bc70bc03f") + wallets = append(wallets, "0xcbd1fd614a7dc5e894f77688a9674ce1cf00d30f") + wallets = append(wallets, "0x1daad627ad95026bfdb4d767f428321778d01c8a") + wallets = append(wallets, "0xdbd0d56895408a9ec391bf07df2562fe9842f86c") + wallets = append(wallets, "0xb96d138874ed22a90befbc2d919402f1e9b3a942") + wallets = append(wallets, "0xec2275eb25f6403619c858fdadc31e0bd76faf3f") + wallets = append(wallets, "0x0a778f8808c41f4ac71c1a0c708e673dff6b90f0") + wallets = append(wallets, "0xa1b195284871334f58e0717d76dcdea0ebed1089") + wallets = append(wallets, "0x50c9779b3906b2e644c45b858d1c615c4de1735e") + wallets = append(wallets, "0xa9372adce121b60ff8fc7fe36991c81bc8fd8092") + wallets = append(wallets, "0xd4d16fdd50889c1d717e2ca10c8839020724a461") + wallets = append(wallets, "0x1141c59a573b52725a219545c456190739fed131") + wallets = append(wallets, "0x5701c9c250c2d0f83f558b7a2d5add6c7c430f75") + wallets = append(wallets, "0x2c6fd882e87f0263958015ed36c47d7fa838f8cc") + wallets = append(wallets, "0xf21205cddcb5fd31aa9962ee57064cf5ccd0b4ca") + wallets = append(wallets, "0xfd8a005082e406215c9e85e712a88167ba691792") + wallets = append(wallets, "0xc2be160c1dbee67a268d87402c55402fd33e0e2c") + wallets = append(wallets, "0x9105b14e096580b4f3aada24f1e2799370b2d0b9") + wallets = append(wallets, "0x33e6e690a77e5d49584a6b91fe3632fb66f8d750") + wallets = append(wallets, "0xc8fe7f624c0236b8b0ee16dca68d444949f0484f") + wallets = append(wallets, "0x2bc3ca92d876b1e9c728113f5b5828e80e4d53cd") + wallets = append(wallets, "0x3ddf47806191cda68969679bee7df6f05a58ad76") + wallets = append(wallets, "0x8c567dbdeef7ff087e697d04dbe6f7e8e6bf90ed") + wallets = append(wallets, "0x24ca41a2f44c7b35448743ecb5d31ae6147a7d07") + wallets = append(wallets, "0xf5c3dbfa53d8131b95a98722cf61392b296298ab") + wallets = append(wallets, "0xd5f2a8446e3644f96d7a7da24c63711ff2a4e4c7") + wallets = append(wallets, "0x3dc36e8244e9a9aef85129475015db6f4abaa3b8") + wallets = append(wallets, "0x852b2b9ca853ab11c767ad8ea1a14d827e55a010") + wallets = append(wallets, "0x3d6061f09f10731d2860004d6b50d22f79a1e77f") + wallets = append(wallets, "0x60041a0c089c7c030c425ec232ec98fb70d4a5ed") + wallets = append(wallets, "0x14c8f3dc8bff69d56268c55df3dbb39b9b767b79") + wallets = append(wallets, "0xa81d5a7aea04e698a652d71241ef6aecfd5728c8") + wallets = append(wallets, "0xea82a3b344a9f5c284881472985715dd08e4a4e3") + wallets = append(wallets, "0x0a32b23e42a15410be09785f5e607126f326eeff") + wallets = append(wallets, "0x65553837360794321f77086b8405423ec981ac59") + wallets = append(wallets, "0x79503d512b54b1a80ab5da537ef4b8fe5f313e99") + wallets = append(wallets, "0x02d9a002e2154b4903e92e00295a1120dcc33770") + wallets = append(wallets, "0x66ed8fd36dec9da16ac5425f4312475f58f3b61a") + wallets = append(wallets, "0x838c360244c67195091aafa83bf451b57638c369") + wallets = append(wallets, "0x5263276095ecda1d36deed6646a639c999979cfa") + wallets = append(wallets, "0x6eeefb3fa4be0a5145bf38b6dff895089c247eb8") + wallets = append(wallets, "0x55bb11f30ed23b19ca5c04e41429d013c46d82f1") + wallets = append(wallets, "0x9d8bcead34f648927d57168922b3e1480bdca1eb") + wallets = append(wallets, "0xbf272b69443efcaa44e26e8062a44c2ab19b11b4") + wallets = append(wallets, "0x8a3bc494b30a49d85f2b9da4a0f9f47e61780a92") + wallets = append(wallets, "0xe6e3af1df4c5f7acb33cca2f8ea72cfde8245a14") + wallets = append(wallets, "0xb559e88de961849abb8bde31b651bfc7ecde1671") + wallets = append(wallets, "0xca65acec482883e410c3cbe94846cd09e542d24e") + wallets = append(wallets, "0x17052f717ac542d321928dda02c2372fc66a8aa5") + wallets = append(wallets, "0x9e868534427c5555ad3101c70a18d2f061adde2b") + wallets = append(wallets, "0x332f4080b9168016f8e0131a951cc0434ed75a16") + wallets = append(wallets, "0x1da48f427be0f89240c40c9d5110b50b4c120b14") + wallets = append(wallets, "0x59be6a7a466b5ce674c50f0a0ab52f1a8f854ec6") + return wallets +} diff --git a/app/upgrades/v20/fixes/stevmos.go b/app/upgrades/v20/fixes/stevmos.go new file mode 100644 index 0000000000..6aaefa7221 --- /dev/null +++ b/app/upgrades/v20/fixes/stevmos.go @@ -0,0 +1,56 @@ +package fixes + +func AddMissingWalletsStEvmos(wallets []string) []string { + wallets = append(wallets, "0x213c90afa27c52c28d48a09d7b34fdb90a323afe") + wallets = append(wallets, "0x623d8f9197a2bc850371252943ce3ebdc6e895f1") + wallets = append(wallets, "0xa52d67ae76ced3f81656b52f7f68d8348e4b36d1") + wallets = append(wallets, "0x68b1467dac5b77d95b53ecc767045564e97c69c5") + wallets = append(wallets, "0x0b557526149591ff779d8aeb2e7c61988b40c9f3") + wallets = append(wallets, "0xa5bc7874c4bb2dd7b1f0f330aed831d89211b83e") + wallets = append(wallets, "0x3aaab60964358fca65e3cd888364d50e850b7d40") + wallets = append(wallets, "0xcca793546a5ca11955a39621458076307f28bdca") + wallets = append(wallets, "0x9500148707d1dba34957f63a18bbd8a4be8cf418") + wallets = append(wallets, "0xb34037e238446b59feb84a12ce6e8cabd853d98e") + wallets = append(wallets, "0xffb3468b6861ba7044fcf61a2d976028204efc49") + wallets = append(wallets, "0x085fe8e11e568f4866a36bbed79ee82a84caf805") + wallets = append(wallets, "0x98cce7ff383106367d447484082c49869f4687d6") + wallets = append(wallets, "0xf2ebee970672ea12e7504bfb192608e80bbeaad9") + wallets = append(wallets, "0x3a5ad7f7e8d8c4accbfbf4975fa46fff030233e9") + wallets = append(wallets, "0xafc86dd630a8814f9650cd2312217eb4617fb9b7") + wallets = append(wallets, "0x3e721ad07b66aba97b61f52fc781ea39c08c1788") + wallets = append(wallets, "0x18233f548849786d7e467ca0fe7f9863e61bdfc4") + wallets = append(wallets, "0xfe75d38b6ef8d1649b7d69a4a044e443c6afe1ce") + wallets = append(wallets, "0x006f28111cdccd261f637e954c76cf45883e15f5") + wallets = append(wallets, "0x583b275f2e8a5418aca34a4ccb1739fdd4789273") + wallets = append(wallets, "0x3dc36e8244e9a9aef85129475015db6f4abaa3b8") + wallets = append(wallets, "0x1bf8fc89f18334be1a82ce7f6288e67d85aea7ff") + wallets = append(wallets, "0x10d1a68de901955b684fb1d55fcf306ccdc430e9") + wallets = append(wallets, "0x4cff6ac23f7b51b0569bc6b8abca43f98f74cbfc") + wallets = append(wallets, "0x2406690c1513b0e9f6fb5084d8c956b0d9fc6d08") + wallets = append(wallets, "0x7e796d919323a3f50d062245d8c79f9f4e21888f") + wallets = append(wallets, "0x250bff984bc20d14b0afa21b0b49a69da4586d72") + wallets = append(wallets, "0x5fb56612bd54da76fcd95f0618c314116b9e7b72") + wallets = append(wallets, "0xb0ec89b8635bba4c20dc0da913d6ca9921632f20") + wallets = append(wallets, "0x42873c4aa0937e8792f66d392a289ddb6361dec8") + wallets = append(wallets, "0x66046266e73e9aa7b91eff66c61c931fc69f9ce8") + wallets = append(wallets, "0xb146844ac6cd89378bbbd4d878c027dd0f4bb165") + wallets = append(wallets, "0xfc53532d7375941993f2992522f1d7fbd6ad3729") + wallets = append(wallets, "0x769249dce2065e677699a94b9c0bb46f079a90ac") + wallets = append(wallets, "0x57d539ad75e1ae12ece5a405d898916a6fb68faa") + wallets = append(wallets, "0x89dd4dad90dc88a3222c17240b51be345c2bbbcf") + wallets = append(wallets, "0x94172ef86cb242b61147fccadf42a38dd03f7d49") + wallets = append(wallets, "0x653683d1ae1f72fecbf4bd00801879c937ffd1e1") + wallets = append(wallets, "0xbbcf3985eb53c30a8eea01d9357314d61fe0e727") + wallets = append(wallets, "0x7c7f3837d43d9af9a2a3b5ac082178173bd4d708") + wallets = append(wallets, "0xc8fe7f624c0236b8b0ee16dca68d444949f0484f") + wallets = append(wallets, "0x2ffb5e5089a6414d3765a6c2c108cb7ca1500232") + wallets = append(wallets, "0xa503ae746877b587fc6056eddcbc9a56891979dc") + wallets = append(wallets, "0xdbaed1f2521fac4feaaa652c141087fb7c65535d") + wallets = append(wallets, "0xf71891fe1086cc4e10cb333541c5b0189735b5e8") + wallets = append(wallets, "0x6bb22bd1aa6f8abc9e3cd47032dce8c65eac1eab") + wallets = append(wallets, "0xc3ef6458b92a6ebfade52b74e451c861cce73b9c") + wallets = append(wallets, "0x02899e083dcb403ba1a1e325c95551c5fe0da817") + wallets = append(wallets, "0xd3c1292e294f77286735a29e7cdb3ae1845a904f") + wallets = append(wallets, "0x6a1d542fe756394fb27b724d22dc1b288ad241c6") + return wallets +} diff --git a/app/upgrades/v20/fixes/tethera.go b/app/upgrades/v20/fixes/tethera.go new file mode 100644 index 0000000000..2c93476fd9 --- /dev/null +++ b/app/upgrades/v20/fixes/tethera.go @@ -0,0 +1,14 @@ +package fixes + +func AddMissingWalletsTetherA(wallets []string) []string { + wallets = append(wallets, "0xce9ebc509f14cef1a37baaaa0e37da62568fd335") + wallets = append(wallets, "0x6d5a1bfb13861c8da5732cdd4f3c512e7ac85a95") + wallets = append(wallets, "0x01f5b36bc7260ac11dfe192c2efc60bdeb5c8b63") + wallets = append(wallets, "0xe2a36ceea3c16349ed991a52bcf5fa74f041c132") + wallets = append(wallets, "0xb804224f45da11fdc2aed1b136b6aab24e3a416c") + wallets = append(wallets, "0x1d5b33c83e284b7894c073fed950d95f8384dd05") + wallets = append(wallets, "0x8303b802a00f998b21a8bcb48c195121e26b6e6b") + wallets = append(wallets, "0xeeacc00244feff0d68a4773547d05c1e24edee7e") + wallets = append(wallets, "0xae49a8b0189521b3c6d0cd7fa62ec2f9036b2d74") + return wallets +} diff --git a/app/upgrades/v20/fixes/tetherg.go b/app/upgrades/v20/fixes/tetherg.go new file mode 100644 index 0000000000..707445da34 --- /dev/null +++ b/app/upgrades/v20/fixes/tetherg.go @@ -0,0 +1,77 @@ +package fixes + +func AddMissingWalletsTetherG(wallets []string) []string { + wallets = append(wallets, "0xfdf7a39803d33cb7d84f9c2c835e2aa05dd3879f") + wallets = append(wallets, "0x0681d7e8e0244675b6f2340f159f80f899ba3377") + wallets = append(wallets, "0x926784b1e8facd2dbb564b00cefe3e53643adfc2") + wallets = append(wallets, "0x8ff83bbd6577963de722e9fdaef226121a9b316e") + wallets = append(wallets, "0x0c881cd49d7ed845b48f345695f3c153071b646e") + wallets = append(wallets, "0x0b154fbd9ecbfd1ddafd117ccdfaaa3bc5fa6ee2") + wallets = append(wallets, "0xf0724a3b204e82f0c02dea5376233cc6116eb877") + wallets = append(wallets, "0x6d5a1bfb13861c8da5732cdd4f3c512e7ac85a95") + wallets = append(wallets, "0xe8231771ff6ab5fafa24b30a8163da69c2d259e1") + wallets = append(wallets, "0x820498afabfa9734b25d4c12a2bf954fe7c11d27") + wallets = append(wallets, "0xbd654d605d149f7a8bdf4d48971d67c3063664d3") + wallets = append(wallets, "0xad0192751b342199599581489c229ee6b5926bce") + wallets = append(wallets, "0x32515491a6994ef5cf42d062d79f65452448efb0") + wallets = append(wallets, "0xbb13b7e8f91ca94a93f8a4fd70d0ebf5b421cbea") + wallets = append(wallets, "0x1d5b33c83e284b7894c073fed950d95f8384dd05") + wallets = append(wallets, "0x209668e22ad026043a70845f1f4edc3eb9b93837") + wallets = append(wallets, "0x1199bb54850508f52c671fceba3c905f8e9f045f") + wallets = append(wallets, "0xc37ef27e563ef632e6732efd049e00fc210acaeb") + wallets = append(wallets, "0x2a6504ac56be733f0af8679f7428996f40067d32") + wallets = append(wallets, "0x523b83d06cbaddd9a847b515e38322c2f5fbc2d2") + wallets = append(wallets, "0x5f6102464f614a6a9a317173c1e38e81caf2193d") + wallets = append(wallets, "0x7c4f61d1b95eb0258f172ddb4c0e1250941ff7bc") + wallets = append(wallets, "0x1f91703c5db47a4658f0e5c30183f2b9bda60e50") + wallets = append(wallets, "0xde8d78b323e1ba04ed9628ae9e2ce386333f3e8e") + wallets = append(wallets, "0x69021801d836e9aec143758cf8ea3dca677e3a24") + wallets = append(wallets, "0xd14ab343e7f750311af62b82aea5481f13480605") + wallets = append(wallets, "0x69ccbe7591d191eb875f66b9a2a3260b4f0e4fb9") + wallets = append(wallets, "0xcafceda42882e2eb89ed3e9009d4ecf5e4246e6f") + wallets = append(wallets, "0x5caf11880cc35ec13c5a50d891a97a672dccc0a5") + wallets = append(wallets, "0x58c680de4b82f48fe34c0dab769c1c1f9fd96470") + wallets = append(wallets, "0x7e94100d7a169cf9c03a5aa99b1b68318adfbe32") + wallets = append(wallets, "0xb89701ed7d8bd1cc981791250c8ac336d730b7fb") + wallets = append(wallets, "0x3a1df5cfd6db9698e624fcfacd8ef59b86afc84b") + wallets = append(wallets, "0xd72b5087540b20d12a0f09b1f49959ec54b24002") + wallets = append(wallets, "0xc910cb5af2e92b8fc361946ae427c5b37367b81c") + wallets = append(wallets, "0xf7c9daebda0aca249cd6352dbd7dd82435fd527f") + wallets = append(wallets, "0xcb177c670523951003eb8eec4265c00ebd116b35") + wallets = append(wallets, "0xfad72582ead34adb914c55b1ea89a16f89f5197d") + wallets = append(wallets, "0xb804224f45da11fdc2aed1b136b6aab24e3a416c") + wallets = append(wallets, "0x91a7a6dde501fa512387da824d98a3f62b1d8ee7") + wallets = append(wallets, "0x5fb0668f35130fd1688fc89b494b535632d4f059") + wallets = append(wallets, "0x02ed7bed488a73cfba89c440b24d21c9c1da3ad4") + wallets = append(wallets, "0x286c0f8c0e02f0f369e74fc7c69387c6cdaa6a28") + wallets = append(wallets, "0x250bff984bc20d14b0afa21b0b49a69da4586d72") + wallets = append(wallets, "0x3e63a201c6ea7bfb0ea9f0d6b52bd8c2da5f4be2") + wallets = append(wallets, "0xc9cb65ab3e5ece4d0b72290760960485dd18d86d") + wallets = append(wallets, "0xf5458f96378484ed9bc7fe678c288a8be964390d") + wallets = append(wallets, "0xdb67d8f84308cdff5a6f1cab9a1e6d0bcf54884e") + wallets = append(wallets, "0x9f125e0ef85df3cf01f8d85847bf939929c49254") + wallets = append(wallets, "0x372f9ae432fecd961f053b29baef00360337705c") + wallets = append(wallets, "0x5b5e44da9718288244110e66a7ca6c537f36f948") + wallets = append(wallets, "0x904986caaf915854139d1f372ed8b2d9d67786ac") + wallets = append(wallets, "0x66046266e73e9aa7b91eff66c61c931fc69f9ce8") + wallets = append(wallets, "0x49a8ddca11a0fa4ce9d7b76c315ffefe8ce28fa0") + wallets = append(wallets, "0xf7908b17c5ea2389117a66582c85500fe26225ab") + wallets = append(wallets, "0x10d1a68de901955b684fb1d55fcf306ccdc430e9") + wallets = append(wallets, "0x869e512e18de67c4a621480291925149569b6f31") + wallets = append(wallets, "0x8bee2be3399bad7bb620e03a3033db80c0429ade") + wallets = append(wallets, "0x7d2b0fb6caa056ce425a09d511161f8f3838fca4") + wallets = append(wallets, "0x4a915fea6ac531213c2d1f261b5a6d376e84e680") + wallets = append(wallets, "0x6178f90d8f3d34aaa36d5acfb2eb6fc57c398219") + wallets = append(wallets, "0x18233f548849786d7e467ca0fe7f9863e61bdfc4") + wallets = append(wallets, "0xc3da629c518404860c8893a66ce3bb2e16bea6ec") + wallets = append(wallets, "0x2406690c1513b0e9f6fb5084d8c956b0d9fc6d08") + wallets = append(wallets, "0xfcd2ce20ef8ed3d43ab4f8c2da13bbf1c6d9512f") + wallets = append(wallets, "0xc3ef6458b92a6ebfade52b74e451c861cce73b9c") + wallets = append(wallets, "0x02899e083dcb403ba1a1e325c95551c5fe0da817") + wallets = append(wallets, "0xcb4b45d5d3ff1910e91116af5c8c4408d0d2a32e") + wallets = append(wallets, "0x04fb30f655700c274ae98a2590f69a3c1299c96c") + wallets = append(wallets, "0x6517029b15127e44e44be1779b0e27584f3ae411") + wallets = append(wallets, "0x721a0dbc366a52e684daae0341163df46f158ab1") + wallets = append(wallets, "0x1ec5d7a34d4a31555df604408f0b769286b93c8a") + return wallets +} diff --git a/app/upgrades/v20/fixes/usdca.go b/app/upgrades/v20/fixes/usdca.go new file mode 100644 index 0000000000..9c4a33b2d2 --- /dev/null +++ b/app/upgrades/v20/fixes/usdca.go @@ -0,0 +1,96 @@ +package fixes + +func AddMissingWalletsUSDCA(wallets []string) []string { + wallets = append(wallets, "0x224a259e475a56d4b36123f48dd8a79213a91928") + wallets = append(wallets, "0xa8e7da5f38667a40e12fb817e7e0a2b760b7a723") + wallets = append(wallets, "0xc40d553dd69ff9a8c63ec1b8052c245d5c89c29c") + wallets = append(wallets, "0xc35a0b554701573de0186315a928e6a7082eac66") + wallets = append(wallets, "0xcb150cf4e948d70e72cf6c62a68380a47acdfff3") + wallets = append(wallets, "0xf6e167a0dc136b6c7617c0da97c05d8aa41cca4f") + wallets = append(wallets, "0xcd2e03e3c64657555506eb625eb8f40a19e718e4") + wallets = append(wallets, "0x054d67a3d574859e5982933e1b5abc573c4d4497") + wallets = append(wallets, "0x140a0c93677606f8f47904fc9dbd34547b66b39d") + wallets = append(wallets, "0xf4ed8aafc9bcae35db4ca9705c950f190b7d1e92") + wallets = append(wallets, "0x2d2171d8e81451e3e0a1e69058b8259ac2c15919") + wallets = append(wallets, "0xe171806a64f6e54a0a0d9de52abc90e79b56656c") + wallets = append(wallets, "0x51a5b5a6da4c99bfce4f52a7402a7b08ceb5ba58") + wallets = append(wallets, "0x9c3eac718c94baf18dc2440b5238727d7bcaa6a8") + wallets = append(wallets, "0x9bc94e4df692814e7caecb5aeb5f4cb4ee1e9ea5") + wallets = append(wallets, "0x65587237b2da6dd70787acd27b277eeabbfcfde2") + wallets = append(wallets, "0x74aae58ecfab8b2d1da26dc248ffa9b3eef98c9a") + wallets = append(wallets, "0xc71b06c337d1ab6fcfdd28df281cd2f401803ba2") + wallets = append(wallets, "0xd0c501c2378fd72436392fc8e8d81d37a54b552c") + wallets = append(wallets, "0x17cef1e15e45d5e629c78a6fcead5d4e03a36be5") + wallets = append(wallets, "0xd47deb9a3ce009c7946ce57579f6f56492669afa") + wallets = append(wallets, "0xe4055ad66e9e17afd1f4e4e44e8c6c4878187c7c") + wallets = append(wallets, "0xca01a1d0993565291051daff390892518acfad3a") + wallets = append(wallets, "0xd4839a77fa90db31c52e468456a54819250bf920") + wallets = append(wallets, "0x75f657924be74a3932f3218fc99091ce183ae59d") + wallets = append(wallets, "0x0d1b0aeb322831120a065fa37039edb79f6e2c62") + wallets = append(wallets, "0x49efee36a95f783165a240e7205ff01d9577f79e") + wallets = append(wallets, "0xa89bef9aac006ee846fd7fd3aa8ee5cb0f502dc6") + wallets = append(wallets, "0x67de9961038f9ff441ed87d713af70e7d40ceab4") + wallets = append(wallets, "0xa158a2e424f42a67235f0de3624210b240b2a1b8") + wallets = append(wallets, "0x1e6950fe92e48f01207ca954b39162191f6a76a1") + wallets = append(wallets, "0x7e19855fc17c96a3515fca9d73bdd00e67a9d4f9") + wallets = append(wallets, "0x2d1e28d237ad38471a24551bc51fe45eb26bbfbd") + wallets = append(wallets, "0xf9a453c734fe350907056b4455e6ed108190aede") + wallets = append(wallets, "0xe4fcb8153ba25ee0c69b0506b54fecf535c04785") + wallets = append(wallets, "0xfb5103f5a1419eff439f3c15f10a0f7aa753540c") + wallets = append(wallets, "0x0c881cd49d7ed845b48f345695f3c153071b646e") + wallets = append(wallets, "0x6d39dbfe15aefd0e697b892371be9b23d38bcc19") + wallets = append(wallets, "0xc6f33d25851fe12e22ec84f9ad76040de81f9851") + wallets = append(wallets, "0xd7166a2e3d1e0b3dd8a00aa82781b89f917d4edf") + wallets = append(wallets, "0xd91b9fd499513e79a4e96d9cab0b3f8059652143") + wallets = append(wallets, "0x1231deb6f5749ef6ce6943a275a1d3e7486f4eae") + wallets = append(wallets, "0x1231deb6f5749ef6ce6943a275a1d3e7486f4eae") + wallets = append(wallets, "0x238b8466cc6e82de2dd22e1538b30851731e0b10") + wallets = append(wallets, "0x5246925920b2d3e9e06de0b9c9e618e5b5f4b15b") + wallets = append(wallets, "0x2557a052e8a9cbad8b47b4d4d4b98a95b00ba45f") + wallets = append(wallets, "0x6e8b1dc1a600a0091c9cf9ca5738a3d47f84a936") + wallets = append(wallets, "0xfbdf7e9796e40cbd16dfeb0db13c9763ede16e9a") + wallets = append(wallets, "0x91aa8b108278d313b96c662aab5bc67d9049a521") + wallets = append(wallets, "0x6e8b1dc1a600a0091c9cf9ca5738a3d47f84a936") + wallets = append(wallets, "0x94f8a0c456e710e9e331727e1d8372592480ffb0") + wallets = append(wallets, "0x7899a0b4f713365a189f485a9a6946ed0446401a") + wallets = append(wallets, "0x5caf11880cc35ec13c5a50d891a97a672dccc0a5") + wallets = append(wallets, "0x9915a95c82ae274764fa9e527d7b5dc0c191ec6d") + wallets = append(wallets, "0xaf5164ad6ff7a0f18819fa31cc008b0a29763d78") + wallets = append(wallets, "0xdbbbe9454e2aa061aa26e9b4369662f901a4fd44") + wallets = append(wallets, "0x31a197e71b636c8657373ec4e9c8c388cc71c522") + wallets = append(wallets, "0xbb6e99fb152c114a7ae49d41658ddc79f2d5d7eb") + wallets = append(wallets, "0x3668b2ed97cb7ce01286907026a66032c57f119a") + wallets = append(wallets, "0x05b95d2c274cb9e9604f495231b3e9e79226f1d6") + wallets = append(wallets, "0x2ed5711d0d722a5a60342985e4e1471f37d9ec84") + wallets = append(wallets, "0x9bb2fac54f168bce6986c3856fcb42d5c365b689") + wallets = append(wallets, "0x7aafe81b79208e618345b27e9e6c8f85f882b171") + wallets = append(wallets, "0xded212e1dbbe9913831199150085d8d12e25bc44") + wallets = append(wallets, "0xc5ffbc479b28070d6911ea5980b979326776a63d") + wallets = append(wallets, "0xc8fe7f624c0236b8b0ee16dca68d444949f0484f") + wallets = append(wallets, "0xf0724a3b204e82f0c02dea5376233cc6116eb877") + wallets = append(wallets, "0x6b7075ee3cedc7f15de15fe0ec66e123ba1a3fbb") + wallets = append(wallets, "0x96e957eaa0048ef57578997205fb856f1c2ac780") + wallets = append(wallets, "0x5f4325b3bd86afeeff8d5a6851241481f9a21672") + wallets = append(wallets, "0xb4c35811b466cbff47a6ffa720ca72fec0445eca") + wallets = append(wallets, "0xb804224f45da11fdc2aed1b136b6aab24e3a416c") + wallets = append(wallets, "0x279e7f7dbe9e34aa1525699577b87c2c43e9664e") + wallets = append(wallets, "0x6bc6e9bff78c939c2ef7af2e248ddfb778b68b52") + wallets = append(wallets, "0xd050b7721f6778af8cb62f1f15cea0f2c8109f81") + wallets = append(wallets, "0x1afd31627170607657224ed4ae701470209c4b2e") + wallets = append(wallets, "0x161c3c998aebbd03b8134d135222e90299899da8") + wallets = append(wallets, "0x006f28111cdccd261f637e954c76cf45883e15f5") + wallets = append(wallets, "0x57c5932738bcc7f1afa50e2b8ed9ad9765e3660f") + wallets = append(wallets, "0x4c3914ce2381d1f8cafb4efc363325fd54ee5ee3") + wallets = append(wallets, "0x583b275f2e8a5418aca34a4ccb1739fdd4789273") + wallets = append(wallets, "0xc910cb5af2e92b8fc361946ae427c5b37367b81c") + wallets = append(wallets, "0xfcd2ce20ef8ed3d43ab4f8c2da13bbf1c6d9512f") + wallets = append(wallets, "0x36cf3381817cd6912ae2e975701b597cf6c44fa3") + wallets = append(wallets, "0x2406690c1513b0e9f6fb5084d8c956b0d9fc6d08") + wallets = append(wallets, "0x06933143320f466a4036fb8d7d260683baed1dab") + wallets = append(wallets, "0xe6893f946dac3563c4a6505ef6d1d1b5a7d2c17a") + wallets = append(wallets, "0x5fb56612bd54da76fcd95f0618c314116b9e7b72") + wallets = append(wallets, "0x6d39dbfe15aefd0e697b892371be9b23d38bcc19") + wallets = append(wallets, "0xc6f33d25851fe12e22ec84f9ad76040de81f9851") + wallets = append(wallets, "0x0c881cd49d7ed845b48f345695f3c153071b646e") + return wallets +} diff --git a/app/upgrades/v20/fixes/usdcg.go b/app/upgrades/v20/fixes/usdcg.go new file mode 100644 index 0000000000..bed841c22a --- /dev/null +++ b/app/upgrades/v20/fixes/usdcg.go @@ -0,0 +1,56 @@ +package fixes + +func AddMissingWalletsUSDCG(wallets []string) []string { + wallets = append(wallets, "0xf539093018cba8474cc4904d0b11c2ecc22d20d9") + wallets = append(wallets, "0x688c7fa4921c889508111610d484e7e51f8c7dc3") + wallets = append(wallets, "0x7b2c360ed6f6c0ac4148e72118d8a12b7bcd7439") + wallets = append(wallets, "0x55ca2c0cc48726472c6f41a29d9d3ae38e867ad4") + wallets = append(wallets, "0xf3c623b226331ee73b14e7b2b2025bd8be85db92") + wallets = append(wallets, "0xaad9aebbb6563c0fd00ffb85e932f8e4e539097e") + wallets = append(wallets, "0x2e6ddcd02bbb9e29a0b4cc4b54c7f9d78b4277d2") + wallets = append(wallets, "0x5200ee16afdeb091d556abeca941d09e26f19235") + wallets = append(wallets, "0xc926d433bd6b51e1accd7c1f1e7ce3101c03d3a0") + wallets = append(wallets, "0xe878ddd1e687c211ce3cde90021cf8d0dddbffdd") + wallets = append(wallets, "0x78b4733fef7ee3a5e233d9d7840ac7af174ca2ad") + wallets = append(wallets, "0xc2871545088781378c6f3c27a732733c8b30b1da") + wallets = append(wallets, "0x944a6276fe44f7ab3b01a0e99577d472e28ef03e") + wallets = append(wallets, "0x0c881cd49d7ed845b48f345695f3c153071b646e") + wallets = append(wallets, "0x6bacc94a11571960543a7861ceb8ebb7b075947e") + wallets = append(wallets, "0x7a1d4bd38d08069402cf2f3ad7881cdc6baeb5c9") + wallets = append(wallets, "0x0fe5e11bc1e29302a7346e615a319b9645e3cc3c") + wallets = append(wallets, "0x2373e53e97eb33895d505c14ac0cda8a66696df5") + wallets = append(wallets, "0x5b325cb24169afc63aa6f8694b947df1e56fc250") + wallets = append(wallets, "0xfa38f38faadb43f23612155bed51bf99fe1a0f61") + wallets = append(wallets, "0xde8d78b323e1ba04ed9628ae9e2ce386333f3e8e") + wallets = append(wallets, "0xbb13b7e8f91ca94a93f8a4fd70d0ebf5b421cbea") + wallets = append(wallets, "0x21aaa8b0345dbdc9b797943894867d9f1d97f2b7") + wallets = append(wallets, "0xfa1ae9a0b1c9b6d4cad91a3d00f5b6f9562c294c") + wallets = append(wallets, "0x38217e938df61518c31af3e7c4628eab87e80b26") + wallets = append(wallets, "0x948473025ba6ad1287d918aaca72c7e57e61de29") + wallets = append(wallets, "0x5a0c711cfc9622428d0a9ae84a14b81d9218802c") + wallets = append(wallets, "0x32515491a6994ef5cf42d062d79f65452448efb0") + wallets = append(wallets, "0xb1513a28af526f7dd428ddb8fbbabebd0ab5fda9") + wallets = append(wallets, "0xda96f7ec9c8c93b804d400608ad1fabb4e14e8a8") + wallets = append(wallets, "0xd954a8efff9fb88ef13321c32b1b89245c173996") + wallets = append(wallets, "0xb804224f45da11fdc2aed1b136b6aab24e3a416c") + wallets = append(wallets, "0x8c7c10e03f195e125af86d9d0ea9448eb8da6173") + wallets = append(wallets, "0x3699659760adfbfcf0883d92d31bbab372c7dec3") + wallets = append(wallets, "0x06bf9f42e7275fc59162c32e22aacb8b0b2531db") + wallets = append(wallets, "0xc83de6e3c8affa0ab3488a6d8a9ef98d9dda8ef6") + wallets = append(wallets, "0xfc2429d8fc16ce82bf7d975686f3eb5f9cb9631b") + wallets = append(wallets, "0x58c680de4b82f48fe34c0dab769c1c1f9fd96470") + wallets = append(wallets, "0x057ae7b17823573f7c1bb2423dd678d8eb26cbcf") + wallets = append(wallets, "0xb1d0f67d3bc2c805bbb719afc6da02f0d03dea70") + wallets = append(wallets, "0xf7c9daebda0aca249cd6352dbd7dd82435fd527f") + wallets = append(wallets, "0xc8fe7f624c0236b8b0ee16dca68d444949f0484f") + wallets = append(wallets, "0x1ffdad3de4d0541ed5561ddf6590df17f205c733") + wallets = append(wallets, "0xfffbda942c44ff345dabdd0305fd91d8b2e478f7") + wallets = append(wallets, "0x279e7f7dbe9e34aa1525699577b87c2c43e9664e") + wallets = append(wallets, "0x250bff984bc20d14b0afa21b0b49a69da4586d72") + wallets = append(wallets, "0xee5695f9d22a7b10e948cf1b03a77575f254ca0a") + wallets = append(wallets, "0xdddd5af8b69a75bfc0d62b412e97b0fceb58cd2d") + wallets = append(wallets, "0x72a5b96a6d40fa6e54f799a1b94ab99d326de37d") + wallets = append(wallets, "0x16544cd394b440dfe4cc5ab2f9cdf479c2fabcb5") + wallets = append(wallets, "0x18233f548849786d7e467ca0fe7f9863e61bdfc4") + return wallets +} diff --git a/app/upgrades/v20/fixes/wethg.go b/app/upgrades/v20/fixes/wethg.go new file mode 100644 index 0000000000..9e3b001d2e --- /dev/null +++ b/app/upgrades/v20/fixes/wethg.go @@ -0,0 +1,66 @@ +package fixes + +func AddMissingWalletsWETHG(wallets []string) []string { + wallets = append(wallets, "0x3977b214694b3dcfedceeefac77d05b68b0aab9c") + wallets = append(wallets, "0x09beca37c5db4a3a8c57b39dce37acffbb55b26e") + wallets = append(wallets, "0xe040369d25e32069145024123554ca98ae84eaae") + wallets = append(wallets, "0xf151a72f8771b74cfd3305664fae65665687456f") + wallets = append(wallets, "0x3b8b7b342d65e360b5eb30c1e5c19ee316efad0e") + wallets = append(wallets, "0xbfd3f5c350eceb6952ef6acb4e7371453fb42361") + wallets = append(wallets, "0x1ffdad3de4d0541ed5561ddf6590df17f205c733") + wallets = append(wallets, "0x945e6bc0d80420f9eb4a70f7d7b00ea8b0651e9b") + wallets = append(wallets, "0x31fb92b9280a5f706151d5eb4e15ab3159c53077") + wallets = append(wallets, "0x46a383b8eb756533f9ec14ea5f80433c43dfdc54") + wallets = append(wallets, "0x20c166ca469e833cd05b6760ae3c283cc617c9bb") + wallets = append(wallets, "0xaa0c7cf76a0fcc2972e682f15f821db8f54b96a1") + wallets = append(wallets, "0xd954a8efff9fb88ef13321c32b1b89245c173996") + wallets = append(wallets, "0xd14ab343e7f750311af62b82aea5481f13480605") + wallets = append(wallets, "0xb2f38155a3a6a455c137f4dc83c0b0e32e9e79e0") + wallets = append(wallets, "0x4e4b39d28a2ac5fdbd6b86629e51d954987d73ec") + wallets = append(wallets, "0x476bec4b7560cab1e6425c5709f39ee8a76a59f6") + wallets = append(wallets, "0xebe6ce0bbe92323eb319ec6fabcd44d8a07bdb5b") + wallets = append(wallets, "0x093b3d645710f49b6049ecd152b2433bf95a0941") + wallets = append(wallets, "0x4f3a53cf74ced06d8397ad289f9c343c71e892d6") + wallets = append(wallets, "0xa3e2d68a7257f176700e911840b6fdc45b68142e") + wallets = append(wallets, "0xf091bd35600f2f25a4d5ea0aeb651416bc2464e6") + wallets = append(wallets, "0xf82ed1d5ba9a8a2701950edaa952c2e207e9ac08") + wallets = append(wallets, "0xc8fe7f624c0236b8b0ee16dca68d444949f0484f") + wallets = append(wallets, "0x0639abd48ba1b0ebff2dd8bd6dc75bf0df9f46f9") + wallets = append(wallets, "0xcf530d8cea790ef8a1d2ae0bbdc09427ae5b684a") + wallets = append(wallets, "0xa5a3d1fc3ecb98de1852ec035397434c7e934833") + wallets = append(wallets, "0x6b23134c368994b597b1ade0da37f8265c59dc7c") + wallets = append(wallets, "0xf5cd542a348f153535e9f9a1c936fef201d2c120") + wallets = append(wallets, "0x250bff984bc20d14b0afa21b0b49a69da4586d72") + wallets = append(wallets, "0xa0bf248504742138d0ee79ca7e5909a09250a21f") + wallets = append(wallets, "0xb0e05376c9c95241a0229bd9fe1e93d0aacb321f") + wallets = append(wallets, "0x17b7f8902a8011c0aff9bb149ddf260c9c78020c") + wallets = append(wallets, "0x2fd07c429a6d393d78038279756ef7eef3a403a0") + wallets = append(wallets, "0xec1c622a9c2f660a7f598db65c0cdc3838f1fa80") + wallets = append(wallets, "0xd605a05e1e9088bbe73a9cb5df79f4be08b656c4") + wallets = append(wallets, "0x394aa60f99ccaf9db21da1772f2a78ddaa0c4f6f") + wallets = append(wallets, "0xd4fa8c6b7568dcbfe6d67963a2da2d208e273791") + wallets = append(wallets, "0x38b2b4816812870a92f56d7a3682203c3a467bd7") + wallets = append(wallets, "0x75594d9462f1d43c44cfcc05e28fbb5db7e36a62") + wallets = append(wallets, "0xe791ada26d63cd888315c23a496d23d671df153f") + wallets = append(wallets, "0x2afb8400eda5dca9cdea9f3f3c747ae8ec0471ea") + wallets = append(wallets, "0x66046266e73e9aa7b91eff66c61c931fc69f9ce8") + wallets = append(wallets, "0x22b1adf80042f980920b7237fcc20ea398b8fa75") + wallets = append(wallets, "0x4df1d0e931c7ade5d8ce53944fce149ad9084547") + wallets = append(wallets, "0x3690934a774758c73bbcb99b7704b3a4848fd1bf") + wallets = append(wallets, "0xc3da629c518404860c8893a66ce3bb2e16bea6ec") + wallets = append(wallets, "0x7fcc63271a568df1a262cc4f995b33c09af2545d") + wallets = append(wallets, "0x2f0c42b79f96aba17b6087a89c993ae9a3c45524") + wallets = append(wallets, "0x77f61a1adc61c11244c2f619c87745489b3c7c5b") + wallets = append(wallets, "0xfcd2ce20ef8ed3d43ab4f8c2da13bbf1c6d9512f") + wallets = append(wallets, "0x94ea90a94522b583b91746e8e39406a16503fa7b") + wallets = append(wallets, "0xc3ef6458b92a6ebfade52b74e451c861cce73b9c") + wallets = append(wallets, "0x9a49575d906cf471a72a26bacc5ecd550bdf8c4a") + wallets = append(wallets, "0x02899e083dcb403ba1a1e325c95551c5fe0da817") + wallets = append(wallets, "0x320b05e4bb3ce29c81081d086deacf1f85e8c912") + wallets = append(wallets, "0xc35aab030e2ccbaefb87363b7abd0aa6549a2aa3") + wallets = append(wallets, "0xb54cbab367225e0a5f46f06460ce184874c8afa2") + wallets = append(wallets, "0xd0a3a8ae09b4d5701ff06cc371cf371a0b16f0af") + wallets = append(wallets, "0xcaa4f65876ca0962d071c8b97faf7554c71fd53e") + wallets = append(wallets, "0x525e3011f77019595bfb954a11876c02c0929b10") + return wallets +} diff --git a/app/upgrades/v20/genesis_test.go b/app/upgrades/v20/genesis_test.go new file mode 100644 index 0000000000..50ce85d43e --- /dev/null +++ b/app/upgrades/v20/genesis_test.go @@ -0,0 +1,156 @@ +package v20_test + +import ( + "math/big" + + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + testkeyring "github.com/evmos/evmos/v18/testutil/integration/evmos/keyring" + "github.com/evmos/evmos/v18/testutil/integration/evmos/network" + "github.com/evmos/evmos/v18/types" + erc20types "github.com/evmos/evmos/v18/x/erc20/types" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" +) + +const ( + // erc20TokenPairHex is the string representation of the ERC-20 token pair address. + erc20TokenPairHex = "0x80b5a32E4F032B2a058b4F29EC95EEfEEB87aDcd" //#nosec G101 -- these are not hardcoded credentials + // SmartContractCode is the hex representation of the smart contract code that is set in genesis. + // + // NOTE: This was printed from the working branch and using ExportGenesis -> then printing the genesis account code. + SmartContractCode = "608060405234801561000f575f80fd5b50600436106101d8575f3560e01c80635c975abb11610102578063a217fddf116100a0578063d53913931161006f578063d53913931461057a578063d547741f14610598578063dd62ed3e146105b4578063e63ab1e9146105e4576101d8565b8063a217fddf146104cc578063a457c2d7146104ea578063a9059cbb1461051a578063ca15c8731461054a576101d8565b80638456cb59116100dc5780638456cb59146104445780639010d07c1461044e57806391d148541461047e57806395d89b41146104ae576101d8565b80635c975abb146103da57806370a08231146103f857806379cc679014610428576101d8565b8063282c51f31161017a578063395093511161014957806339509351146103685780633f4ba83a1461039857806340c10f19146103a257806342966c68146103be576101d8565b8063282c51f3146102f45780632f2ff15d14610312578063313ce5671461032e57806336568abe1461034c576101d8565b806318160ddd116101b657806318160ddd1461025a5780631cf2c7e21461027857806323b872dd14610294578063248a9ca3146102c4576101d8565b806301ffc9a7146101dc57806306fdde031461020c578063095ea7b31461022a575b5f80fd5b6101f660048036038101906101f19190612005565b610602565b604051610203919061204a565b60405180910390f35b61021461067b565b60405161022191906120ed565b60405180910390f35b610244600480360381019061023f919061219a565b61070b565b604051610251919061204a565b60405180910390f35b61026261072d565b60405161026f91906121e7565b60405180910390f35b610292600480360381019061028d919061219a565b610736565b005b6102ae60048036038101906102a99190612200565b6107b4565b6040516102bb919061204a565b60405180910390f35b6102de60048036038101906102d99190612283565b6107e2565b6040516102eb91906122bd565b60405180910390f35b6102fc6107fe565b60405161030991906122bd565b60405180910390f35b61032c600480360381019061032791906122d6565b610822565b005b610336610843565b604051610343919061232f565b60405180910390f35b610366600480360381019061036191906122d6565b610859565b005b610382600480360381019061037d919061219a565b6108dc565b60405161038f919061204a565b60405180910390f35b6103a0610912565b005b6103bc60048036038101906103b7919061219a565b61098c565b005b6103d860048036038101906103d39190612348565b610a0a565b005b6103e2610a1e565b6040516103ef919061204a565b60405180910390f35b610412600480360381019061040d9190612373565b610a33565b60405161041f91906121e7565b60405180910390f35b610442600480360381019061043d919061219a565b610a79565b005b61044c610a99565b005b6104686004803603810190610463919061239e565b610b13565b60405161047591906123eb565b60405180910390f35b610498600480360381019061049391906122d6565b610b3f565b6040516104a5919061204a565b60405180910390f35b6104b6610ba2565b6040516104c391906120ed565b60405180910390f35b6104d4610c32565b6040516104e191906122bd565b60405180910390f35b61050460048036038101906104ff919061219a565b610c38565b604051610511919061204a565b60405180910390f35b610534600480360381019061052f919061219a565b610cad565b604051610541919061204a565b60405180910390f35b610564600480360381019061055f9190612283565b610ccf565b60405161057191906121e7565b60405180910390f35b610582610cf0565b60405161058f91906122bd565b60405180910390f35b6105b260048036038101906105ad91906122d6565b610d14565b005b6105ce60048036038101906105c99190612404565b610d35565b6040516105db91906121e7565b60405180910390f35b6105ec610db7565b6040516105f991906122bd565b60405180910390f35b5f7f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610674575061067382610ddb565b5b9050919050565b60606005805461068a9061246f565b80601f01602080910402602001604051908101604052809291908181526020018280546106b69061246f565b80156107015780601f106106d857610100808354040283529160200191610701565b820191905f5260205f20905b8154815290600101906020018083116106e457829003601f168201915b5050505050905090565b5f80610715610e54565b9050610722818585610e5b565b600191505092915050565b5f600454905090565b6107677f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848610762610e54565b610b3f565b6107a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161079d9061250f565b60405180910390fd5b6107b0828261101e565b5050565b5f806107be610e54565b90506107cb8582856111e3565b6107d685858561126e565b60019150509392505050565b5f805f8381526020019081526020015f20600101549050919050565b7f3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a84881565b61082b826107e2565b610834816114dd565b61083e83836114f1565b505050565b5f600760019054906101000a900460ff16905090565b610861610e54565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146108ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c59061259d565b60405180910390fd5b6108d88282611523565b5050565b5f806108e6610e54565b90506109078185856108f88589610d35565b61090291906125e8565b610e5b565b600191505092915050565b6109437f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a61093e610e54565b610b3f565b610982576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109799061268b565b60405180910390fd5b61098a611555565b565b6109bd7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66109b8610e54565b610b3f565b6109fc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109f390612719565b60405180910390fd5b610a0682826115b6565b5050565b610a1b610a15610e54565b8261101e565b50565b5f60075f9054906101000a900460ff16905090565b5f60025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b610a8b82610a85610e54565b836111e3565b610a95828261101e565b5050565b610aca7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610ac5610e54565b610b3f565b610b09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b00906127a7565b60405180910390fd5b610b11611705565b565b5f610b378260015f8681526020019081526020015f2061176790919063ffffffff16565b905092915050565b5f805f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b606060068054610bb19061246f565b80601f0160208091040260200160405190810160405280929190818152602001828054610bdd9061246f565b8015610c285780601f10610bff57610100808354040283529160200191610c28565b820191905f5260205f20905b815481529060010190602001808311610c0b57829003601f168201915b5050505050905090565b5f801b81565b5f80610c42610e54565b90505f610c4f8286610d35565b905083811015610c94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8b90612835565b60405180910390fd5b610ca18286868403610e5b565b60019250505092915050565b5f80610cb7610e54565b9050610cc481858561126e565b600191505092915050565b5f610ce960015f8481526020019081526020015f2061177e565b9050919050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b610d1d826107e2565b610d26816114dd565b610d308383611523565b505050565b5f60035f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610e4d5750610e4c82611791565b5b9050919050565b5f33905090565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610ec9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ec0906128c3565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610f37576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2e90612951565b60405180910390fd5b8060035f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258360405161101191906121e7565b60405180910390a3505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361108c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611083906129df565b60405180910390fd5b611097825f836117fa565b5f60025f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101561111b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161111290612a6d565b60405180910390fd5b81810360025f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508160045f82825403925050819055505f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516111cb91906121e7565b60405180910390a36111de835f8461180a565b505050565b5f6111ee8484610d35565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611268578181101561125a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161125190612ad5565b60405180910390fd5b6112678484848403610e5b565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036112dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d390612b63565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361134a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134190612bf1565b60405180910390fd5b6113558383836117fa565b5f60025f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050818110156113d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d090612c7f565b60405180910390fd5b81810360025f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508160025f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516114c491906121e7565b60405180910390a36114d784848461180a565b50505050565b6114ee816114e9610e54565b61180f565b50565b6114fb8282611893565b61151e8160015f8581526020019081526020015f2061196d90919063ffffffff16565b505050565b61152d828261199a565b6115508160015f8581526020019081526020015f20611a7490919063ffffffff16565b505050565b61155d611aa1565b5f60075f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61159f610e54565b6040516115ac91906123eb565b60405180910390a1565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611624576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161b90612ce7565b60405180910390fd5b61162f5f83836117fa565b8060045f82825461164091906125e8565b925050819055508060025f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055508173ffffffffffffffffffffffffffffffffffffffff165f73ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516116ee91906121e7565b60405180910390a36117015f838361180a565b5050565b61170d611aea565b600160075f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611750610e54565b60405161175d91906123eb565b60405180910390a1565b5f611774835f0183611b34565b5f1c905092915050565b5f61178a825f01611b5b565b9050919050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b611805838383611b6a565b505050565b505050565b6118198282610b3f565b61188f5761182681611bc2565b611833835f1c6020611bef565b604051602001611844929190612dd3565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161188691906120ed565b60405180910390fd5b5050565b61189d8282610b3f565b6119695760015f808481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555061190e610e54565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b5f611992835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611e24565b905092915050565b6119a48282610b3f565b15611a70575f805f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550611a15610e54565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b5f611a99835f018373ffffffffffffffffffffffffffffffffffffffff165f1b611e8b565b905092915050565b611aa9610a1e565b611ae8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611adf90612e56565b60405180910390fd5b565b611af2610a1e565b15611b32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2990612ebe565b60405180910390fd5b565b5f825f018281548110611b4a57611b49612edc565b5b905f5260205f200154905092915050565b5f815f01805490509050919050565b611b75838383611f87565b611b7d610a1e565b15611bbd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bb490612f79565b60405180910390fd5b505050565b6060611be88273ffffffffffffffffffffffffffffffffffffffff16601460ff16611bef565b9050919050565b60605f6002836002611c019190612f97565b611c0b91906125e8565b67ffffffffffffffff811115611c2457611c23612fd8565b5b6040519080825280601f01601f191660200182016040528015611c565781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110611c8d57611c8c612edc565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611cf057611cef612edc565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f6001846002611d2e9190612f97565b611d3891906125e8565b90505b6001811115611dd7577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110611d7a57611d79612edc565b5b1a60f81b828281518110611d9157611d90612edc565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350600485901c945080611dd090613005565b9050611d3b565b505f8414611e1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1190613076565b60405180910390fd5b8091505092915050565b5f611e2f8383611f8c565b611e8157825f0182908060018154018082558091505060019003905f5260205f20015f9091909190915055825f0180549050836001015f8481526020019081526020015f208190555060019050611e85565b5f90505b92915050565b5f80836001015f8481526020019081526020015f205490505f8114611f7c575f600182611eb89190613094565b90505f6001865f0180549050611ece9190613094565b9050818114611f34575f865f018281548110611eed57611eec612edc565b5b905f5260205f200154905080875f018481548110611f0e57611f0d612edc565b5b905f5260205f20018190555083876001015f8381526020019081526020015f2081905550505b855f01805480611f4757611f466130c7565b5b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050611f81565b5f9150505b92915050565b505050565b5f80836001015f8481526020019081526020015f20541415905092915050565b5f80fd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b611fe481611fb0565b8114611fee575f80fd5b50565b5f81359050611fff81611fdb565b92915050565b5f6020828403121561201a57612019611fac565b5b5f61202784828501611ff1565b91505092915050565b5f8115159050919050565b61204481612030565b82525050565b5f60208201905061205d5f83018461203b565b92915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561209a57808201518184015260208101905061207f565b5f8484015250505050565b5f601f19601f8301169050919050565b5f6120bf82612063565b6120c9818561206d565b93506120d981856020860161207d565b6120e2816120a5565b840191505092915050565b5f6020820190508181035f83015261210581846120b5565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6121368261210d565b9050919050565b6121468161212c565b8114612150575f80fd5b50565b5f813590506121618161213d565b92915050565b5f819050919050565b61217981612167565b8114612183575f80fd5b50565b5f8135905061219481612170565b92915050565b5f80604083850312156121b0576121af611fac565b5b5f6121bd85828601612153565b92505060206121ce85828601612186565b9150509250929050565b6121e181612167565b82525050565b5f6020820190506121fa5f8301846121d8565b92915050565b5f805f6060848603121561221757612216611fac565b5b5f61222486828701612153565b935050602061223586828701612153565b925050604061224686828701612186565b9150509250925092565b5f819050919050565b61226281612250565b811461226c575f80fd5b50565b5f8135905061227d81612259565b92915050565b5f6020828403121561229857612297611fac565b5b5f6122a58482850161226f565b91505092915050565b6122b781612250565b82525050565b5f6020820190506122d05f8301846122ae565b92915050565b5f80604083850312156122ec576122eb611fac565b5b5f6122f98582860161226f565b925050602061230a85828601612153565b9150509250929050565b5f60ff82169050919050565b61232981612314565b82525050565b5f6020820190506123425f830184612320565b92915050565b5f6020828403121561235d5761235c611fac565b5b5f61236a84828501612186565b91505092915050565b5f6020828403121561238857612387611fac565b5b5f61239584828501612153565b91505092915050565b5f80604083850312156123b4576123b3611fac565b5b5f6123c18582860161226f565b92505060206123d285828601612186565b9150509250929050565b6123e58161212c565b82525050565b5f6020820190506123fe5f8301846123dc565b92915050565b5f806040838503121561241a57612419611fac565b5b5f61242785828601612153565b925050602061243885828601612153565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f600282049050600182168061248657607f821691505b60208210810361249957612498612442565b5b50919050565b7f45524332304d696e7465724275726e6572446563696d616c733a206d757374205f8201527f68617665206275726e657220726f6c6520746f206275726e0000000000000000602082015250565b5f6124f960388361206d565b91506125048261249f565b604082019050919050565b5f6020820190508181035f830152612526816124ed565b9050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e63655f8201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b5f612587602f8361206d565b91506125928261252d565b604082019050919050565b5f6020820190508181035f8301526125b48161257b565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6125f282612167565b91506125fd83612167565b9250828201905080821115612615576126146125bb565b5b92915050565b7f45524332304d696e7465724275726e6572446563696d616c733a206d757374205f8201527f686176652070617573657220726f6c6520746f20756e70617573650000000000602082015250565b5f612675603b8361206d565b91506126808261261b565b604082019050919050565b5f6020820190508181035f8301526126a281612669565b9050919050565b7f45524332304d696e7465724275726e6572446563696d616c733a206d757374205f8201527f68617665206d696e74657220726f6c6520746f206d696e740000000000000000602082015250565b5f61270360388361206d565b915061270e826126a9565b604082019050919050565b5f6020820190508181035f830152612730816126f7565b9050919050565b7f45524332304d696e7465724275726e6572446563696d616c733a206d757374205f8201527f686176652070617573657220726f6c6520746f20706175736500000000000000602082015250565b5f61279160398361206d565b915061279c82612737565b604082019050919050565b5f6020820190508181035f8301526127be81612785565b9050919050565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f775f8201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b5f61281f60258361206d565b915061282a826127c5565b604082019050919050565b5f6020820190508181035f83015261284c81612813565b9050919050565b7f45524332303a20617070726f76652066726f6d20746865207a65726f206164645f8201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b5f6128ad60248361206d565b91506128b882612853565b604082019050919050565b5f6020820190508181035f8301526128da816128a1565b9050919050565b7f45524332303a20617070726f766520746f20746865207a65726f2061646472655f8201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b5f61293b60228361206d565b9150612946826128e1565b604082019050919050565b5f6020820190508181035f8301526129688161292f565b9050919050565b7f45524332303a206275726e2066726f6d20746865207a65726f206164647265735f8201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b5f6129c960218361206d565b91506129d48261296f565b604082019050919050565b5f6020820190508181035f8301526129f6816129bd565b9050919050565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e5f8201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b5f612a5760228361206d565b9150612a62826129fd565b604082019050919050565b5f6020820190508181035f830152612a8481612a4b565b9050919050565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000005f82015250565b5f612abf601d8361206d565b9150612aca82612a8b565b602082019050919050565b5f6020820190508181035f830152612aec81612ab3565b9050919050565b7f45524332303a207472616e736665722066726f6d20746865207a65726f2061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f612b4d60258361206d565b9150612b5882612af3565b604082019050919050565b5f6020820190508181035f830152612b7a81612b41565b9050919050565b7f45524332303a207472616e7366657220746f20746865207a65726f20616464725f8201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b5f612bdb60238361206d565b9150612be682612b81565b604082019050919050565b5f6020820190508181035f830152612c0881612bcf565b9050919050565b7f45524332303a207472616e7366657220616d6f756e74206578636565647320625f8201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b5f612c6960268361206d565b9150612c7482612c0f565b604082019050919050565b5f6020820190508181035f830152612c9681612c5d565b9050919050565b7f45524332303a206d696e7420746f20746865207a65726f2061646472657373005f82015250565b5f612cd1601f8361206d565b9150612cdc82612c9d565b602082019050919050565b5f6020820190508181035f830152612cfe81612cc5565b9050919050565b5f81905092915050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000005f82015250565b5f612d43601783612d05565b9150612d4e82612d0f565b601782019050919050565b5f612d6382612063565b612d6d8185612d05565b9350612d7d81856020860161207d565b80840191505092915050565b7f206973206d697373696e6720726f6c65200000000000000000000000000000005f82015250565b5f612dbd601183612d05565b9150612dc882612d89565b601182019050919050565b5f612ddd82612d37565b9150612de98285612d59565b9150612df482612db1565b9150612e008284612d59565b91508190509392505050565b7f5061757361626c653a206e6f74207061757365640000000000000000000000005f82015250565b5f612e4060148361206d565b9150612e4b82612e0c565b602082019050919050565b5f6020820190508181035f830152612e6d81612e34565b9050919050565b7f5061757361626c653a20706175736564000000000000000000000000000000005f82015250565b5f612ea860108361206d565b9150612eb382612e74565b602082019050919050565b5f6020820190508181035f830152612ed581612e9c565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f45524332305061757361626c653a20746f6b656e207472616e736665722077685f8201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b5f612f63602a8361206d565b9150612f6e82612f09565b604082019050919050565b5f6020820190508181035f830152612f9081612f57565b9050919050565b5f612fa182612167565b9150612fac83612167565b9250828202612fba81612167565b91508282048414831517612fd157612fd06125bb565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f61300f82612167565b91505f8203613021576130206125bb565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e745f82015250565b5f61306060208361206d565b915061306b8261302c565b602082019050919050565b5f6020820190508181035f83015261308d81613054565b9050919050565b5f61309e82612167565b91506130a983612167565b92508282039050818111156130c1576130c06125bb565b5b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea26469706673582212208e17db436f847258cc8b148f2ec3689c9d1043000f9acacdf5a893071a6136a964736f6c63430008170033" +) + +var ( + // accountWithERC20s is the address of the account that has ERC-20 tokens in genesis. + accountWithERC20s = common.HexToAddress("0x7B5089c16eC85d73D8d5f6879f39B08797877356") + // bech32WithERC20s is the bech32 formatted address of the account with ERC-20s. + bech32WithERC20s = sdk.AccAddress(accountWithERC20s.Bytes()) + + // code is the bytecode of the contract. + // + // These conversions are taken from the code hash check in InitGenesis: + // https://github.com/evmos/evmos/blob/ca0f3e4d3e8407fd983b42aa595b052a67c1598b/x/evm/genesis.go#L48-L64 + code = common.Hex2Bytes(SmartContractCode) + // codeHash is the hash of the contract code. + codeHash = crypto.Keccak256Hash(code) + + // Storage is the genesis storage for the deployed ERC-20 contract + // + // NOTE: This is generated the same way described above with ExportGenesis and iterating of the genesis accounts on the working example + Storage = evmtypes.Storage{ + {Key: "0x0000000000000000000000000000000000000000000000000000000000000005", Value: "0x786d706c00000000000000000000000000000000000000000000000000000008"}, + {Key: "0x0000000000000000000000000000000000000000000000000000000000000006", Value: "0x786d706c00000000000000000000000000000000000000000000000000000008"}, + {Key: "0x0000000000000000000000000000000000000000000000000000000000000007", Value: "0x0000000000000000000000000000000000000000000000000000000000000600"}, + {Key: "0x0eb5be412f275a18f6e4d622aee4ff40b21467c926224771b782d4c095d1444b", Value: "0x00000000000000000000000047eeb2eac350e1923b8cbdfa4396a077b36e62a0"}, + {Key: "0x0ef55e0cc676cf0b0dcbdc7d53c3b797e88e44b10ecee85d45144bc7392574c7", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0x26bde78f605f19d1d853933fa781096670ea82ad96c9a3fb49f407e9600b316a", Value: "0x00000000000000000000000047eeb2eac350e1923b8cbdfa4396a077b36e62a0"}, + {Key: "0x28bcb2563cf7895ce732c75018c5f73c44037088fc4505201fc28c3147d1d4a0", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0x2e681a43037a582fb0535432b520e9dc97303bf239f82648091f9be82f4b677e", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0x42aa905ad67e072b45e9dae81c8fa8bc705cc25014d5e9f10fa5114ae9c0dcf1", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0x4796a5437e25bdc491b74d328cf6b437c8587e216f52049c7df56421f51ae30f", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0x64e21244e91af723e1b962171ed4828dcecc0d7b89872e516a5db8266da80000", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0x6d2487ab6e76634bbe98b9d5b39803d625a8f9249da9e03e70c638bf76d9e29b", Value: "0x00000000000000000000000047eeb2eac350e1923b8cbdfa4396a077b36e62a0"}, + {Key: "0x97c12224ac75d13d2d9a9e30dd25212b81a4e2c19743b211209b4bca3db99142", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0xa6eef7e35abe7026729641147f7915573c7e97b47efa546f5f6e3230263bcb49", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0xb009fbc347bffd144efd545cc4b15a37592e1dd7063753564d9ecc6fea764b6f", Value: "0x00000000000000000000000047eeb2eac350e1923b8cbdfa4396a077b36e62a0"}, + {Key: "0xb9cbbae02fe941283ec0eefd7b121e3bc7f89fae077b27bdd75a7fd4cf1543a8", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0xbd709b1d40030de11c73f3ce33376499eb0cd135667d98ee19bd658eef2adc4d", Value: "0x0000000000000000000000000000000000000000000000000000000000000064"}, + {Key: "0xc5724e8640ef1f7915e4839c81ad4b592af3c601230608793acd429a848553e9", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0xfac4953099c6f6272238a038333d99c9cd0475cb85c72b761909fadae4b6cbcd", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + {Key: "0xfd061ffb53f8d83182630fadee503ca39e0bae885f162932fe84d25caddbc888", Value: "0x0000000000000000000000000000000000000000000000000000000000000001"}, + } + + // mintAmount is the amount of tokens to be minted for a non-native ERC-20 contract. + mintAmount = big.NewInt(5e18) + + // SmartContractAddress is the bech32 address of the Ethereum smart contract account that is set in genesis. + SmartContractAddress = sdk.AccAddress(common.HexToAddress(erc20TokenPairHex).Bytes()) +) + +// createGenesisWithTokenPairs creates a genesis state that contains the state that cannot be created +// otherwise anymore. This is mainly the conversion of native Coins to their ERC-20 representation, +// which is now defunct with STR v2. +// +// That's why we need to create a custom genesis state that contains the ERC-20 balances and the token pairs +// for the native XMPL coin. +// +// The following elements have to be created: +// +// - 1 token pair with IBC native denom +// - The corresponding smart contract with its code and balances (ERC-20 balance) +// - An ERC-20 balance for the xmpl denom which represents some native coins, +// that have been converted to the ERC-20 representation. +// +// NOTE: This assumes, that the SDK coin balances should be handled in the balances setup for +// the integration network. +func createGenesisWithTokenPairs(keyring testkeyring.Keyring) network.CustomGenesisState { + genesisAccounts := []authtypes.AccountI{ + // NOTE: we are adding the account which has native coins as ERC-20s to the genesis state to check that + // both balances are merged afterward. + &authtypes.BaseAccount{ + Address: bech32WithERC20s.String(), + PubKey: nil, + AccountNumber: 0, + Sequence: 0, + }, + &types.EthAccount{ + BaseAccount: &authtypes.BaseAccount{ + Address: SmartContractAddress.String(), + PubKey: nil, + AccountNumber: 9, + Sequence: 1, + }, + CodeHash: codeHash.String(), + }, + } + + // Add all keys from the keyring to the genesis accounts as well. + // + // NOTE: This is necessary to enable the account to send EVM transactions, + // because the Mono ante handler checks the account balance by querying the + // account from the account keeper first. If these accounts are not in the genesis + // state, the ante handler finds a zero balance because of the missing account. + for i, addr := range keyring.GetAllAccAddrs() { + genesisAccounts = append(genesisAccounts, &authtypes.BaseAccount{ + Address: addr.String(), + PubKey: nil, + AccountNumber: uint64(i + 1), + Sequence: 1, + }) + } + + accGenesisState := authtypes.DefaultGenesisState() + for _, genesisAccount := range genesisAccounts { + // NOTE: This type requires to be packed into a *types.Any as seen on SDK tests, + // e.g. https://github.com/evmos/cosmos-sdk/blob/v0.47.5-evmos.2/x/auth/keeper/keeper_test.go#L193-L223 + accGenesisState.Accounts = append(accGenesisState.Accounts, codectypes.UnsafePackAny(genesisAccount)) + } + + // Add token pairs to genesis + erc20GenesisState := erc20types.DefaultGenesisState() + erc20GenesisState.TokenPairs = []erc20types.TokenPair{{ + Erc20Address: erc20TokenPairHex, + Denom: XMPL, + Enabled: true, + ContractOwner: erc20types.OWNER_MODULE, // NOTE: Owner is the module account since it's a native token and was registered through governance + }} + + // Add the smart contracts to the EVM genesis + evmGenesisState := evmtypes.DefaultGenesisState() + evmGenesisState.Accounts = append(evmGenesisState.Accounts, evmtypes.GenesisAccount{ + Address: erc20TokenPairHex, + Code: SmartContractCode, + Storage: Storage, + }) + + // Combine module genesis states + return network.CustomGenesisState{ + authtypes.ModuleName: accGenesisState, + erc20types.ModuleName: erc20GenesisState, + evmtypes.ModuleName: evmGenesisState, + } +} diff --git a/app/upgrades/v20/integration_test.go b/app/upgrades/v20/integration_test.go new file mode 100644 index 0000000000..4ff45d6c23 --- /dev/null +++ b/app/upgrades/v20/integration_test.go @@ -0,0 +1,276 @@ +package v20_test + +import ( + "math/big" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/ethereum/go-ethereum/common" + "github.com/evmos/evmos/v18/app/upgrades/v20" + testfactory "github.com/evmos/evmos/v18/testutil/integration/evmos/factory" + "github.com/evmos/evmos/v18/testutil/integration/evmos/grpc" + testkeyring "github.com/evmos/evmos/v18/testutil/integration/evmos/keyring" + "github.com/evmos/evmos/v18/testutil/integration/evmos/network" + testutils "github.com/evmos/evmos/v18/testutil/integration/evmos/utils" + erc20types "github.com/evmos/evmos/v18/x/erc20/types" + + //nolint:revive // dot-imports are okay for Ginkgo BDD + . "github.com/onsi/ginkgo/v2" + //nolint:revive // dot-imports are okay for Gomega assertions + . "github.com/onsi/gomega" +) + +// TestSTRv2Migration runs the Ginkgo BDD tests for the migration logic +// associated with the Single Token Representation v2. +func TestSTRv2Migration(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "STR v2 Migration Suite") +} + +type ConvertERC20CoinsTestSuite struct { + keyring testkeyring.Keyring + network *network.UnitTestNetwork + handler grpc.Handler + factory testfactory.TxFactory + + // erc20Contract is the address of the deployed ERC-20 contract for testing purposes. + erc20Contract common.Address + // nativeTokenPair is a registered token pair for a native Coin. + nativeTokenPair erc20types.TokenPair + // nonNativeTokenPair is a registered token pair for an ERC-20 native asset. + nonNativeTokenPair erc20types.TokenPair + // wevmosContract is the address of the deployed WEVMOS contract for testing purposes. + wevmosContract common.Address +} + +// NOTE: For these tests it's mandatory to run them ORDERED! +var _ = Describe("STR v2 tests -", Ordered, func() { + var ( + ts *ConvertERC20CoinsTestSuite + + // unconverted is the amount of native coins that have not been converted to ERC-20. + unconverted = int64(500) + // converted is the amount of native coins that have been converted to ERC-20. + converted = int64(100) + ) + + BeforeAll(func() { + // NOTE: In the setup function we are creating a custom genesis state for the integration network + // which contains balances for accounts in different denominations, both in native as well as ERC-20 representation. + var err error + ts, err = NewConvertERC20CoinsTestSuite() + Expect(err).ToNot(HaveOccurred(), "failed to create test suite") + }) + + Describe("the genesis state of the network", Ordered, func() { + It("should include all expected accounts", func() { + expectedAccounts := ts.keyring.GetAllAccAddrs() + expectedAccounts = append(expectedAccounts, bech32WithERC20s, SmartContractAddress) + + for _, acc := range expectedAccounts { + got, err := ts.handler.GetAccount(acc.String()) + Expect(err).ToNot(HaveOccurred(), "failed to get account") + Expect(got).ToNot(BeNil(), "expected non-nil account") + } + }) + + It("should have the expected initial balances", func() { + // We check that the ERC20 converted coins have been added back to the bank balance. + // + // NOTE: We are deliberately ONLY checking the balance of the XMPL coin, because the AEVMOS balance was changed + // through paying transaction fees and they are not affected by the migration. + err := testutils.CheckBalances(ts.handler, []banktypes.Balance{ + { + Address: ts.keyring.GetAccAddr(erc20Deployer).String(), + Coins: sdk.NewCoins( + sdk.NewCoin(AEVMOS, network.PrefundedAccountInitialBalance), + ), + }, + { + Address: bech32WithERC20s.String(), + Coins: sdk.NewCoins( + sdk.NewCoin(AEVMOS, network.PrefundedAccountInitialBalance), + sdk.NewInt64Coin(XMPL, unconverted), + ), + }, + }) + Expect(err).ToNot(HaveOccurred(), "expected different balances") + }) + + It("should have registered a native token pair", func() { + res, err := ts.handler.GetTokenPairs() + Expect(err).ToNot(HaveOccurred(), "failed to get token pairs") + Expect(res.TokenPairs).To(HaveLen(1), "unexpected number of token pairs") + Expect(res.TokenPairs[0].Denom).To(Equal(XMPL), "expected different denom") + Expect(res.TokenPairs[0].IsNativeCoin()).To(BeTrue(), "expected token pair to be for a native coin") + + Expect(res.TokenPairs[0].Erc20Address).To( + Equal(common.BytesToAddress(SmartContractAddress.Bytes()).String()), + "expected different ERC-20 contract", + ) + + // Assign the native token pair to the test suite for later use. + ts.nativeTokenPair = res.TokenPairs[0] + }) + + It("should show separate ERC-20 and bank balances", func() { + xmplBalance, err := ts.handler.GetBalance(bech32WithERC20s, XMPL) + Expect(err).ToNot(HaveOccurred(), "failed to get XMPL balance") + Expect(xmplBalance.Balance.Amount.Int64()).To( + Equal(unconverted), + "expected different XMPL balance", + ) + + // Test that the ERC-20 contract for the IBC native coin has the correct user balance after genesis. + balance, err := testutils.GetERC20BalanceForAddr( + ts.factory, + ts.keyring.GetPrivKey(erc20Deployer), + accountWithERC20s, + ts.nativeTokenPair.GetERC20Contract(), + ) + Expect(err).ToNot(HaveOccurred(), "failed to query ERC20 balance") + Expect(balance.String()).To( + Equal(big.NewInt(converted).String()), + "expected different ERC-20 balance after genesis", + ) + }) + + It("should have a balance of escrowed tokens in the ERC-20 module account", func() { + balancesRes, err := ts.handler.GetAllBalances(authtypes.NewModuleAddress(erc20types.ModuleName)) + Expect(err).ToNot(HaveOccurred(), "failed to get balances") + Expect(balancesRes.Balances).ToNot(BeNil(), "expected non-nil balances") + Expect(balancesRes.Balances).ToNot(BeEmpty(), "expected non-empty balances") + }) + }) + + Describe("the network state preparation", Ordered, func() { + It("should run without an error", func() { + var err error + ts, err = PrepareNetwork(ts) + Expect(err).ToNot(HaveOccurred(), "failed to prepare network state") + }) + + It("should have registered a non-native token pair", func() { + res, err := ts.handler.GetTokenPairs() + Expect(err).ToNot(HaveOccurred(), "failed to get token pairs") + Expect(res.TokenPairs).To(HaveLen(2), "unexpected number of token pairs") + Expect(res.TokenPairs).To(ContainElement(ts.nonNativeTokenPair), "non-native token pair not found") + }) + + It("should have minted ERC-20 tokens for the contract deployer", func() { + balance, err := testutils.GetERC20Balance(ts.factory, ts.keyring.GetPrivKey(erc20Deployer), ts.erc20Contract) + Expect(err).ToNot(HaveOccurred(), "failed to query ERC-20 balance") + Expect(balance).To(Equal(mintAmount), "expected different balance after minting ERC-20") + }) + }) + + Describe("the migration", Ordered, func() { + // balancePre is the balance of the account having some WEVMOS tokens before the migration. + // + // NOTE: we are checking the balances of the account before the migration to compare + // them with the balances after the migration to check that the WEVMOS tokens + // have been correctly unwrapped. + var balancePre *sdk.Coin + + BeforeAll(func() { + balancePreRes, err := ts.handler.GetBalance(ts.keyring.GetAccAddr(erc20Deployer), AEVMOS) + Expect(err).ToNot(HaveOccurred(), "failed to check balances") + balancePre = balancePreRes.Balance + }) + + It("should succeed", func() { + logger := ts.network.GetContext().Logger().With("upgrade") + + // Convert the coins back using the upgrade util + err := v20.RunSTRv2Migration( + ts.network.GetContext(), + logger, + ts.network.App.AccountKeeper, + ts.network.App.BankKeeper, + ts.network.App.Erc20Keeper, + ts.network.App.EvmKeeper, + ts.wevmosContract, + ts.network.GetDenom(), + ) + Expect(err).ToNot(HaveOccurred(), "failed to run migration") + + err = ts.network.NextBlock() + Expect(err).ToNot(HaveOccurred(), "failed to execute block") + }) + + It("should have converted the ERC-20s back to the native representation", func() { + // We check that the ERC20 converted coins have been added back to the bank balance. + err := testutils.CheckBalances(ts.handler, []banktypes.Balance{ + { + Address: bech32WithERC20s.String(), + Coins: sdk.NewCoins( + sdk.NewCoin(AEVMOS, network.PrefundedAccountInitialBalance), + sdk.NewInt64Coin(XMPL, unconverted+converted), + ), + }, + }) + Expect(err).ToNot(HaveOccurred(), "expected different balances") + }) + + It("should have converted WEVMOS back to the base denomination", func() { + // We are checking that the WEVMOS tokens have been converted back to the base denomination. + balancePostRes, err := ts.handler.GetBalance(ts.keyring.GetAccAddr(erc20Deployer), AEVMOS) + Expect(err).ToNot(HaveOccurred(), "failed to check balances") + Expect(balancePostRes.Balance.String()).To( + Equal(balancePre.AddAmount(sentWEVMOS).String()), + "expected different balance after converting WEVMOS back to unwrapped denom", + ) + }) + + It("should have registered the WEVMOS token as a native token pair", func() { + tokenPairRes, err := ts.handler.GetTokenPair(ts.network.GetDenom()) + Expect(err).ToNot(HaveOccurred(), "failed to get token pairs") + Expect(tokenPairRes.TokenPair.Erc20Address).To( + Equal(ts.wevmosContract.String()), + "expected different ERC-20 address for token pair", + ) + }) + + It("should enable getting the same account balance through the bank and the ERC-20 contract", func() { + // NOTE: We check that the ERC20 contract for the native token pair can still be called, + // even though the original contract code was deleted, and it is now re-deployed + // as a precompiled contract. + balance, err := testutils.GetERC20BalanceForAddr( + ts.factory, + ts.keyring.GetPrivKey(erc20Deployer), + accountWithERC20s, + ts.nativeTokenPair.GetERC20Contract(), + ) + Expect(err).ToNot(HaveOccurred(), "failed to query ERC20 balance") + Expect(balance.Int64()).To(Equal(unconverted+converted), "expected different balance after converting ERC20") + + balanceRes, err := ts.handler.GetBalance(bech32WithERC20s, ts.nativeTokenPair.Denom) + Expect(err).ToNot(HaveOccurred(), "failed to check balances") + Expect(balanceRes.Balance.Amount.Int64()).To(Equal(unconverted+converted), "expected different balance after converting ERC20") + }) + + It("should have removed all balances from the ERC-20 module account", func() { + balancesRes, err := ts.handler.GetAllBalances(authtypes.NewModuleAddress(erc20types.ModuleName)) + Expect(err).ToNot(HaveOccurred(), "failed to get balances") + Expect(balancesRes.Balances.IsZero()).To(BeTrue(), "expected different balance for module account") + }) + + It("should not have converted the native ERC-20s", func() { + balance, err := testutils.GetERC20Balance(ts.factory, ts.keyring.GetPrivKey(erc20Deployer), ts.nonNativeTokenPair.GetERC20Contract()) + Expect(err).ToNot(HaveOccurred(), "failed to query ERC20 balance") + Expect(balance).To(Equal(mintAmount), "expected different balance after converting ERC20") + }) + + It("should show the full Evmos balance when querying the (former) WEVMOS contract", func() { + balance, err := testutils.GetERC20Balance(ts.factory, ts.keyring.GetPrivKey(erc20Deployer), ts.wevmosContract) + Expect(err).ToNot(HaveOccurred(), "failed to query ERC20 balance") + + bankBalance, err := ts.handler.GetBalance(ts.keyring.GetAccAddr(erc20Deployer), ts.network.GetDenom()) + Expect(err).ToNot(HaveOccurred(), "failed to query aevmos balance from bank module") + + Expect(balance.Int64()).To(Equal(bankBalance.Balance.Amount.Int64()), "expected different WEVMOS ERC-20 query balance") + }) + }) +}) diff --git a/app/upgrades/v20/migration.go b/app/upgrades/v20/migration.go new file mode 100644 index 0000000000..25d4363d97 --- /dev/null +++ b/app/upgrades/v20/migration.go @@ -0,0 +1,58 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package v20 + +import ( + errorsmod "cosmossdk.io/errors" + "github.com/cometbft/cometbft/libs/log" + sdk "github.com/cosmos/cosmos-sdk/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/ethereum/go-ethereum/common" + erc20keeper "github.com/evmos/evmos/v18/x/erc20/keeper" + "github.com/evmos/evmos/v18/x/erc20/types" + evmkeeper "github.com/evmos/evmos/v18/x/evm/keeper" +) + +// RunSTRv2Migration converts all the registered ERC-20 tokens of Cosmos native token pairs +// back to the native representation and registers the WEVMOS token as an ERC-20 token pair. +func RunSTRv2Migration( + ctx sdk.Context, + logger log.Logger, + accountKeeper authkeeper.AccountKeeper, + bankKeeper bankkeeper.Keeper, + erc20Keeper erc20keeper.Keeper, + evmKeeper *evmkeeper.Keeper, + wrappedContractAddr common.Address, + nativeDenom string, +) error { + // NOTE: it's necessary to register the WEVMOS token as a native token pair before adding + // the dynamic EVM extensions (which is relying on the registered token pairs). + pair := types.NewTokenPair(wrappedContractAddr, nativeDenom, types.OWNER_MODULE) + erc20Keeper.SetToken(ctx, pair) + + // Filter all token pairs for the ones that are for Cosmos native coins. + nativeTokenPairs := getNativeTokenPairs(ctx, erc20Keeper) + + // NOTE (@fedekunze): first we must convert the all the registered tokens. + // If we do it the other way around, the conversion will fail since there won't + // be any contract code due to the selfdestruct. + if err := ConvertERC20Coins( + ctx, + logger, + accountKeeper, + bankKeeper, + erc20Keeper, + *evmKeeper, + wrappedContractAddr, + nativeTokenPairs, + ); err != nil { + return errorsmod.Wrap(err, "failed to convert native coins") + } + + // Register the ERC-20 extensions for the native token pairs and delete the old contract code. + return RegisterERC20Extensions( + ctx, erc20Keeper, evmKeeper, + ) +} diff --git a/app/upgrades/v20/upgrades.go b/app/upgrades/v20/upgrades.go new file mode 100644 index 0000000000..b9aed050c4 --- /dev/null +++ b/app/upgrades/v20/upgrades.go @@ -0,0 +1,77 @@ +// Copyright Tharsis Labs Ltd.(Evmos) +// SPDX-License-Identifier:ENCL-1.0(https://github.com/evmos/evmos/blob/main/LICENSE) + +package v20 + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/ethereum/go-ethereum/common" + erc20precompile "github.com/evmos/evmos/v18/precompiles/erc20" + "github.com/evmos/evmos/v18/utils" + erc20keeper "github.com/evmos/evmos/v18/x/erc20/keeper" + evmkeeper "github.com/evmos/evmos/v18/x/evm/keeper" +) + +// CreateUpgradeHandler creates an SDK upgrade handler for v17.0.0 +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + ak authkeeper.AccountKeeper, + bk bankkeeper.Keeper, + erck erc20keeper.Keeper, + ek *evmkeeper.Keeper, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + logger := ctx.Logger().With("upgrade", UpgradeName) + + // revenue module is deprecated + logger.Debug("deleting revenue module from version map...") + delete(vm, "revenue") + + // Leave modules as-is to avoid running InitGenesis. + // Get EVM denomination + evmDenom := ek.GetParams(ctx).EvmDenom + + var wrappedContractAddr common.Address + switch { + case utils.IsMainnet(ctx.ChainID()): + wrappedContractAddr = common.HexToAddress(erc20precompile.WEVMOSContractMainnet) + case utils.IsTestnet(ctx.ChainID()): + wrappedContractAddr = common.HexToAddress(erc20precompile.WEVMOSContractTestnet) + default: + logger.Error("unexpected chain id", "chain-id", ctx.ChainID()) + } + + // Execute the conversion for all ERC20 token pairs for native Cosmos coins to their native representation. + // + // NOTE: We do NOT need to register the corresponding EVM extensions during the upgrade, because + // they will be instantiated as dynamic precompiles during the initialization of the EVM in any given EVM + // transaction. + // + // What is necessary is to register the WEVMOS token as a token pair in the ERC-20 module, so it will be + // correctly registered as an active precompile. + cacheCtx, writeFn := ctx.CacheContext() + if err := RunSTRv2Migration(cacheCtx, + logger, + ak, + bk, + erck, + ek, + wrappedContractAddr, + evmDenom, + ); err != nil { + logger.Error("failed to fully convert erc20s to native coins", "error", err.Error()) + } else { + // Write the cache to the context + writeFn() + } + + // Leave modules are as-is to avoid running InitGenesis. + logger.Debug("running module migrations ...") + return mm.RunMigrations(ctx, configurator, vm) + } +} diff --git a/app/upgrades/v20/utils_test.go b/app/upgrades/v20/utils_test.go new file mode 100644 index 0000000000..fc2dbea416 --- /dev/null +++ b/app/upgrades/v20/utils_test.go @@ -0,0 +1,188 @@ +package v20_test + +import ( + errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/evmos/evmos/v18/contracts" + testfactory "github.com/evmos/evmos/v18/testutil/integration/evmos/factory" + "github.com/evmos/evmos/v18/testutil/integration/evmos/grpc" + testkeyring "github.com/evmos/evmos/v18/testutil/integration/evmos/keyring" + "github.com/evmos/evmos/v18/testutil/integration/evmos/network" + "github.com/evmos/evmos/v18/testutil/integration/evmos/utils" + erc20types "github.com/evmos/evmos/v18/x/erc20/types" + evmtypes "github.com/evmos/evmos/v18/x/evm/types" +) + +const ( + AEVMOS = "aevmos" + XMPL = "xmpl" + + // erc20Deployer is the index for the account that deploys the ERC-20 contract. + erc20Deployer = 0 +) + +// sentWEVMOS is the amount of WEVMOS sent to the WEVMOS contract during testing. +var sentWEVMOS = sdk.NewInt(1e18) + +// NewConvertERC20CoinsTestSuite sets up a test suite to test the conversion of ERC-20 coins to native coins. +// +// It sets up a basic integration test suite with accounts, that contain balances in a native non-Evmos coin. +// This coin is registered as an ERC-20 token pair in the ERC-20 module keeper, +// and a portion of the initial balance is converted to the ERC-20 representation upon genesis already. +// +// This also means, that the ERC-20 module address has a balance of the escrowed ERC-20 token pair coins. +func NewConvertERC20CoinsTestSuite() (*ConvertERC20CoinsTestSuite, error) { + kr := testkeyring.New(1) + fundedBalances := []banktypes.Balance{ + { + Address: kr.GetAccAddr(erc20Deployer).String(), + Coins: sdk.NewCoins( + sdk.NewCoin(AEVMOS, network.PrefundedAccountInitialBalance), + ), + }, + { + Address: bech32WithERC20s.String(), + Coins: sdk.NewCoins( + sdk.NewCoin(AEVMOS, network.PrefundedAccountInitialBalance), + sdk.NewInt64Coin(XMPL, 500), + ), + }, + // NOTE: Here, we are adding the ERC-20 module address to the funded balances, + // since we have "converted coins to ERC-20s". + // This initial balance is representative of the escrowed coins during this operation. + { + Address: types.NewModuleAddress(erc20types.ModuleName).String(), + Coins: sdk.NewCoins(sdk.NewInt64Coin(XMPL, 100)), + }, + } + + genesisState := createGenesisWithTokenPairs(kr) + + nw := network.NewUnitTestNetwork( + network.WithCustomGenesis(genesisState), + network.WithBalances(fundedBalances...), + ) + handler := grpc.NewIntegrationHandler(nw) + txFactory := testfactory.New(nw, handler) + + return &ConvertERC20CoinsTestSuite{ + keyring: kr, + network: nw, + handler: handler, + factory: txFactory, + }, nil +} + +// PrepareNetwork is a helper method to take care of the following steps to prepare the test suite for +// testing the STR v2 migrations: +// +// - deploy an ERC-20 token contract (EVM-native!) +// - register a token pair for this smart contract +// - mint some tokens to the deployer account +// - This is to show that non-native registered ERC20s are not converted and their balances still remain only in the EVM. +func PrepareNetwork(ts *ConvertERC20CoinsTestSuite) (*ConvertERC20CoinsTestSuite, error) { + // NOTE: we are adjusting the gov params to have a min deposit of 0 for the voting proposal. + // This makes it simpler to register the token pair for the test. + govParamsRes, err := ts.handler.GetGovParams("voting") + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to get gov params") + } + + govParams := govParamsRes.GetParams() + govParams.MinDeposit = sdk.Coins{} + err = ts.network.UpdateGovParams(*govParams) + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to update gov params") + } + + // NOTE: We deploy a standard ERC-20 to show that non-native registered ERC20s + // are not converted and their balances still remain untouched. + erc20Addr, err := ts.factory.DeployContract(ts.keyring.GetPrivKey(erc20Deployer), + evmtypes.EvmTxArgs{}, + testfactory.ContractDeploymentData{ + Contract: contracts.ERC20MinterBurnerDecimalsContract, + ConstructorArgs: []interface{}{ + "MYTOKEN", "TKN", uint8(18), + }, + }, + ) + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to deploy ERC-20 contract") + } + + err = ts.network.NextBlock() + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to execute block") + } + + // We mint some tokens to the deployer address. + _, err = ts.factory.ExecuteContractCall( + ts.keyring.GetPrivKey(erc20Deployer), evmtypes.EvmTxArgs{To: &erc20Addr}, testfactory.CallArgs{ + ContractABI: contracts.ERC20MinterBurnerDecimalsContract.ABI, + MethodName: "mint", + Args: []interface{}{ts.keyring.GetAddr(erc20Deployer), mintAmount}, + }, + ) + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to mint ERC-20 tokens") + } + + err = ts.network.NextBlock() + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to execute block") + } + + // NOTE: We register the ERC-20 token as a token pair. + nonNativeTokenPair, err := utils.RegisterERC20(ts.factory, ts.network, utils.ERC20RegistrationData{ + Address: erc20Addr, + Denom: "MYTOKEN", + ProposerPriv: ts.keyring.GetPrivKey(erc20Deployer), + }) + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to register ERC-20 token") + } + + // NOTE: We deploy another smart contract. This is a wrapped token contract + // as a representation of the WEVMOS token. + wevmosAddr, err := ts.factory.DeployContract( + ts.keyring.GetPrivKey(erc20Deployer), + evmtypes.EvmTxArgs{}, + testfactory.ContractDeploymentData{Contract: contracts.WEVMOSContract}, + ) + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to deploy WEVMOS contract") + } + + err = ts.network.NextBlock() + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to execute block") + } + + // send some coins to the wevmos address to deposit them. + _, err = ts.factory.ExecuteEthTx( + ts.keyring.GetPrivKey(erc20Deployer), + evmtypes.EvmTxArgs{ + To: &wevmosAddr, + Amount: sentWEVMOS.BigInt(), + // FIXME: the gas simulation is not working correctly - otherwise results in out of gas + GasLimit: 100_000, + }, + ) + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to send WEVMOS to contract") + } + + err = ts.network.NextBlock() + if err != nil { + return &ConvertERC20CoinsTestSuite{}, errorsmod.Wrap(err, "failed to execute block") + } + + // Assign dynamic values to the test suite (=those that were not included in genesis). + ts.erc20Contract = erc20Addr + ts.nonNativeTokenPair = nonNativeTokenPair + ts.wevmosContract = wevmosAddr + + return ts, nil +}