I really need your guy's help as I'm stuck in this for a week. Actually, I'm implementing a swap function on pancakeswap, I'm following this documentation. I'm doing swapEthForExactTokens
but getting an error that I don't understand. I wrote the function...
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.11;
import "@theanthill/pancake-swap-periphery/contracts/interfaces/IPancakeRouter01.sol";
import "@theanthill/pancake-swap-periphery/contracts/interfaces/IERC20.sol";
contract Pancakeswap {
address internal constant PANCAKESWAP_ROUTER_ADDRESS = 0x10ED43C718714eb63d5aA57B78B54704E256024E;
address internal constant PANCAKE_FACTORY_ADDRESS = 0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73;
address internal constant BTCB = 0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c;
address private constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address private constant WBNB = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;
IPancakeRouter01 public pancakeswapRouter;
constructor() {
pancakeswapRouter = IPancakeRouter01(PANCAKESWAP_ROUTER_ADDRESS);
}
function getPath(address arg0, address arg1) public pure returns (address[] memory) {
address[] memory path = new address[](2);
path[0] = arg0;
path[1] = arg1;
return path;
}
function swappingETHForExactTokens(uint256 amountOut, address tokenOut) public payable returns (uint256[] memory) {
uint256 deadline = block.timestamp + 15;
uint256[] memory swappedAmounts = pancakeswapRouter.swapETHForExactTokens{
value: msg.value}(amountOut, getPath(WETH, tokenOut), address(this), deadline);
(bool success, ) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
return swappedAmounts;
}
}
When it comes to unit testing, I'm doing it with typescript like the following.
export function shouldBehaveLikePancakeswap(): void {
const AMOUNT_OUT = 10;
const AMOUNT_IN = 100;
const WHALE = process.env.WETH_WHALE;
const DAI = process.env.DAI;
const WBTC = process.env.WBTC;
const TOKEN_OUT = DAI;
const expectedSwapAmount = "557227237267357629";
let TestPancakeswap;
let pancakeswap;
let receiver: { address: any };
let other;
it("should swap eth for exact tokens", async function () {
[other, receiver] = await ethers.getSigners();
TestPancakeswap = await ethers.getContractFactory("Pancakeswap");
pancakeswap = await TestPancakeswap.deploy();
const amounts = await pancakeswap.swappingETHForExactTokens(AMOUNT_OUT, TOKEN_OUT, {value: expectedSwapAmount});
console.log(`amounts of token received ${amounts}`);
});
}
and in the last, calling shouldBehaveLikePancakeswap()
from the main testing file.
I'm running all this after forking mainnet on hardhat like below...
hardhat.config.ts
networks: {
develop: {
url: "http://127.0.0.1:8545",
timeout: 200000,
allowUnlimitedContractSize: true,
},
hardhat: {
forking: {
url: "https://eth-mainnet.alchemyapi.io/v2/$MY_ALCHEMY_ID",
blockNumber: 14389000,
},
accounts: {
mnemonic,
},
chainId: chainIds.hardhat,
},
and then, with command: yarn test --network hardhat
I'm running, and in return, getting this error...
1) Unit tests
Pancakeswap
should swap eth for exact tokens:
Error: Transaction reverted: function returned an unexpected amount of data
at Pancakeswap.getEstimatedEthForTokens (contracts/Pancakeswap.sol:36)
at Pancakeswap.swappingETHForExactTokens (contracts/Pancakeswap.sol:40)
at async HardhatNode._mineBlockWithPendingTxs (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:1772:23)
at async HardhatNode.mineBlock (node_modules/hardhat/src/internal/hardhat-network/provider/node.ts:466:16)
at async EthModule._sendTransactionAndReturnHash (node_modules/hardhat/src/internal/hardhat-network/provider/modules/eth.ts:1496:18)
at async HardhatNetworkProvider.request (node_modules/hardhat/src/internal/hardhat-network/provider/provider.ts:118:18)
at async EthersProviderWrapper.send (node_modules/@nomiclabs/hardhat-ethers/src/internal/ethers-provider-wrapper.ts:13:20)
The first two lines of error says, I'm getting the error in lines...
uint256[] memory swappedAmounts = pancakeswapRouter.swapETHForExactTokens{
value: ethAmountDeriveable}(amountOut, getPath(WETH, tokenOut), address(this), deadline);