axelarnetwork / support

Your source for support with the Axelar Network
3 stars 1 forks source link

UNPREDICTABLE_GAS_LIMIT #143

Open ekkis opened 1 month ago

ekkis commented 1 month ago

I'm following the guide at: https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#run-the-custominterchaintokenjs-script-to-deploy-to-polygon

and calling interchainTokenServiceContract.deployTokenManager as indicated in the previous link but I'm getting this error:

Error: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="execution reverted", method="estimateGas" Error Codes Documentation for ethers, a complete, tiny and simple Ethereum library.

according to the docs, this happens because "the transaction is complex in a way that does not permit a node to estimate the gas requirements", so I've replaced the gasAmount with 500000 instead of calling the gasEstimator() function but I still get the error

{
  reason: 'execution reverted',
  code: 'UNPREDICTABLE_GAS_LIMIT',
  method: 'estimateGas',
  transaction: {
    from: '0x6d30f9c939720eD4E982c00d0A6Da1e1dccb178F',
    to: '0xB5FB4BE02232B1bBA4dC8f81dc24C26980dE9e3C',
    value: BigNumber { value: "500000" },
    data: '0x98d78c82e91062b5ede99a4e1b5aae38797aca0a56701e9ceeec39000183782b7d5adaf200000000000000000000000000000...ed4e982c00d0a6da1e1dccb178f000000000000000000000000',
    accessList: null
  }

since I'm no longer calling the gasEstimator then I gather that it's the deployment method that's trying to do its own estimation. as per suggestions on Discord, I've also tried higher values e.g. 2,000,000 but with no resolution. also, I have 100 MATIC in the account, which should be way more than enough to pay for transaction fees

here's my deployment code:

const param = ethers.utils.defaultAbiCoder.encode(
    ["bytes", "address"],
    [signer.address, polygonCustomTokenAddress]
  );

  // const gasAmount = await gasEstimator();
  const gasAmount = 20000000;

  // Deploy the token manager
  const deployTxData = await interchainTokenServiceContract.deployTokenManager(
    "0xe91062b5ede99a4e1b5aae38797aca0a56701e9ceeec39000183782b7d5adaf2",
    "Polygon",
    MINT_BURN,
    param,
    ethers.utils.parseEther("0.01"),
    { value: gasAmount }
  );

and the signature of the contract I'm trying to deploy:

contract SimpleCustomToken is ERC20, ERC20Burnable, AccessControl, ERC20Permit {

// Define a constant for the minter role using keccak256 to generate a unique hash
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    constructor(address defaultAdmin, address minter)
        ERC20("SimpleCustomToken", "SCT") // Set token name and symbol
        ERC20Permit("SimpleCustomToken") // Initialize ERC20Permit with the token name
    {

it has been suggested that the arguments handed to the deployer must match my contract constructor's but I'm not sure if that is correct

thanks in advance,

ekkis

p.s. incidentally, I'm deploying to Polygon/Arbitrum as the Fantom faucet is broken and thus I can't pay for deployments. also, Fantom seems to have no support at all

Olanetsoft commented 1 month ago

Hello @ekkis, thanks for flagging this. I tried simulating the process on my end to see if I could replicate the issue, and there are a few things I noticed from your feedback that I'd like to point out.

The Polygon network you added in your deployment code as "Polygon" is no longer supported, as that was Goerli(we will remove it from docs). You should change it to "polygon-sepolia" as we announced a few months ago, detailed here.

The signature looks correct as it is. Also, when doing the gas estimation using the gasEstimator() method, what parameters are you passing? Could you please share them so I can double-check? There’s no need to hardcode the gas amount like that. Thanks.

ekkis commented 1 month ago

The Polygon network you added in your deployment code as "Polygon" is no longer supported, as that was Goerli(we will remove it from docs). You should change it to "polygon-sepolia" as we announced a few months ago, detailed here.

this is from my hardhat.config.js:

module.exports = {
  solidity: "0.8.27",
  networks: {
    polygon: {
      url: "https://rpc-amoy.polygon.technology/",
      chainid: 80002,
      accounts: [process.env.PRIVATE_KEY]
    },

so I'm using Amoy, which is based on sepolia. that should work right?

that raises another point: in the code as provided in the guide, "Polygon" is used. shouldn't this be "polygon" to match what I have in the hardhat config? or better yet, shouldn't it be EvmChain.POLYGON?

also, I did try the string "polygon-sepolia" but this failed too

Also, when doing the gas estimation using the gasEstimator() method, what parameters are you passing?

none:

const gasAmount = await gasEstimator();

where:

async function gasEstimator() {
  const gas = await api.estimateGasFee(
    EvmChain.ARBITRUM_SEPOLIA,
    EvmChain.POLYGON,
    GasToken.FTM,
    700000,
    1.1
  );

  return gas;
}

and... I just realised the GasToken is set to FTM but I'm deploying to Arbitrum (as Fantom is broken)... so this should be set to something else?

p.s. I set that 3rd value to GasToken.ETH (Arbitrum uses ETH for gas) but it still fails with the same error

ekkis commented 1 month ago

another interesting point... in https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#add-your-private-key-to-env-and-hardhatconfigjs you define polygon like this (your definition has spaces in the url):

polygon: {
      url: "https://polygon-amoy.drpc.org   ",
      chainId: 80001,
      accounts: [PRIVATE_KEY],
    },

but as per the information I looked up for Amoy I see:

    polygon: {
      url: "https://rpc-amoy.polygon.technology/",
      chainid: 80002,
      accounts: [process.env.PRIVATE_KEY]
    },

is your documentation correct?

p.s.

it seems that DRPC is a key-based system so the url as stated would not likely work. it would need to be something like https://lb.drpc.org/ogrpc?network=polygon-amoy&dkey=<key-here> so the better thing is to use the url I'm using. the docs should be fixed

p.p.s.

here's the Polygon page with the authoritative information (the currency symbol is wrong. it is now POL): https://docs.polygon.technology/tools/dApp-development/common-tools/remix/?h=testnet#deploying-to-the-amoy-testnet

ekkis commented 1 month ago

by the way, this section: https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#run-the-custominterchaintokenjs-script-to-deploy-to-polygon contains code that references fantom, not polygon. this needs fixing:

FUNCTION_NAME=deployRemoteTokenManager npx hardhat run customInterchainToken.js --network fantom
ekkis commented 1 month ago

one other note, the tutorial page is divided into 2 sections. the second section "On this page" won't scroll unless I scroll down the entire page. that's really annoying. they should both be scrollable so as to allow access to the shortcuts

ekkis commented 1 month ago

also, perhaps you could clarify for me. Stephan said the parameters passed to the deployTokenManager should match those expected by the contract's constructor (it's not quite what he said, I'm paraphrasing)? so here's what I'm passing:

const param = ethers.utils.defaultAbiCoder.encode(
    ["bytes", "address"],
    [signer.address, polygonCustomTokenAddress]
  );

but as I pointed out previously, the constructor takes 2 addresses, one for the default admin and another for the minter. so are my parameters at fault here? doesn't it seem that "bytes" should be "address"?

ekkis commented 1 month ago

by the way, some guidance for deploying a contract using hardhat in this section would be very useful. it would make the guide complete and help those of us who've never done it. it took me a while to figure out how to:

https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#deploy-an-erc-20-token-on-the-fantom-and-polygon-testnets

ekkis commented 1 month ago

also, the indentation for Deploy a token manager on Fantom (right before Add a main() function) is wrong. it should be one in. it's otherwise confusing

image
ekkis commented 1 month ago

and this section https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#remotely-deploy-a-token-manager-on-the-polygon-testnet would best be called "Deploy a remote token manager on the Polygon testnet"

ekkis commented 1 month ago

the comment to "change salt" in the code below would easily be missed by someone who just copy/pastes and runs the code:

  const deployTxData = await interchainTokenServiceContract.deployTokenManager(
    "0x7f5fe989334ad23b77e8da841f672394d021ae83ff0a24afb461ba19d72e3553", // change salt
    "Polygon",
    MINT_BURN,
    param,
    ethers.utils.parseEther("0.01"),
    { value: gasAmount }
  );

wouldn't it be better to do?

  const deployTxData = await interchainTokenServiceContract.deployTokenManager(
    "0x" + crypto.randomBytes(32).toString("hex")

and what would happen if we don't change the salt?

this issue appears twice in this section of the guide: https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#perform-remote-token-manager-deployment

ekkis commented 1 month ago

I found a note:

When deploying the token manager to a preferred chain other than the local chain (in our example, the Fantom testnet) while the remote chain is Polygon, make sure to deploy the remote token manager from the local chain

this makes no sense. I don't have a local chain (because I deployed to a preferred chain (Arbitrum since Fantom is broken)). so how is this supposed to be done?

just to try it, I ran:

FUNCTION_NAME=deployRemoteTokenManager npx hardhat run customInterchainToken.js --network fantom

instead of using --network arbitrum (as I had it before), but it still fails in the same way

If you deploy to the Polygon testnet, you may encounter a TokenManagerDoesNotExist error. This error occurs because there is no token manager on Polygon with the tokenId you are using. You don’t need to deploy a remote token manager for Polygon because there is already one available on Fantom. Therefore, we deploy that token manager from the Fantom testnet.

in the previous step I created a token manager (on Arbitrum). what the above seems to indicate is that we'll deploy that contract to Polygon. but to do so it would need to know the address of the contract, and this isn't passed to the deployTokenManager method (instead, it gets a "salt" -- is this supposed to be the same salt that was used to deploy the token manager?)

ekkis commented 1 month ago

by the way, Fantom is no more. it's now called Sonic. the guide should be rewritten for some other platform

Olanetsoft commented 1 month ago

Thanks for all this valuable feedback, @ekkis. That's quite in-depth, and we appreciate your help flagging this thing. I have a few things I want to call to your attention while I respond to other messages for clarification.

  1. Yes, using Polygon AMoy pointing to this RPC (https://rpc-amoy.polygon.technology) should work.

  2. That raises another point: in the code provided in the guide, "Polygon" is used. Shouldn't this be "polygon" to match what I have in the hardhat config? Better yet, shouldn't it be EvmChain? POLYGON?

The chain name passed into the interchainTokenServiceContract.deployTokenManager function is correct as "Polygon" and not "polygon," you can take a look at the chain name list here for every chain as its case sensitive. This is not something picked from hardhat config like you mentioned.

  1. Also, I did try the string "polygon-sepolia," but this failed too

This shouldn't fail for gas estimation as i just tested myself and i got the gas estimation correctly. It would be great to push your script to github and share the repo or github gist.

  1. and... I just realised the GasToken is set to FTM but I'm deploying to Arbitrum (as Fantom is broken)... so this should be set to something else? p.s. I set that 3rd value to GasToken.ETH (Arbitrum uses ETH for gas), but it still fails with the same error

Yes, it should be set to ETH since that's the token on Arb sepolia. What do you mean if failed too? What failed? Gas estimation or deploying token manager? I just tried gas estimation for this step and it works fine see the code i used, similar to what we have in the docs below.

const {
    AxelarQueryAPI,
    Environment,
    EvmChain,
    GasToken,
} = require("@axelar-network/axelarjs-sdk");

const api = new AxelarQueryAPI({ environment: Environment.TESTNET });

async function gasEstimator() {
    const gas = await api.estimateGasFee(
        EvmChain.ARBITRUM_SEPOLIA,
        EvmChain.POLYGON,
        GasToken.ETH,
        700000,
        1.1
    );

    console.log(gas)
    return gas;
}

gasEstimator()

I got this value: 60723842558632 in wei, which shows that the gas estimator SDK works fine as expected.

  1. another interesting point... in https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#add-your-private-key-to-env-and-hardhatconfigjs you define polygon like this (your definition has spaces in the URL).

This would be updated even though it doesn't affect the RPC's working fine as expected. If you have auto format enabled on your IDE, that should be fixed automatically.

  1. it seems that DRPC is a key-based system so the url as stated would not likely work. it would need to be something like https://lb.drpc.org/ogrpc?network=polygon-amoy&dkey= so the better thing is to use the url I'm using. The docs should be fixed.

Oh yes, that should work, too. You can see a list of public RPCs here. Feel free to use any as you prefer, but what we have on the docs works fine (I just tested it again), and we can update it.

  1. by the way, this section: https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#run-the-custominterchaintokenjs-script-to-deploy-to-polygon contains code that references fantom, not polygon. this needs fixing:

This does not need any fix, as it is correct. We made a callout here stating why its correct and also why you need to call fantom and not polygon.

  1. one other note, the tutorial page is divided into 2 sections. the second section "On this page" won't scroll unless I scroll down the entire page. that's really annoying. They should both be scrollable so as to allow access to the shortcuts

This is noted. Thanks for flagging. I have created an issue here. We will fix it.

  1. also, perhaps you could clarify for me. Stephan said the parameters passed to the deployTokenManager should match those expected by the contract's constructor (it's not quite what he said, I'm paraphrasing)?

Thats not correct, what you have is correct.

  1. by the way, some guidance for deploying a contract using hardhat in this section would be very useful. it would make the guide complete and help those of us who've never done it. it took me a while to figure out how to: https://docs.axelar.dev/dev/send-tokens/interchain-tokens/developer-guides/link-custom-tokens-deployed-across-multiple-chains-into-interchain-tokens/#deploy-an-erc-20-token-on-the-fantom-and-polygon-testnets

Great catch. ERC20 token deployment is a default approach for most developers, but we will add a reference to an existing guide.

  1. also, the indentation for Deploy a token manager on Fantom (right before Add a main() function) is wrong. it should be one in. It's otherwise confusing

This is autogenerated from the content based on the headings, and as seen, this step is vital and needs to be called out.

  1. remotely-deploy-a-token-manager-on-the-polygon-testnet would best be called "Deploy a remote token manager on the Polygon testnet"

We will fix this.

  1. wouldn't it be better to do?

    "0x" + crypto.randomBytes(32).toString("hex")
    and what would happen if we don't change the salt?

    No, you can do that because you already deployed on the source change and are trying to deploy on the remote chain. Only the salt value, which is a unique generated value, must be used for both deployments. In the future, if you want to extend to another chain, you need to use the same salt. That's why we added a callout for you to save the salt value safely, as it would be required for remote deployment.

  2. I don't have a local chain (because I deployed to a preferred chain (Arbitrum since Fantom is broken)). so how is this supposed to be done?

The first chain you deployed to is what we are referring to local chain here so for example if you deploy to arbitrum then that's your "local" and the polygon is your remote chain.

  1. in the previous step I created a token manager (on Arbitrum). what the above seems to indicate is that we'll deploy that contract to Polygon. but to do so it would need to know the address of the contract, and this isn't passed to the deployTokenManager method (instead, it gets a "salt" -- is this supposed to be the same salt that was used to deploy the token manager?

Yes, the same salt value for all remote deployments.

  1. by the way, Fantom is no more. It's now called Sonic. The guide should be rewritten for some other platform

Thank you for the feedback. We are aware of this, but it hasn't completely sunsetted. The RPC still works fine, but we will update it anyway.

Let me know if you need additional help.