0xPolygon / polygon-edge

A Framework for Building Ethereum-compatible Blockchain Networks
https://polygon.technology/solutions/polygon-edge/
Apache License 2.0
1.01k stars 533 forks source link

Failed to Extract Exit event during withdraw #1781

Open sahil3Vedi opened 1 year ago

sahil3Vedi commented 1 year ago

Failed to Extract Exit event during withdraw

Description

The following error is thrown when trying to withdraw an ERC20 token from the Supernet.

Your environment

Steps to reproduce

Stefan-Ethernal commented 1 year ago

From what I can see, the root token is deployed to Mumbai (https://mumbai.polygonscan.com/address/0xaadbc81dec3d3f27a23b9fc8d9f1f031034079e6), which means it is a root chain originated token.

The deposit command is correctly invoked, however, the withdraw command isn't. The wrong child-predicate address is provided. The bridge configuration, that is kept in the genesis.json contains root chain contract addresses. erc20ChildMintablePredicateAddress is used when we have child chain (namely Supernets) originated tokens, that we want to bridge (back) from a root chain to a Supernets. So for your use case, when bridging a root chain originated token from a root chain to a Supernets, you need to provide the address of ChildERC20Predicate, which is deployed to the Supernets. Its address is hardcoded and known in advance (namely ChildERC20Predicate is deployed on this address: 0x1004). Other predicate addresses that are deployed in the genesis on a Supernets (alongside already mentioned ChildERC20Predicate) are found here: https://github.com/0xPolygon/polygon-edge/blob/develop/contracts/system_addresses.go#L24-L40.

So the key takeaway should be that mintable predicates are used when bridging Supernets-originated tokens and other predicates (without the mintable prefix) are used for bridging root-chain-originated tokens.

sahil3Vedi commented 1 year ago

Hi @Stefan-Ethernal,

I followed your recommendation and used this command to withdraw:

./polygon-edge bridge withdraw-erc20 --amounts 100000000000000000 --child-predicate 0x0000000000000000000000000000000000001004 --child-token 0x3EB10E0c47Cab33036199f5e20bc89C4B2Cca72B --json-rpc http://127.0.0.1:9545 --receivers 0xAE3ac03497aB6aFfF786bCFF95DD6e9095Dc5d55 --sender-key $PRIVATE_KEY

However, I receive the following error on doing so:

failed to send withdraw transaction (receiver: 0xAE3ac03497aB6aFfF786bCFF95DD6e9095Dc5d55, amount: 100000000000000000). error: failed to estimate gas: {"code":-32603,"message":"unable to apply transaction even for the highest gas limit 10000000: execution reverted: ChildERC20Predicate: NOT_CONTRACT"})

Kindly let me know which address needs to be funded / referenced in order to mitigate this error, Thanks!

Stefan-Ethernal commented 1 year ago

Hi @sahil3Vedi, apparently the wrong address for --child-token is provided and it is not a smart contract for some reason.

Is this JSON RPC URL of some of the Supernets validators http://127.0.0.1:9545?

