Skip to content

Commit

Permalink
feat: migrate WFX to WPUNDIAI (PundiAI#917)
Browse files Browse the repository at this point in the history
  • Loading branch information
zakir-code authored Jan 16, 2025
1 parent 2e86610 commit f12c298
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 1 deletion.
25 changes: 25 additions & 0 deletions app/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func Test_UpgradeTestnet(t *testing.T) {

checkMetadataValidate(t, ctx, myApp)
checkPundiAIFXERC20Token(t, ctx, myApp)
checkWrapToken(t, ctx, myApp)
}

func buildApp(t *testing.T) *app.App {
Expand Down Expand Up @@ -164,6 +165,9 @@ func beforeUpgrade(ctx sdk.Context, myApp *app.App) BeforeUpgradeData {

func checkAppUpgrade(t *testing.T, ctx sdk.Context, myApp *app.App, bdd BeforeUpgradeData) {
t.Helper()

checkWrapToken(t, ctx, myApp)

checkStakingMigrationDelete(t, ctx, myApp)

checkGovCustomParams(t, ctx, myApp)
Expand All @@ -183,6 +187,27 @@ func checkAppUpgrade(t *testing.T, ctx sdk.Context, myApp *app.App, bdd BeforeUp
checkPundiAIFXERC20Token(t, ctx, myApp)
}

func checkWrapToken(t *testing.T, ctx sdk.Context, myApp *app.App) {
t.Helper()
erc20TokenKeeper := contract.NewERC20TokenKeeper(myApp.EvmKeeper)
wrapTokenAddress := nextversion.GetWFXAddress(ctx.ChainID())
name, err := erc20TokenKeeper.Name(ctx, wrapTokenAddress)
require.NoError(t, err)
assert.EqualValues(t, nextversion.WrapTokenName, name)
symbol, err := erc20TokenKeeper.Symbol(ctx, wrapTokenAddress)
require.NoError(t, err)
assert.EqualValues(t, nextversion.WrapTokenSymbol, symbol)
decimals, err := erc20TokenKeeper.Decimals(ctx, wrapTokenAddress)
require.NoError(t, err)
assert.EqualValues(t, 18, decimals)
owner, err := erc20TokenKeeper.Owner(ctx, wrapTokenAddress)
require.NoError(t, err)
assert.EqualValues(t, common.BytesToAddress(myApp.AccountKeeper.GetModuleAddress(erc20types.ModuleName).Bytes()), owner)
supply, err := erc20TokenKeeper.TotalSupply(ctx, wrapTokenAddress)
require.NoError(t, err)
assert.EqualValues(t, 1, supply.Cmp(big.NewInt(0)))
}

func checkLayer2OracleIsOnline(t *testing.T, ctx sdk.Context, layer2Keeper crosschainkeeper.Keeper) {
t.Helper()
oracles := layer2Keeper.GetAllOracles(ctx, false)
Expand Down
5 changes: 5 additions & 0 deletions app/upgrades/v8/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ func upgradeTestnet(ctx sdk.Context, app *keepers.AppKeepers) error {
if err := migrateErc20FXToPundiAI(ctx, app.Erc20Keeper); err != nil {
return err
}

migrationWFXToWPUNDIAI(ctx, app.EvmKeeper)

return migrateMetadataFXToPundiAI(ctx, app.BankKeeper)
}

Expand All @@ -122,6 +125,8 @@ func upgradeMainnet(
return fromVM, err
}

migrationWFXToWPUNDIAI(ctx, app.EvmKeeper)

if err = migrateEvmParams(ctx, app.EvmKeeper); err != nil {
return fromVM, err
}
Expand Down
107 changes: 107 additions & 0 deletions app/upgrades/v8/wrap_token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package v8

import (
"bytes"
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"

fxtypes "github.com/pundiai/fx-core/v8/types"
fxevmkeeper "github.com/pundiai/fx-core/v8/x/evm/keeper"
)

const (
WrapTokenSymbol = "WPUNDIAI"
// #nosec G101
WrapTokenName = "Wrapped Pundi AIFX Token"
)

const (
nameSlot = 201
symbolSlot = 202
totalSupplySlot = 204
lastSlot = 300
)

var (
// skip eip1967.proxy.implementation 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
eip1967ProxyImplKey = common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc")
// skip eip1967.proxy.admin
eip1967ProxyAdminKey = common.HexToHash("0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103")
// skip eip1967.proxy.rollback
eip1967ProxyRollbackKey = common.HexToHash("0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143")
// skip eip1967.proxy.beacon
eip1967ProxyBeaconKey = common.HexToHash("0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50")

mainnetWFXAddress = common.HexToAddress("0x80b5a32E4F032B2a058b4F29EC95EEfEEB87aDcd")

testnetWFXAddress = common.HexToAddress("0x3452e23F9c4cC62c70B7ADAd699B264AF3549C19")
)

func migrationWFXToWPUNDIAI(ctx sdk.Context, evmKeeper *fxevmkeeper.Keeper) {
wfxAddr := GetWFXAddress(ctx.ChainID())

totalUpdateState := 0
evmKeeper.ForEachStorage(ctx, wfxAddr, func(key, value common.Hash) bool {
slot := big.NewInt(0).SetBytes(key.Bytes())
if slot.Cmp(big.NewInt(lastSlot)) < 0 || isEip1967ProxyKey(key) {
return true
}
evmKeeper.SetState(ctx, wfxAddr, key, scaleDownBy100(value.Bytes()))
totalUpdateState++
return true
})

ctx.Logger().Info("total update state", "total", totalUpdateState)

// set totalSupply
totalSupplyByte := evmKeeper.GetState(ctx, wfxAddr, slotToHashByte(totalSupplySlot))
evmKeeper.SetState(ctx, wfxAddr, slotToHashByte(totalSupplySlot), scaleDownBy100(totalSupplyByte.Bytes()))

// test update storage
nameBytes := encodeShortStringWithoutPrefix(WrapTokenName)
evmKeeper.SetState(ctx, wfxAddr, slotToHashByte(nameSlot), nameBytes)

symbolBytes := encodeShortStringWithoutPrefix(WrapTokenSymbol)
evmKeeper.SetState(ctx, wfxAddr, slotToHashByte(symbolSlot), symbolBytes)
ctx.Logger().Info("migration WFX to WPUNDIAI done")
}

func GetWFXAddress(chainID string) common.Address {
if chainID == fxtypes.MainnetChainId {
return mainnetWFXAddress
}
return testnetWFXAddress
}

func isEip1967ProxyKey(key common.Hash) bool {
return bytes.Equal(key.Bytes(), eip1967ProxyImplKey.Bytes()) ||
bytes.Equal(key.Bytes(), eip1967ProxyAdminKey.Bytes()) ||
bytes.Equal(key.Bytes(), eip1967ProxyRollbackKey.Bytes()) ||
bytes.Equal(key.Bytes(), eip1967ProxyBeaconKey.Bytes())
}

func slotToHashByte(slot uint64) common.Hash {
return common.BigToHash(big.NewInt(int64(slot)))
}

func scaleDownBy100(valueByte []byte) []byte {
value := big.NewInt(0).SetBytes(valueByte)
newValue := value.Div(value, big.NewInt(100))
return common.BigToHash(newValue).Bytes()
}

func encodeShortStringWithoutPrefix(s string) []byte {
if len(s) > 31 {
panic("String exceeds 31 bytes, requires dynamic encoding!")
}
data := []byte(s)
dataLen := len(data) * 2
padding := make([]byte, 31-len(data))
// add padding to the end
data = append(data, padding...)
// add length to last byte (add suffix length)
data = append(data, byte(dataLen))
return data
}
2 changes: 1 addition & 1 deletion scripts/linter.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -eo pipefail

patternLimits=(
"nolint:23"
"#nosec:5"
"#nosec:6"
"CrossChain:4"
"cross chain:0"
"GetERC1967Proxy:4"
Expand Down

0 comments on commit f12c298

Please sign in to comment.