未能在 pancakeswap 中添加流動性
我正在嘗試使用作為 PANCAKESWAP 複製的 solidity 和 truffle 腳本在 binance 測試網上進行一些交易。我能夠成功編譯並執行一次腳本。當我嘗試在路由器和工廠的不同地址上再次執行此操作時,它給了我以下錯誤:
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)'
我的 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" // } }, }, };
當我嘗試使用 truffle 命令而不是腳本來做同樣的事情時,它給了我同樣的錯誤。松露命令是:
pool.addLiquidity("0x84D2A9d0D51fd578c76908603bfdd91417F54915","0x22E692b514690757Bc26DE1C01d4Fc7207d30f90",4000,4000,7000,7000,"0xe95745a8F4E3cDb1cF5bfFD4A94F0B249e99f489",Math.floor(Date.now() / 1000) + 60 * 10).then(function(r){console.log(r);});
我的流動性函式如下:我什至嘗試刪除斷言語句並用 if 替換它,但面臨同樣的錯誤。
// **** 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 }
我的deploypool.js文件:
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(); };
已驗證路由器地址 https://testnet.bscscan.com/address/0x73D58041eDdD468e016Cfbc13f3BDc4248cCD65D#code
驗證工廠地址 https://testnet.bscscan.com/address/0x81338c4e7a7f30297af1dd1dbf02fc1299b0ea12#code
上一個使用不同的工廠和路由器地址成功交易 https://testnet.bscscan.com/tx/0x9ca6e07ffcc0ab50c2f181783a14a17e850ad16dbd15c1590e4f2321cc9d44b5
好吧,在這個問題上花了幾天時間後,我才知道我只是在通過 testnet 進行多次部署之前更改了一次 init_hash。init_hash 每次都會更改,因此您必須每次將 init_hash 從 pancake pair 文件複製到 pancake 庫中。這樣做之後,我能夠使用我自己的路由器和工廠地址通過 bsc 測試網成功添加流動性。
您的部署腳本在以下位置失敗:
await router.addLiquidity(...)
在呼叫 addLiquidity() 時,當它到達:
(uint reserveA, uint reserveB) = PancakeLibrary.getReserves(factory, tokenA, tokenB);
反過來又失敗了:
(uint reserve0, uint reserve1,) = IPancakePair(pairFor(factory, tokenA, tokenB)).getReserves();
這裡 tokenA 和 tokenB 的 pairFor 的輸出是
0x78715162d94936c07d811a03e3e0411a4270bf6c
你的令牌對部署在0xb8c774F637C2B40d2a834Bb6c1EecD7c96166Cf9
._addLiquidity
如果它不存在(通過呼叫檢查getPair() == 0x000...0
),路由器的功能會創建對,如果對存在則呼叫getReserves()
它反過來呼叫pairFor()
。如果您對 PancakePair 進行了更改,則 init_hash 可能會更改,並且pairFor()
find pair 計算的地址可能會有所不同。您可以嘗試刪除對工廠的 createPair 呼叫並在沒有它的情況下進行檢查。