Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CW->ERC pointer registry #1499

Merged
merged 2 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ func New(

app.EvmKeeper = *evmkeeper.NewKeeper(keys[evmtypes.StoreKey], memKeys[evmtypes.MemStoreKey],
app.GetSubspace(evmtypes.ModuleName), app.BankKeeper, &app.AccountKeeper, &app.StakingKeeper,
app.TransferKeeper)
app.TransferKeeper, wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper))
app.evmRPCConfig, err = evmrpc.ReadConfig(appOpts)
if err != nil {
panic(fmt.Sprintf("error reading EVM config due to %s", err))
Expand Down Expand Up @@ -806,8 +806,8 @@ func New(
oracletypes.ModuleName,
tokenfactorytypes.ModuleName,
epochmoduletypes.ModuleName,
evmtypes.ModuleName,
wasm.ModuleName,
evmtypes.ModuleName,
acltypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/initGenesis
)
Expand Down
16 changes: 16 additions & 0 deletions proto/evm/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ option go_package = "github.com/sei-protocol/sei-chain/x/evm/types";
service Msg {
rpc EVMTransaction(MsgEVMTransaction) returns (MsgEVMTransactionResponse);
rpc Send(MsgSend) returns (MsgSendResponse);
rpc RegisterPointer(MsgRegisterPointer) returns (MsgRegisterPointerResponse);
}

message MsgEVMTransaction {
Expand Down Expand Up @@ -53,3 +54,18 @@ message MsgSend {
}

message MsgSendResponse {}

enum PointerType {
ERC20 = 0;
ERC721 = 1;
}

message MsgRegisterPointer {
string sender = 1;
PointerType pointer_type = 2;
string erc_address = 3;
}

message MsgRegisterPointerResponse {
string pointer_address = 1;
}
3 changes: 2 additions & 1 deletion testutil/keeper/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import (
"encoding/hex"
"sync"
"time"

"github.com/cosmos/cosmos-sdk/crypto/hd"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
Expand Down Expand Up @@ -51,7 +52,7 @@

func MockEVMKeeper() (*evmkeeper.Keeper, sdk.Context) {
testApp := app.Setup(false, false)
ctx := testApp.GetContextForDeliverTx([]byte{}).WithBlockHeight(8)
ctx := testApp.GetContextForDeliverTx([]byte{}).WithBlockHeight(8).WithBlockTime(time.Now())

Check warning

Code scanning / CodeQL

Calling the system time Warning test

Calling the system time may be a possible source of non-determinism
k := testApp.EvmKeeper
k.InitGenesis(ctx, *evmtypes.DefaultGenesis())

Expand Down
22 changes: 22 additions & 0 deletions x/evm/artifacts/erc20/artifacts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package erc20

import "embed"

const CurrentVersion uint16 = 1

//go:embed cwerc20.wasm
var f embed.FS

var cachedBin []byte

func GetBin() []byte {
if cachedBin != nil {
return cachedBin
}
bz, err := f.ReadFile("cwerc20.wasm")
if err != nil {
panic("failed to read ERC20 wrapper contract wasm")
}
cachedBin = bz
return bz
}
Binary file added x/evm/artifacts/erc20/cwerc20.wasm
Binary file not shown.
22 changes: 22 additions & 0 deletions x/evm/artifacts/erc721/artifacts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package erc721

import "embed"

const CurrentVersion uint16 = 1

//go:embed cwerc721.wasm
var f embed.FS

var cachedBin []byte

func GetBin() []byte {
if cachedBin != nil {
return cachedBin
}
bz, err := f.ReadFile("cwerc721.wasm")
if err != nil {
panic("failed to read ERC721 wrapper contract wasm")
}
cachedBin = bz
return bz
}
Binary file added x/evm/artifacts/erc721/cwerc721.wasm
Binary file not shown.
15 changes: 15 additions & 0 deletions x/evm/artifacts/utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package utils

import "encoding/binary"

func GetVersionBz(version uint16) []byte {
res := make([]byte, 2)
binary.BigEndian.PutUint16(res, version)
return res
}

func GetCodeIDBz(codeID uint64) []byte {
res := make([]byte, 8)
binary.BigEndian.PutUint64(res, codeID)
return res
}
22 changes: 22 additions & 0 deletions x/evm/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
"fmt"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -13,6 +14,9 @@ import (
"github.com/ethereum/go-ethereum/trie/triedb/hashdb"
"github.com/ethereum/go-ethereum/trie/triedb/pathdb"

"github.com/sei-protocol/sei-chain/x/evm/artifacts/erc20"
"github.com/sei-protocol/sei-chain/x/evm/artifacts/erc721"
artifactsutils "github.com/sei-protocol/sei-chain/x/evm/artifacts/utils"
"github.com/sei-protocol/sei-chain/x/evm/types"
)

Expand All @@ -31,6 +35,24 @@ func (k *Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) {
k.SetAddressMapping(ctx, sdk.MustAccAddressFromBech32(addr.SeiAddress), common.HexToAddress(addr.EthAddress))
}

erc20CodeID, err := k.wasmKeeper.Create(ctx, k.accountKeeper.GetModuleAddress(types.ModuleName), erc20.GetBin(), nil)
if err != nil {
panic(err)
}
prefix.NewStore(k.PrefixStore(ctx, types.PointerCWCodePrefix), types.PointerCW20ERC20Prefix).Set(
artifactsutils.GetVersionBz(erc20.CurrentVersion),
artifactsutils.GetCodeIDBz(erc20CodeID),
)

erc721CodeID, err := k.wasmKeeper.Create(ctx, k.accountKeeper.GetModuleAddress(types.ModuleName), erc721.GetBin(), nil)
if err != nil {
panic(err)
}
prefix.NewStore(k.PrefixStore(ctx, types.PointerCWCodePrefix), types.PointerCW721ERC721Prefix).Set(
artifactsutils.GetVersionBz(erc721.CurrentVersion),
artifactsutils.GetCodeIDBz(erc721CodeID),
)

if k.EthReplayConfig.Enabled && !ethReplayInitialied {
header := k.OpenEthDatabase()
params := k.GetParams(ctx)
Expand Down
9 changes: 8 additions & 1 deletion x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"sort"
"sync"

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
Expand Down Expand Up @@ -49,6 +50,7 @@ type Keeper struct {
accountKeeper *authkeeper.AccountKeeper
stakingKeeper *stakingkeeper.Keeper
transferKeeper ibctransferkeeper.Keeper
wasmKeeper *wasmkeeper.PermissionedKeeper

cachedFeeCollectorAddressMtx *sync.RWMutex
cachedFeeCollectorAddress *common.Address
Expand Down Expand Up @@ -109,7 +111,7 @@ func (ctx *ReplayChainContext) GetHeader(hash common.Hash, number uint64) *ethty
func NewKeeper(
storeKey sdk.StoreKey, memStoreKey sdk.StoreKey, paramstore paramtypes.Subspace,
bankKeeper bankkeeper.Keeper, accountKeeper *authkeeper.AccountKeeper, stakingKeeper *stakingkeeper.Keeper,
transferKeeper ibctransferkeeper.Keeper) *Keeper {
transferKeeper ibctransferkeeper.Keeper, wasmKeeper *wasmkeeper.PermissionedKeeper) *Keeper {
if !paramstore.HasKeyTable() {
paramstore = paramstore.WithKeyTable(types.ParamKeyTable())
}
Expand All @@ -121,6 +123,7 @@ func NewKeeper(
accountKeeper: accountKeeper,
stakingKeeper: stakingKeeper,
transferKeeper: transferKeeper,
wasmKeeper: wasmKeeper,
pendingTxs: make(map[string][]*PendingTx),
nonceMx: &sync.RWMutex{},
cachedFeeCollectorAddressMtx: &sync.RWMutex{},
Expand All @@ -138,6 +141,10 @@ func (k *Keeper) BankKeeper() bankkeeper.Keeper {
return k.bankKeeper
}

func (k *Keeper) WasmKeeper() *wasmkeeper.PermissionedKeeper {
return k.wasmKeeper
}

func (k *Keeper) GetStoreKey() sdk.StoreKey {
return k.storeKey
}
Expand Down
58 changes: 58 additions & 0 deletions x/evm/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package keeper

import (
"context"
"encoding/binary"
"encoding/json"
"fmt"
"math"
"math/big"
"runtime/debug"

"github.com/armon/go-metrics"
"github.com/cosmos/cosmos-sdk/store/prefix"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
Expand All @@ -19,6 +22,9 @@ import (
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/sei-protocol/sei-chain/utils"
"github.com/sei-protocol/sei-chain/x/evm/artifacts/erc20"
"github.com/sei-protocol/sei-chain/x/evm/artifacts/erc721"
artifactsutils "github.com/sei-protocol/sei-chain/x/evm/artifacts/utils"
"github.com/sei-protocol/sei-chain/x/evm/state"
"github.com/sei-protocol/sei-chain/x/evm/types"
)
Expand Down Expand Up @@ -249,3 +255,55 @@ func (server msgServer) Send(goCtx context.Context, msg *types.MsgSend) (*types.
}
return &types.MsgSendResponse{}, nil
}

func (server msgServer) RegisterPointer(goCtx context.Context, msg *types.MsgRegisterPointer) (*types.MsgRegisterPointerResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
var existingPointer sdk.AccAddress
var existingVersion uint16
var currentVersion uint16
var exists bool
switch msg.PointerType {
case types.PointerType_ERC20:
currentVersion = erc20.CurrentVersion
existingPointer, existingVersion, exists = server.GetCW20ERC20Pointer(ctx, common.HexToAddress(msg.ErcAddress))
case types.PointerType_ERC721:
currentVersion = erc721.CurrentVersion
existingPointer, existingVersion, exists = server.GetCW721ERC721Pointer(ctx, common.HexToAddress(msg.ErcAddress))
default:
panic("unknown pointer type")
}
if exists && existingVersion >= currentVersion {
return nil, fmt.Errorf("pointer %s already registered at version %d", existingPointer.String(), existingVersion)
}
store := server.PrefixStore(ctx, types.PointerCWCodePrefix)
payload := map[string]interface{}{}
switch msg.PointerType {
case types.PointerType_ERC20:
store = prefix.NewStore(store, types.PointerCW20ERC20Prefix)
payload["erc20_address"] = msg.ErcAddress
case types.PointerType_ERC721:
store = prefix.NewStore(store, types.PointerCW721ERC721Prefix)
payload["erc721_address"] = msg.ErcAddress
default:
panic("unknown pointer type")
}
codeID := binary.BigEndian.Uint64(store.Get(artifactsutils.GetVersionBz(currentVersion)))
bz, err := json.Marshal(payload)
if err != nil {
return nil, err
}
moduleAcct := server.accountKeeper.GetModuleAddress(types.ModuleName)
pointerAddr, _, err := server.wasmKeeper.Instantiate(ctx, codeID, moduleAcct, moduleAcct, bz, fmt.Sprintf("Pointer of %s", msg.ErcAddress), sdk.NewCoins())
if err != nil {
return nil, err
}
switch msg.PointerType {
case types.PointerType_ERC20:
err = server.SetCW20ERC20Pointer(ctx, common.HexToAddress(msg.ErcAddress), pointerAddr.String())
case types.PointerType_ERC721:
err = server.SetCW721ERC721Pointer(ctx, common.HexToAddress(msg.ErcAddress), pointerAddr.String())
default:
panic("unknown pointer type")
}
return &types.MsgRegisterPointerResponse{PointerAddress: pointerAddr.String()}, err
}
45 changes: 45 additions & 0 deletions x/evm/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import (
"github.com/sei-protocol/sei-chain/example/contracts/simplestorage"
testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper"
"github.com/sei-protocol/sei-chain/x/evm/ante"
"github.com/sei-protocol/sei-chain/x/evm/artifacts/erc20"
"github.com/sei-protocol/sei-chain/x/evm/artifacts/erc721"
"github.com/sei-protocol/sei-chain/x/evm/keeper"
"github.com/sei-protocol/sei-chain/x/evm/state"
"github.com/sei-protocol/sei-chain/x/evm/types"
Expand Down Expand Up @@ -456,3 +458,46 @@ func TestSend(t *testing.T) {
require.Equal(t, sdk.NewInt(500000), k.BankKeeper().GetBalance(ctx, seiFrom, "usei").Amount)
require.Equal(t, sdk.NewInt(500000), k.BankKeeper().GetBalance(ctx, seiTo, "usei").Amount)
}

func TestRegisterPointer(t *testing.T) {
k, ctx := testkeeper.MockEVMKeeper()
sender, _ := testkeeper.MockAddressPair()
_, pointee := testkeeper.MockAddressPair()
res, err := keeper.NewMsgServerImpl(k).RegisterPointer(sdk.WrapSDKContext(ctx), &types.MsgRegisterPointer{
Sender: sender.String(),
PointerType: types.PointerType_ERC20,
ErcAddress: pointee.Hex(),
})
require.Nil(t, err)
pointer, version, exists := k.GetCW20ERC20Pointer(ctx, pointee)
require.True(t, exists)
require.Equal(t, erc20.CurrentVersion, version)
require.Equal(t, pointer.String(), res.PointerAddress)

// already exists
_, err = keeper.NewMsgServerImpl(k).RegisterPointer(sdk.WrapSDKContext(ctx), &types.MsgRegisterPointer{
Sender: sender.String(),
PointerType: types.PointerType_ERC20,
ErcAddress: pointee.Hex(),
})
require.NotNil(t, err)

res, err = keeper.NewMsgServerImpl(k).RegisterPointer(sdk.WrapSDKContext(ctx), &types.MsgRegisterPointer{
Sender: sender.String(),
PointerType: types.PointerType_ERC721,
ErcAddress: pointee.Hex(),
})
require.Nil(t, err)
pointer, version, exists = k.GetCW721ERC721Pointer(ctx, pointee)
require.True(t, exists)
require.Equal(t, erc721.CurrentVersion, version)
require.Equal(t, pointer.String(), res.PointerAddress)

// already exists
_, err = keeper.NewMsgServerImpl(k).RegisterPointer(sdk.WrapSDKContext(ctx), &types.MsgRegisterPointer{
Sender: sender.String(),
PointerType: types.PointerType_ERC721,
ErcAddress: pointee.Hex(),
})
require.NotNil(t, err)
}
Loading
Loading