Can you try the following, using foundry (https://book.getfoundry.sh/), invoke the following command to find out the child token address on the ChildERC20Predicate:

cast call 0x3EB10E0c47Cab33036199f5e20bc89C4B2Cca72B --rpc-url http://127.0.0.1:9545 "function rootTokenToChildToken(address)" 0xaADBC81Dec3D3f27a23b9fC8d9F1f031034079e6

Also query it on the RootERC20Predicate (erc20PredicateAddress from genesis.json) and make sure they are the same (you can provide me the output of both commands):

cast call <erc20PredicateAddress from genesis> --rpc-url <$MUMBAI_RPC> "function rootTokenToChildToken(address)" 0xaADBC81Dec3D3f27a23b9fC8d9F1f031034079e6

If those addresses are the same but differ from the one printed out with the deposit command, then provide it for the child-token address in withdraw command.

sahil3Vedi commented 1 year ago

Hi @Stefan-Ethernal

Output of the first command:

Error: 
(code: -32600, message: unable to execute call: not in allow list, data: None)

Output of the second command:

0x0000000000000000000000003eb10e0c47cab33036199f5e20bc89c4b2cca72b
Stefan-Ethernal commented 1 year ago

Hi @sahil3Vedi,

Error: 
(code: -32600, message: unable to execute call: not in allow list, data: None)

this error gives a bit more context and a new perspective. Apparently, it seems that you are using access lists, but account is not allowlisted.

In rough outline, you should execute the following command, but update it to suit to your particular parameters. What it does is that it allow lists account for bridge transactions.

cast send --private-key <bridge allow list admin private key> --rpc-url http://127.0.0.1:9545 --legacy \
0x0200000000000000000000000000000000000004 "function setEnabled(address)" <address of the account that sends bridge withdraw transactions>

If this fails for some reason, then please provide a genesis.json to figure out is there an alternative approach.

sahil3Vedi commented 1 year ago

Hi @Stefan-Ethernal , it fails with the following message:

Error: 
(code: -32603, message: cannot remove admin role from caller, data: None)

I should mention that the bridge allow list admin and the address sending the bridge withdraw transactions are the same account.

I'm attaching the genesis.json inside a zip. genesis.zip

Stefan-Ethernal commented 1 year ago

Can you double check that you haven't provided address of admin account as a parameter to setEnabled (0xAE3ac03497aB6aFfF786bCFF95DD6e9095Dc5d55)?

cast send --private-key <bridge allow list admin private key> --rpc-url http://127.0.0.1:9545 --legacy \
0x0200000000000000000000000000000000000004 "function setEnabled(address)" 0xAE3ac03497aB6aFfF786bCFF95DD6e9095Dc5d55

Are you enable to try the whole thing from the scratch using bridge allow list admin private key? It should be allowed to do both deposits and withdrawals. Or if you have already done that, can you try with another account, but first enable it in the bridge allow list, by executing cast send transaction from the above?

Other than the account that is performing withdrawal not in the access list somehow, everything else seems correct to me.

sahil3Vedi commented 1 year ago

Hi @Stefan-Ethernal,

Wanted to share something interesting with you. DUring genesis instead of using allowlists I now use blocklists. After despositing I get the same message. However, the output of this command:

cast call 0x3EB10E0c47Cab33036199f5e20bc89C4B2Cca72B --rpc-url http://127.0.0.1:9545 "function rootTokenToChildToken(address)" 0xaADBC81Dec3D3f27a23b9fC8d9F1f031034079e6

Is this:

0x

Does this provide us with some insight for the issue?

sankalpZeeve commented 1 year ago

Hi, I'm facing the same issue, following everything as mentioned in the thread. We are trying to deposit tokens from the rootchain, and mint then successfully as native currency within the supernet. The deposit transaction didn't really increase the balance on supernet though. While doing withdrawl we are facing similar issue.

Current seeing the out of 0x as described above. We're not even using allow lists for transactors or bridge ACLs.

deepalt92 commented 1 year ago

Hi, Has anyone been able to solve this issue? I had a similar issue. I have setup a Polygon Supernet on my local. However, withdraws and deposits between the supernet and the demo Geth (used in the setup documentation) do not seem to work. Below are the steps I followed: 1) Deploy the Supernet and the Rootchain and pre-mine some MATIC to my MetaMask wallet 2) Use the MATIC on my MetaMask to deploy my custom ERC20 token and mint some coins. Let's say my token name is "X" 3) Use the following command to withdraw tokens from the Supernet to the Rootchain (taken from your docs):

./polygon-edge bridge withdraw-erc20 --sender-key <private-key-of-Metamask-that-hold-X-tokens> --receivers <receiving-Metamask-address> --amounts 1 --child-predicate <ERC20-predicate-contract-address-in-the-genesis.json> --child-token <the-custom-token-address-I-deployed-on-the-Supernet> --json-rpc <localhost:port_supernet_validator>

The problem: On the console I get the following error - "failed to extract exit event: failed to find exit event log" Trying to deposit tokens from the Rootchain to the Supernet using the "./polygon-edge bridge deposit" command also seem to not work. Any help is hugely appreciated. Also some clarity on what predicate contract address should be given when we have deployed our own ERC20 token on the Supernet would be helpful.