0xPolygon / polygon-edge

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

RPC error [pancakeswap fork] #2029

Open nnlgsakib opened 10 months ago

nnlgsakib commented 10 months ago

I've deployed a Pancakeswap fork on my Polygon-based blockchain today. Everything seems to be working well, but I'm encountering an issue when attempting to add liquidity.

Error logs found in my browser console

And unable to add liquidity

{ "code": -32603, "message": "Internal JSON-RPC error.", "data": { "code": -32603, "message": "unable to apply transaction even for the highest gas limit 5000000000: execution reverted" }, "stack": "{\n \"code\": -32603,\n \"message\": \"Internal JSON-RPC error.\",\n \"data\": {\n \"code\": -32603,\n \"message\": \"unable to apply transaction even for the highest gas limit 5000000000: execution reverted\"\n },\n \"stack\": \"Error: Internal JSON-RPC error.\n
}

Stefan-Ethernal commented 10 months ago

Can you share with us the following information:

nnlgsakib commented 10 months ago

Can you share with us the following information:

  • which software version are you running at?
  • which consensus protocol are you executing (IBFT or PolyBFT)?
  • how does it look the transaction which you are sending? Are you invoking some smart contract and if yes, can you provide source code and point out which function you are invoking and which parameter values are provided?
  • can you provide the genesis.json file?

Consensus:ibft{pos} Genesis: https://raw.githubusercontent.com/Mind-chain/setpos/main/genesis.json

version 1.3.1[latest]

Please check this And I'll share the Pancake fork sources later

nnlgsakib commented 10 months ago

Can you share with us the following information:

  • which software version are you running at?
  • which consensus protocol are you executing (IBFT or PolyBFT)?
  • how does it look the transaction which you are sending? Are you invoking some smart contract and if yes, can you provide source code and point out which function you are invoking and which parameter values are provided?
  • can you provide the genesis.json file?

Are you there! Please help me

goran-ethernal commented 10 months ago

What are you setting for Gas on that transaction?

Also, answer to this would be useful:

how does it look the transaction which you are sending? Are you invoking some smart contract and if yes, can you provide source code and point out which function you are invoking and which parameter values are provided?

akegaviar commented 8 months ago

@nnlgsakib curious if you were able to resolve this or have any insights? I might have a similar issue here.

nnlgsakib commented 8 months ago

@nnlgsakib curious if you were able to resolve this or have any insights? I might have a similar issue here.

No sir.I have been unsuccessful in solving this

nnlgsakib commented 8 months ago

@nnlgsakib curious if you were able to resolve this or have any insights? I might have a similar issue here.

Did you get any solution?

akegaviar commented 8 months ago

hey @nnlgsakib

So I was working on a different set of contracts (not a dex like Pancake/Uniswap etc) to make them work on Polygon Edge, but I'm pretty sure the mechanism is the same. I managed to make it work.

Shooting a bit in the dark here as I don't have all the info on your setup, but it does really look like a very similar issue.

Background

Polygon Edge has ACL contracts that have allow lists of addresses that can deploy contracts on the network.

Since you deployed the contracts, your address is on the list. What you might be missing though is this: when you do an add liquidity for the first time for a pair that doesn't exist yet, the factory contract needs to deploy a liquidity pair contract.

And since the factory contract address is not on the contractDeployerAllowList > enabledAddresses list in the network genesis file, it's not allowed to do the deployment and you get the error.

So what you need to do is after you deploy your set of contracts, add the factory contract (or whatever contract that does the deployment when you call it) to the list of addresses allowed to do the deployments.

Actually doing this is a bit of a quest, so documenting it here for you & others just in case.

ACL addresses

ACLs are actually precompiled contracts on the network and you work with them in the same way as you do with normal contracts—by making transactions.

There are three main ACLs: Contract Deployer ACL, Transactions ACL, Bridge ACL.

Here's the precompiled addresses:

So, to add a factory contract address to the Contracts Deployer ACL, you need to make a transaction from your Admin address (listed in genesis in contractDeployerAllowList > adminAddresses) to 0x0200000000000000000000000000000000000000.

Checking if an address is enabled

You need to make an eth_call (basically a read call) to readAddressList(address) to check if an address is on the list.

Here's how you construct this. Get the function signature for readAddressList(address) for example here https://web3tools.chainstacklabs.com/generate-solidity-functions-signature & then add the address padded to 32.

Here's an example for 0x3140eA9ff2F70182b454a1111b38917A069a067A:

curl --request POST \
     --url NODE_ENDPOINT \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "eth_call",
  "params": [
    {
      "to": "0x0200000000000000000000000000000000000000",
      "data": "0xd78bca690000000000000000000000003140eA9ff2F70182b454a1111b38917A069a067A"
    },
    "latest"
  ]
}
'

Adding an address

Adding an address is making a call to the Contracts Deployer ACL contract from an Admin address on that contract.

Here's an example with ethers.js 5.x:

const ethers = require('ethers');

