Skip to content

Commit

Permalink
fix: deploy with factory addr and add access list in readme
Browse files Browse the repository at this point in the history
  • Loading branch information
djm07073 committed Oct 21, 2024
1 parent 1ea2c4b commit 5e5409f
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 24 deletions.
12 changes: 10 additions & 2 deletions app/ibc-hooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ type MsgCall struct {
Input string `protobuf:"bytes,3,opt,name=input,proto3" json:"input,omitempty"`
// Value is the amount of fee denom token to transfer to the contract.
Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"`
// AccessList is a predefined list of Ethereum addresses and their corresponding storage slots that a transaction will interact with during its execution. can be none
AccessList []AccessTuple `protobuf:"bytes,5,rep,name=access_list,json=accessList,proto3" json:"access_list"`
}
```

Expand All @@ -75,6 +77,8 @@ msg := MsgCall{
Input: packet.data.memo["evm"]["message"]["input"],
// Value is the amount of fee denom token to transfer to the contract.
Value: packet.data.memo["evm"]["message"]["value"]
// Value is the amount of fee denom token to transfer to the contract.
AccessList: packet.data.memo["evm"]["message"]["access_list"]
}
```

Expand Down Expand Up @@ -188,8 +192,12 @@ Also when a contract make IBC transfer request, it should provide async callback
// execute message on receive packet
"message": {
"contract_addr": "0xerc20_wrapper_contract", // should query erc20 wrapper contract addr
"input": "pack(unwrap, denom, recipient, amount)", // function selector(fc078758) + abiCoder.encode([string,address,address],denom,amount) ref) https://docs.ethers.org/v6/api/abi/abi-coder/#AbiCoder-encode
"value": "0"
"input": "pack(unwrap, denom, recipient, amount)", // function selector(fc078758) + abiCoder.encode([string,address,address],denom,recipient,amount) ref) https://docs.ethers.org/v6/api/abi/abi-coder/#AbiCoder-encode
"value": "0",
"access_list": {
"address" : "...", // contract address
"storage_keys": ["...","..."] // storage keys of contract
}
}
}
}
Expand Down
39 changes: 35 additions & 4 deletions x/evm/contracts/erc20_wrapper/ERC20Wrapper.go

Large diffs are not rendered by default.

21 changes: 6 additions & 15 deletions x/evm/contracts/erc20_wrapper/ERC20Wrapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ contract ERC20Wrapper is
string constant NAME_PREFIX = "Wrapped";
string constant SYMBOL_PREFIX = "W";
uint64 callBackId = 0;
ERC20Factory public immutable factory;
mapping(address => address) public wrappedTokens; // origin -> wrapped
mapping(address => address) public originTokens; // wrapped -> origin
mapping(uint64 => IbcCallBack) private ibcCallBack; // id -> CallBackInfo

constructor(address erc20Factory) {
factory = ERC20Factory(erc20Factory);
}

/**
* @notice This function wraps the tokens and transfer the tokens by ibc transfer
* @dev A sender requires sender approve to this contract to transfer the tokens.
Expand Down Expand Up @@ -125,23 +130,9 @@ contract ERC20Wrapper is
);
}

function _createERC20(
string memory name,
string memory symbol,
uint8 decimals
) internal returns (address) {
ERC20 erc20 = new ERC20(name, symbol, decimals);

// register the ERC20 contract with the ERC20 registry
ERC20_REGISTRY_CONTRACT.register_erc20_from_factory(address(erc20));

emit ERC20Created(address(erc20), address(this));
return address(erc20);
}

function _ensureWrappedTokenExists(address token) internal {
if (wrappedTokens[token] == address(0)) {
address wrappedToken = _createERC20(
address wrappedToken = factory.createERC20(
string.concat(NAME_PREFIX, IERC20(token).name()),
string.concat(SYMBOL_PREFIX, IERC20(token).symbol()),
WRAPPED_DECIMAL
Expand Down
17 changes: 14 additions & 3 deletions x/evm/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"

"github.com/initia-labs/minievm/x/evm/contracts/erc20_factory"
"github.com/initia-labs/minievm/x/evm/contracts/erc20_wrapper"
"github.com/initia-labs/minievm/x/evm/types"
)

Expand All @@ -23,12 +24,12 @@ func (k Keeper) Initialize(ctx context.Context) error {
// InitializeWithDecimals initializes the EVM state at genesis with the given decimals
func (k Keeper) InitializeWithDecimals(ctx context.Context, decimals uint8) error {
// 1. Deploy and store the ERC20 factory contract.
code, err := hexutil.Decode(erc20_factory.Erc20FactoryBin)
factoryCode, err := hexutil.Decode(erc20_factory.Erc20FactoryBin)
if err != nil {
return err
}

_, factoryAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, code, nil, types.ERC20FactorySalt, nil)
_, factoryAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, factoryCode, nil, types.ERC20FactorySalt, nil)
if err != nil {
return err
}
Expand All @@ -50,7 +51,17 @@ func (k Keeper) InitializeWithDecimals(ctx context.Context, decimals uint8) erro
}

// 3. Deploy and store the wrapper ERC20 factory contract for IBC transfers to the destination chain (not compatible due to 18 decimals).
_, wrapperAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, code, nil, types.ERC20WrapperSalt, nil)
wrapperCode, err := hexutil.Decode(erc20_wrapper.Erc20WrapperBin)
if err != nil {
return err
}

Check warning on line 57 in x/evm/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/genesis.go#L56-L57

Added lines #L56 - L57 were not covered by tests
abi, _ := erc20_wrapper.Erc20WrapperMetaData.GetAbi()
wrapperConstructorArg, err := abi.Constructor.Inputs.Pack(factoryAddr)
if err != nil {
return err
}

Check warning on line 62 in x/evm/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/genesis.go#L61-L62

Added lines #L61 - L62 were not covered by tests

_, wrapperAddr, _, err := k.EVMCreate2(ctx, types.StdAddress, append(wrapperCode, wrapperConstructorArg...), nil, types.ERC20WrapperSalt, nil)
if err != nil {
return err
}

Check warning on line 67 in x/evm/keeper/genesis.go

View check run for this annotation

Codecov / codecov/patch

x/evm/keeper/genesis.go#L66-L67

Added lines #L66 - L67 were not covered by tests
Expand Down
24 changes: 24 additions & 0 deletions x/evm/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package keeper_test
import (
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/initia-labs/minievm/x/evm/contracts/erc20_wrapper"
"github.com/initia-labs/minievm/x/evm/types"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -79,3 +81,25 @@ func Test_Genesis(t *testing.T) {
_genState := input.EVMKeeper.ExportGenesis(ctx)
require.Equal(t, genState, _genState)
}

func Test_Initialize(t *testing.T) {
ctx, input := createTestInput(t, false, true)
wrapperAddr, err := input.EVMKeeper.GetERC20WrapperAddr(ctx)
require.NoError(t, err)

caller := common.HexToAddress("0x0")
abi, err := erc20_wrapper.Erc20WrapperMetaData.GetAbi()
require.NoError(t, err)

viewArg, err := abi.Pack("factory")
require.NoError(t, err)

factoryAddrBytes, err := input.EVMKeeper.EVMStaticCall(ctx, caller, wrapperAddr, viewArg, nil)
require.NoError(t, err)

factoryAddr := common.BytesToAddress(factoryAddrBytes)
expectedFactoryAddr, err := input.EVMKeeper.GetERC20FactoryAddr(ctx)
require.NoError(t, err)

require.Equal(t, expectedFactoryAddr, factoryAddr)
}

0 comments on commit 5e5409f

Please sign in to comment.