I am trying to make a few transactions on binance test net using a script in solidity and truffle which is a clone of PANCAKESWAP. I was able to successfully compile and execute the script once. When I tried to do it again on different addresses for router and factory it gave me the following error:
StatusError: Transaction: 0xc94424b8c6037e75e0eaf5f21982e2f73f88e71e18e0e5e783c642d6210e686f exited with an error (status 0).
at module.exports (D:\Blockchain\pancake\createpool\scripts\deploypool.js:18:18)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
tx: '0xc94424b8c6037e75e0eaf5f21982e2f73f88e71e18e0e5e783c642d6210e686f',
receipt: {
blockHash: '0xc4bea040096811e809c18216d85fc82813b60db9545d4e1bf6ab7c4dd344fe87',
blockNumber: 8023495,
contractAddress: null,
cumulativeGasUsed: 699140,
from: '0xe95745a8f4e3cdb1cf5bffd4a94f0b249e99f489',
gasUsed: 29046,
logs: [],
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
status: false,
to: '0x7632ae832440032fb4ca93e56873a92a01b06e13',
transactionHash: '0xc94424b8c6037e75e0eaf5f21982e2f73f88e71e18e0e5e783c642d6210e686f',
transactionIndex: 2,
rawLogs: []
},
reason: undefined,
hijackedStack: 'StatusError: Transaction: 0xc94424b8c6037e75e0eaf5f21982e2f73f88e71e18e0e5e783c642d6210e686f exited with an error (status 0). \n' +
' Please check that the transaction:\n' +
' - satisfies all conditions set by Solidity `require` statements.\n' +
' - does not trigger a Solidity `revert` statement.\n' +
'\n' +
' at Object.receipt (C:\\Users\\DELL\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\packages\\contract\\lib\\handlers.js:124:1)\n' +
' at runMicrotasks (<anonymous>)\n' +
' at processTicksAndRejections (internal/process/task_queues.js:97:5)\n' +
' at Function.start (C:\\Users\\DELL\\AppData\\Roaming\\npm\\node_modules\\truffle\\build\\webpack:\\packages\\contract\\lib\\override.js:49:1)'
My truffle-config.js:
//SPDX-License-Identifier: MIT
require('dotenv').config();
var HDWalletProvider = require("truffle-hdwallet-provider");
const infuraKey = process.env.infuraKey;
const mnemonic = process.env.mnemonic;
module.exports = {
networks: {
// Useful for testing. The `development` name is special - truffle uses it by default
// if it's defined here and no other network is specified at the command line.
// You should run a client (like ganache-cli, geth or parity) in a separate terminal
// tab if you use this network and you must also set the `host`, `port` and `network_id`
// options below to some value.
//
development: {
host: "127.0.0.1", // Localhost (default: none)
port: 8545, // Standard Ethereum port (default: none)
network_id: "*", // Any network (default: none)
},
rinkeby: {
provider: function () {
return new HDWalletProvider(mnemonic, "https://rinkeby.infura.io/v3/" + infuraKey);
},
network_id: 4,
gas: 4500000,
gasPrice: 10000000000,
},
bscTestnet: {
provider: () => new HDWalletProvider(
mnemonic,
'https://data-seed-prebsc-1-s1.binance.org:8545'
),
from: '0xe95745a8F4E3cDb1cF5bfFD4A94F0B249e99f489',
network_id: 97,
gas: 4500000,
gasPrice: 10000000000,
skipDryRun: true
},
mainnet: {
provider: () => new HDWalletProvider(
mnemonic,
'https://bsc-dataseed.binance.org/'
),
network_id: 56,
gas: 4500000,
gasPrice: 10000000000,
skipDryRun: true
}
},
mocha: {
// timeout: 100000
},
// Configure your compilers
compilers: {
solc: {
version: "0.8.0", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
// optimizer: {
// enabled: false,
// runs: 200
// },
// evmVersion: "byzantium"
// }
},
},
};
When i tried to do the same using a truffle command instead of the script it gave me the same error. The truffle command was:
pool.addLiquidity("0x84D2A9d0D51fd578c76908603bfdd91417F54915","0x22E692b514690757Bc26DE1C01d4Fc7207d30f90",4000,4000,7000,7000,"0xe95745a8F4E3cDb1cF5bfFD4A94F0B249e99f489",Math.floor(Date.now() / 1000) + 60 * 10).then(function(r){console.log(r);});
My liquidity functions are below:
I have even tried remove the assert statement and replacing it with an if but face the same error.
// **** ADD LIQUIDITY ****
function _addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin
) private returns (uint amountA, uint amountB) {
// create the pair if it doesn't exist yet
if (INiftFactory(factory).getPair(tokenA, tokenB) == address(0)) {
INiftFactory(factory).createPair(tokenA, tokenB);
}
(uint reserveA, uint reserveB) = NiftLibrary.getReserves(factory, tokenA, tokenB);
if (reserveA == 0 && reserveB == 0) {
(amountA, amountB) = (amountADesired, amountBDesired);
} else {
uint amountBOptimal = NiftLibrary.quote(amountADesired, reserveA, reserveB);
if (amountBOptimal <= amountBDesired) {
require(amountBOptimal >= amountBMin, 'NiftRouter: INSUFFICIENT_B_AMOUNT');
(amountA, amountB) = (amountADesired, amountBOptimal);
} else {
uint amountAOptimal = NiftLibrary.quote(amountBDesired, reserveB, reserveA);
assert(amountAOptimal <= amountADesired);
require(amountAOptimal >= amountAMin, 'NiftRouter: INSUFFICIENT_A_AMOUNT');
(amountA, amountB) = (amountAOptimal, amountBDesired);
}
}
}
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
(amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
address pair = NiftLibrary.pairFor(factory, tokenA, tokenB);
TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
liquidity = INiftPair(pair).mint(to);
}
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
(amountToken, amountETH) = _addLiquidity(
token,
WETH,
amountTokenDesired,
msg.value,
amountTokenMin,
amountETHMin
);
address pair = NiftLibrary.pairFor(factory, token, WETH);
TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
IWETH(WETH).deposit{value: amountETH}();
assert(IWETH(WETH).transfer(pair, amountETH));
liquidity = INiftPair(pair).mint(to);
if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH); // refund dust eth, if any
}
My deploypool.js file:
const Factory = artifacts.require('Factory.sol');
const Router = artifacts.require('Router.sol');
const Pair = artifacts.require('Pair.sol');
const Token1 = artifacts.require('token1.sol');
const Token2 = artifacts.require('token2.sol');
module.exports = async done => {
try {
//const [admin, _] = await web3.eth.getAccounts();
const factory = await Factory.at('0x81338c4e7a7f30297aF1dd1dBF02Fc1299b0EA12');
const router = await Router.at('0x73D58041eDdD468e016Cfbc13f3BDc4248cCD65D');
const token1 = await Token1.new();
const token2 = await Token2.new();
const pairAddress = await factory.createPair.call(token1.address, token2.address);
const tx = await factory.createPair(token1.address, token2.address);
await token1.approve(router.address, 10000);
await token2.approve(router.address, 10000);
await router.addLiquidity(
token1.address,
token2.address,
9000,
9000,
10000,
10000,
'mymetamaskaddress',
Math.floor(Date.now() / 1000) + 60 * 10
);
const pair = await Pair.at(pairAddress);
const balance = await pair.balanceOf("0xe95745a8F4E3cDb1cF5bfFD4A94F0B249e99f489");
console.log(`balance LP: ${balance.toString()}`);
} catch (e) {
console.log(e);
}
done();
};
Address of verified router https://testnet.bscscan.com/address/0x73D58041eDdD468e016Cfbc13f3BDc4248cCD65D#code
Address of verified factory
https://testnet.bscscan.com/address/0x81338c4e7a7f30297af1dd1dbf02fc1299b0ea12#code
Previous Successful transaction with a different factory and router address
https://testnet.bscscan.com/tx/0x9ca6e07ffcc0ab50c2f181783a14a17e850ad16dbd15c1590e4f2321cc9d44b5
Best Answer
your deploy script fails at:
while making a call to addLiquidity(), when it reaches:
which in turn fails at:
here the output of pairFor for tokenA and tokenB is
0x78715162d94936c07d811a03e3e0411a4270bf6c
while your tokens pair is deployed at0xb8c774F637C2B40d2a834Bb6c1EecD7c96166Cf9
._addLiquidity
fucntion of router creates the pair if it doesn't exists (checks by callinggetPair() == 0x000...0
) and if pair exists then callsgetReserves()
which in turn callspairFor()
. If you have made changes to PancakePair then init_hash might change and address calculated bypairFor()
to find pair might be different. You can try removing createPair call to factory and check without it.