diff --git a/x/crosschain/keeper/evm_hooks.go b/x/crosschain/keeper/evm_hooks.go index a9779766d8..c575598cf1 100644 --- a/x/crosschain/keeper/evm_hooks.go +++ b/x/crosschain/keeper/evm_hooks.go @@ -129,8 +129,13 @@ func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20W if err != nil { return fmt.Errorf("cannot encode address %s: %s", event.To, err.Error()) } - gasLimit := foreignCoin.GasLimit - // gasLimit+uint64(event.Raw.Index) to genereate different cctx for multiple events in the same tx. + + gasLimit, err := k.fungibleKeeper.QueryGasLimit(ctx, ethcommon.HexToAddress(foreignCoin.Zrc20ContractAddress)) + if err != nil { + return fmt.Errorf("cannot query gas limit: %s", err.Error()) + } + + // gasLimit+uint64(event.Raw.Index) to generate different cctx for multiple events in the same tx. msg := types.NewMsgVoteOnObservedInboundTx( "", emittingContract.Hex(), @@ -142,7 +147,7 @@ func (k Keeper) ProcessZRC20WithdrawalEvent(ctx sdk.Context, event *zrc20.ZRC20W "", event.Raw.TxHash.String(), event.Raw.BlockNumber, - gasLimit+uint64(event.Raw.Index), + gasLimit.Uint64()+uint64(event.Raw.Index), foreignCoin.CoinType, foreignCoin.Asset, ) diff --git a/x/crosschain/keeper/gas_payment_test.go b/x/crosschain/keeper/gas_payment_test.go index e110017694..d15bf96e94 100644 --- a/x/crosschain/keeper/gas_payment_test.go +++ b/x/crosschain/keeper/gas_payment_test.go @@ -99,6 +99,7 @@ func setupGasCoin( assetName, symbol, 8, + nil, ) require.NoError(t, err) assertContractDeployment(t, evmk, ctx, addr) diff --git a/x/crosschain/keeper/msg_server_whitelist_erc20_test.go b/x/crosschain/keeper/msg_server_whitelist_erc20_test.go index 0f7fa29916..8a2925ddcd 100644 --- a/x/crosschain/keeper/msg_server_whitelist_erc20_test.go +++ b/x/crosschain/keeper/msg_server_whitelist_erc20_test.go @@ -57,6 +57,11 @@ func TestKeeper_WhitelistERC20(t *testing.T) { require.True(t, found) require.EqualValues(t, fmt.Sprintf("%s:%s", common.CmdWhitelistERC20, erc20Address), cctx.RelayedMessage) + // check gas limit is set + gasLimit, err := zk.FungibleKeeper.QueryGasLimit(ctx, ethcommon.HexToAddress(zrc20)) + require.NoError(t, err) + require.Equal(t, uint64(100000), gasLimit.Uint64()) + // Ensure that whitelist a new erc20 create a cctx with a different index res, err = k.WhitelistERC20(ctx, &types.MsgWhitelistERC20{ Creator: admin, diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go index 803510d38d..c806073894 100644 --- a/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts_privnet.go @@ -83,13 +83,13 @@ func (k Keeper) BlockOneDeploySystemContracts(goCtx context.Context) error { return err } - ETHZRC20Addr, err := k.SetupChainGasCoinAndPool(ctx, common.GoerliChain().ChainId, "ETH", "gETH", 18) + ETHZRC20Addr, err := k.SetupChainGasCoinAndPool(ctx, common.GoerliChain().ChainId, "ETH", "gETH", 18, nil) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } ctx.Logger().Info("Deployed ETH ZRC20 at " + ETHZRC20Addr.String()) - BTCZRC20Addr, err := k.SetupChainGasCoinAndPool(ctx, common.BtcRegtestChain().ChainId, "BTC", "tBTC", 8) + BTCZRC20Addr, err := k.SetupChainGasCoinAndPool(ctx, common.BtcRegtestChain().ChainId, "BTC", "tBTC", 8, nil) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } diff --git a/x/fungible/keeper/begin_blocker_deploy_system_contracts_testnet.go b/x/fungible/keeper/begin_blocker_deploy_system_contracts_testnet.go index cb516422cc..5c19164ba0 100644 --- a/x/fungible/keeper/begin_blocker_deploy_system_contracts_testnet.go +++ b/x/fungible/keeper/begin_blocker_deploy_system_contracts_testnet.go @@ -76,20 +76,20 @@ func (k Keeper) BlockOneDeploySystemContracts(goCtx context.Context) error { if err != nil { return err } - _, err = k.SetupChainGasCoinAndPool(ctx, common.GoerliChain().ChainId, "ETH", "gETH", 18) + _, err = k.SetupChainGasCoinAndPool(ctx, common.GoerliChain().ChainId, "ETH", "gETH", 18, nil) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } - _, err = k.SetupChainGasCoinAndPool(ctx, common.BscTestnetChain().ChainId, "BNB", "tBNB", 18) + _, err = k.SetupChainGasCoinAndPool(ctx, common.BscTestnetChain().ChainId, "BNB", "tBNB", 18, nil) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } - _, err = k.SetupChainGasCoinAndPool(ctx, common.MumbaiChain().ChainId, "MATIC", "tMATIC", 18) + _, err = k.SetupChainGasCoinAndPool(ctx, common.MumbaiChain().ChainId, "MATIC", "tMATIC", 18, nil) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } - _, err = k.SetupChainGasCoinAndPool(ctx, common.BtcTestNetChain().ChainId, "BTC", "tBTC", 8) + _, err = k.SetupChainGasCoinAndPool(ctx, common.BtcTestNetChain().ChainId, "BTC", "tBTC", 8, nil) if err != nil { return sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } diff --git a/x/fungible/keeper/gas_coin_and_pool.go b/x/fungible/keeper/gas_coin_and_pool.go index 493977a879..ce725743cb 100644 --- a/x/fungible/keeper/gas_coin_and_pool.go +++ b/x/fungible/keeper/gas_coin_and_pool.go @@ -18,16 +18,28 @@ import ( // SetupChainGasCoinAndPool setup gas ZRC20, and ZETA/gas pool for a chain // add 0.1gas/0.1wzeta to the pool // FIXME: add cointype and use proper gas limit based on cointype/chain -func (k Keeper) SetupChainGasCoinAndPool(ctx sdk.Context, chainID int64, gasAssetName string, symbol string, decimals uint8) (ethcommon.Address, error) { +func (k Keeper) SetupChainGasCoinAndPool( + ctx sdk.Context, + chainID int64, + gasAssetName string, + symbol string, + decimals uint8, + gasLimit *big.Int, +) (ethcommon.Address, error) { chain := common.GetChainFromChainID(chainID) if chain == nil { return ethcommon.Address{}, zetaObserverTypes.ErrSupportedChains } name := fmt.Sprintf("%s-%s", gasAssetName, chain.ChainName) - transferGasLimit := big.NewInt(21_000) - if common.IsBitcoinChain(chain.ChainId) { - transferGasLimit = big.NewInt(100) // 100B for a typical tx + transferGasLimit := gasLimit + + // default values + if transferGasLimit == nil { + transferGasLimit = big.NewInt(21_000) + if common.IsBitcoinChain(chain.ChainId) { + transferGasLimit = big.NewInt(100) // 100B for a typical tx + } } zrc20Addr, err := k.DeployZRC20Contract(ctx, name, symbol, decimals, chain.ChainId, common.CoinType_Gas, "", transferGasLimit) diff --git a/x/fungible/keeper/gas_coin_and_pool_test.go b/x/fungible/keeper/gas_coin_and_pool_test.go index c2fb61e960..9bdd139fdc 100644 --- a/x/fungible/keeper/gas_coin_and_pool_test.go +++ b/x/fungible/keeper/gas_coin_and_pool_test.go @@ -30,6 +30,7 @@ func setupGasCoin( assetName, symbol, 8, + nil, ) require.NoError(t, err) assertContractDeployment(t, evmk, ctx, addr) diff --git a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go index 4784f3f3f6..24ab3f5f87 100644 --- a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go +++ b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20.go @@ -45,7 +45,7 @@ func (k msgServer) DeployFungibleCoinZRC20(goCtx context.Context, msg *types.Msg } if msg.CoinType == zetacommon.CoinType_Gas { // #nosec G701 always in range - address, err = k.SetupChainGasCoinAndPool(ctx, msg.ForeignChainId, msg.Name, msg.Symbol, uint8(msg.Decimals)) + address, err = k.SetupChainGasCoinAndPool(ctx, msg.ForeignChainId, msg.Name, msg.Symbol, uint8(msg.Decimals), big.NewInt(msg.GasLimit)) if err != nil { return nil, sdkerrors.Wrapf(err, "failed to setupChainGasCoinAndPool") } diff --git a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go index e40c1af9ae..788feba0fb 100644 --- a/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go +++ b/x/fungible/keeper/msg_server_deploy_fungible_coin_zrc20_test.go @@ -46,6 +46,11 @@ func TestMsgServer_DeployFungibleCoinZRC20(t *testing.T) { require.Equal(t, foreignCoin.CoinType, common.CoinType_Gas) require.Contains(t, foreignCoin.Name, "foo") + // check gas limit + gasLimit, err := k.QueryGasLimit(ctx, ethcommon.HexToAddress(foreignCoin.Zrc20ContractAddress)) + require.NoError(t, err) + require.Equal(t, uint64(1000000), gasLimit.Uint64()) + gas, err := k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) require.NoError(t, err) require.Equal(t, gasAddress, gas.Hex()) @@ -59,7 +64,7 @@ func TestMsgServer_DeployFungibleCoinZRC20(t *testing.T) { "bar", "bar", common.CoinType_ERC20, - 1000000, + 2000000, )) require.NoError(t, err) assertContractDeployment(t, sdkk.EvmKeeper, ctx, ethcommon.HexToAddress(res.Address)) @@ -69,6 +74,11 @@ func TestMsgServer_DeployFungibleCoinZRC20(t *testing.T) { require.Equal(t, foreignCoin.CoinType, common.CoinType_ERC20) require.Contains(t, foreignCoin.Name, "bar") + // check gas limit + gasLimit, err = k.QueryGasLimit(ctx, ethcommon.HexToAddress(foreignCoin.Zrc20ContractAddress)) + require.NoError(t, err) + require.Equal(t, uint64(2000000), gasLimit.Uint64()) + // gas should remain the same gas, err = k.QuerySystemContractGasCoinZRC20(ctx, big.NewInt(chainID)) require.NoError(t, err)