async function main() {
    const provider = new ethers.providers.JsonRpcProvider('NODE_ENDPOINT');
    const privateKey = 'PRIVATE_KEY';
    const wallet = new ethers.Wallet(privateKey, provider);

    const contractAddress = '0x0200000000000000000000000000000000000000';
    const contractABI = [
        {
            "inputs": [
                {
                    "internalType": "address",
                    "name": "addr",
                    "type": "address"
                }
            ],
            "name": "setEnabled",
            "outputs": [],
            "stateMutability": "nonpayable",
            "type": "function"
        }
    ];

    const contract = new ethers.Contract(contractAddress, contractABI, wallet);

    const tx = await contract.setEnabled('0x3140eA9ff2F70182b454a1111b38917A069a067A');
    console.log('Transaction hash:', tx.hash);

    const receipt = await tx.wait();
    console.log('Transaction was mined in block', receipt.blockNumber);
}

main().catch(console.error);

You can use the approach to manage the other ACLs too.

Hope this helps!

nnlgsakib commented 8 months ago

hey @nnlgsakib

So I was working on a different set of contracts (not a dex like Pancake/Uniswap etc) to make them work on Polygon Edge, but I'm pretty sure the mechanism is the same. I managed to make it work.

Shooting a bit in the dark here as I don't have all the info on your setup, but it does really look like a very similar issue.

Background

Polygon Edge has ACL contracts that have allow lists of addresses that can deploy contracts on the network.

Since you deployed the contracts, your address is on the list. What you might be missing though is this: when you do an add liquidity for the first time for a pair that doesn't exist yet, the factory contract needs to deploy a liquidity pair contract.

And since the factory contract address is not on the contractDeployerAllowList > enabledAddresses list in the network genesis file, it's not allowed to do the deployment and you get the error.

So what you need to do is after you deploy your set of contracts, add the factory contract (or whatever contract that does the deployment when you call it) to the list of addresses allowed to do the deployments.

Actually doing this is a bit of a quest, so documenting it here for you & others just in case.

ACL addresses

ACLs are actually precompiled contracts on the network and you work with them in the same way as you do with normal contracts—by making transactions.

There are three main ACLs: Contract Deployer ACL, Transactions ACL, Bridge ACL.

Here's the precompiled addresses:

  • Contract Deployer ACL: 0x0200000000000000000000000000000000000000
  • Transactions ACL 0x0200000000000000000000000000000000000002
  • Bridge ACL: 0x0200000000000000000000000000000000000004

So, to add a factory contract address to the Contracts Deployer ACL, you need to make a transaction from your Admin address (listed in genesis in contractDeployerAllowList > adminAddresses) to 0x0200000000000000000000000000000000000000.

Checking if an address is enabled

You need to make an eth_call (basically a read call) to readAddressList(address) to check if an address is on the list.

Here's how you construct this. Get the function signature for readAddressList(address) for example here https://web3tools.chainstacklabs.com/generate-solidity-functions-signature & then add the address padded to 32.

Here's an example for 0x3140eA9ff2F70182b454a1111b38917A069a067A:

curl --request POST \
     --url NODE_ENDPOINT \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "eth_call",
  "params": [
    {
      "to": "0x0200000000000000000000000000000000000000",
      "data": "0xd78bca690000000000000000000000003140eA9ff2F70182b454a1111b38917A069a067A"
    },
    "latest"
  ]
}
'

Adding an address

Adding an address is making a call to the Contracts Deployer ACL contract from an Admin address on that contract.

Here's an example with ethers.js 5.x:

const ethers = require('ethers');

async function main() {
    const provider = new ethers.providers.JsonRpcProvider('NODE_ENDPOINT');
    const privateKey = 'PRIVATE_KEY';
    const wallet = new ethers.Wallet(privateKey, provider);

    const contractAddress = '0x0200000000000000000000000000000000000000';
    const contractABI = [
        {
            "inputs": [
                {
                    "internalType": "address",
                    "name": "addr",
                    "type": "address"
                }
            ],
            "name": "setEnabled",
            "outputs": [],
            "stateMutability": "nonpayable",
            "type": "function"
        }
    ];

    const contract = new ethers.Contract(contractAddress, contractABI, wallet);

    const tx = await contract.setEnabled('0x3140eA9ff2F70182b454a1111b38917A069a067A');
    console.log('Transaction hash:', tx.hash);

    const receipt = await tx.wait();
    console.log('Transaction was mined in block', receipt.blockNumber);
}

main().catch(console.error);
  • NODE_ENDPOINT — your node endpoint
  • PRIVATE_KEY — replace with the Admin private key for the address that's listed as an Admin in genesis for this specific ACL
  • 0x0200000000000000000000000000000000000000 — Contracts Deployer ACL contract address
  • contractABI — ABI for the Contracts Deployer ACL contract. I got it by compiling this Solidity code here
  • 0x3140eA9ff2F70182b454a1111b38917A069a067A — your factory contract address

You can use the approach to manage the other ACLs too.

Hope this helps!

i just made the transaction according your instruction

but still not working

Sir, I am using ibft

https://raw.githubusercontent.com/Mind-chain/setpos/main/genesis.json

this is my genesis.json

@Stefan-Ethernal @vcastellm please help me