我一直在开发智能合约,我正在尝试使用 Polygon 主网在 Uniswap 上执行交换,但我正在努力让它工作,
这是我正在使用的可靠性代码:
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.7.6;
pragma abicoder v2;
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
//import "https://github.com/Uniswap/v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";
//import "https://github.com/Uniswap/v3-periphery/blob/main/contracts/libraries/TransferHelper.sol";
import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';
//import "https://github.com/Uniswap/v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol";
contract FlashLoan {
address public constant LINK = 0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39;
address public constant USDC = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;
IERC20 public usdcToken = IERC20(USDC);
IERC20 public linkToken = IERC20(LINK);
IUniswapV2Router02 public quickswapRouter = IUniswapV2Router02(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff);
address public constant uniswapRouter = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
ISwapRouter public immutable routerUniswapInterficie = ISwapRouter(uniswapRouter);
uint24 public constant poolFee = 3000;
address payable owner;
constructor(){
owner = payable(msg.sender);
}
function firstSwap(uint256 amountIn) external returns (uint256 amountOut){
usdcToken.approve(uniswapRouter, amountIn); //aquest es uniswap!
ISwapRouter.ExactInputSingleParams memory params =
ISwapRouter.ExactInputSingleParams({
tokenIn: USDC,
tokenOut: LINK,
fee: poolFee,
recipient: address(this),//qui rep els tokens
deadline: block.timestamp,
amountIn: amountIn,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
// The call to `exactInputSingle` executes the swap.
return routerUniswapInterficie.exactInputSingle(params);
}
function getBalance(address _tokenAddress) external view returns (uint256) {
return IERC20(_tokenAddress).balanceOf(address(this));
}
function withdrawVell(address _tokenAddress) external onlyOwner {
IERC20 token = IERC20(_tokenAddress);
token.transfer(msg.sender, token.balanceOf(address(this)));
}
modifier onlyOwner() {
require(
msg.sender == owner,
"Only the contract owner can call this function"
);
_;
}
receive() external payable {}
}
我已经尝试过将这段代码重新混合,并将所有代币地址和路由器地址硬编码,并且它工作完美,我可以获取合约中可用的特定代币的余额,并且可以将其上的 USDC 交换为 LINK 和 im使用approve函数允许路由器使用我的USDC,但是当我尝试从我的javascript文件调用firstSwap()函数时,情况就出现了变化,这样我就可以通过调用脚本来执行交换。这是我尝试运行的 JavaScript 代码:
const { ethers, network } = require("hardhat");
const fs = require("fs");
require("dotenv").config();
let config,arb,owner,inTrade,balance;
config = require('./../config/polygon.json');
const contract = require("../artifacts/contracts/FlashLoan.sol/FlashLoan.json");
const infuraProvider = new ethers.providers.InfuraProvider("matic", process.env.PROJECT_ID);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY,infuraProvider);
const FlashLoanContract = new ethers.Contract(config.arbContract, contract.abi, signer);
const main = async() =>{
//await setup();
//await getBalance();
//await withdraw(baseToken);
await performFirstSwap();
}
/*
const getBalance = async () => {
balance= await arb.getBalance(config.bases[0].address);
console.log(`Balance is: ${balance}`);
}
const setup = async () => {
[owner] = await ethers.getSigners();
console.log(`Owner: ${owner.address}`);
const IArb = await ethers.getContractFactory('FlashLoan');
arb = await IArb.attach(config.arbContract);//aqui tinc el meu contracte
}
async function withdraw(baseTokenw){
try{
const provider = new ethers.providers.InfuraProvider("matic", process.env.PROJECT_ID);
const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
// Conecta el contrato con el signer
const connectedContract = FlashLoanContract.connect(signer);
const gasPrice = ethers.utils.parseUnits("100", "gwei");
// Llama a la función firstSwap
const tx = await connectedContract.withdrawVell(baseTokenw, {gasLimit: 150000, gasPrice});
await tx.wait();
}
catch(error){
console.log(error);
}
}*/
async function performFirstSwap() {
console.log("Starting the swap");
try {
const gasPrice = ethers.utils.parseUnits("100", "gwei");
const tx = await FlashLoanContract.firstSwap(400000, {gasLimit: 150000, gasPrice});
await tx.wait();
console.log("Swap transaction successful:");
} catch (error) {
console.error("Error in the transaction:", error);
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
我已经尝试过所有的功能,它们都像一个魅力一样工作,(取款和 getBalance)所以我知道正确的合约已连接,但是当我尝试使用firstSwap 调用时它失败并给出以下错误:
Error in the transaction: Error: transaction failed [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (transactionHash="0xc5f2e8393d04a254d243330f869bde0c054ef736994cd49382b62ed13d8a3995", transaction={"type":2,"chainId":137,"nonce":135,"maxPriorityFeePerGas":{"type":"BigNumber","hex":"0x174876e800"},"maxFeePerGas":{"type":"BigNumber","hex":"0x174876e800"},"gasPrice":null,"gasLimit":{"type":"BigNumber","hex":"0x0249f0"},"to":"0x7A292CEF5D1b0c55177427719602027afAeBfE04","value":{"type":"BigNumber","hex":"0x00"},"data":"0xfc57fea80000000000000000000000000000000000000000000000000000000000061a80","accessList":[],"hash":"0xc5f2e8393d04a254d243330f869bde0c054ef736994cd49382b62ed13d8a3995","v":1,"r":"0xcca4b3d0a68acc7fda29acc589df48522c71aaad499cd08c433817586c35aace","s":"0x328cbcda1a9676709627e43898faa58170cc738c9340c87120b380ff302097a0","from":"0x223c02bf20B580f234dE37745d1C7a81AC2E5D84","confirmations":0}, receipt={"to":"0x7A292CEF5D1b0c55177427719602027afAeBfE04","from":"0x223c02bf20B580f234dE37745d1C7a81AC2E5D84","contractAddress":null,"transactionIndex":44,"gasUsed":{"type":"BigNumber","hex":"0x023ff9"},"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000002000000000000000000100000080000000000000000000004000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000020000000004000000000000000000001000000000000000000000000000000100000000000000000000000800000000000000000000000080000000000000000000000100000","blockHash":"0x48aa29ee072ff33f9f4b8fb5b40ca889354cfa4420fa939b1b3193ee048b5a1f","transactionHash":"0xc5f2e8393d04a254d243330f869bde0c054ef736994cd49382b62ed13d8a3995","logs":[{"transactionIndex":44,"blockNumber":47188057,"transactionHash":"0xc5f2e8393d04a254d243330f869bde0c054ef736994cd49382b62ed13d8a3995","address":"0x0000000000000000000000000000000000001010","topics":["0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63","0x0000000000000000000000000000000000000000000000000000000000001010","0x000000000000000000000000223c02bf20b580f234de37745d1c7a81ac2e5d84","0x000000000000000000000000eedba2484aaf940f37cd3cd21a5d7c4a7dafbfc0"],"data":"0x0000000000000000000000000000000000000000000000000000330f0aa31b5a00000000000000000000000000000000000000000000000064dd45e1e93d59ba000000000000000000000000000000000000000000009a5ec15ac7b2c066dee600000000000000000000000000000000000000000000000064dd12d2de9a3e60000000000000000000000000000000000000000000009a5ec15afac1cb09fa40","logIndex":2251,"blockHash":"0x48aa29ee072ff33f9f4b8fb5b40ca889354cfa4420fa939b1b3193ee048b5a1f"}],"blockNumber":47188057,"confirmations":1,"cumulativeGasUsed":{"type":"BigNumber","hex":"0x01941cab"},"effectiveGasPrice":{"type":"BigNumber","hex":"0x174876e800"},"status":0,"type":2,"byzantium":true}, code=CALL_EXCEPTION, version=providers/5.7.2)
at Logger.makeError (/home/paucontracts/smart_contracts/hardhat_test/node_modules/@ethersproject/logger/src.ts/index.ts:269:28)
at Logger.throwError (/home/paucontracts/smart_contracts/hardhat_test/node_modules/@ethersproject/logger/src.ts/index.ts:281:20)
at InfuraProvider.<anonymous> (/home/paucontracts/smart_contracts/hardhat_test/node_modules/@ethersproject/providers/src.ts/base-provider.ts:1549:24)
at step (/home/paucontracts/smart_contracts/hardhat_test/node_modules/@ethersproject/providers/lib/base-provider.js:48:23)
at Object.next (/home/paucontracts/smart_contracts/hardhat_test/node_modules/@ethersproject/providers/lib/base-provider.js:29:53)
at fulfilled (/home/paucontracts/smart_contracts/hardhat_test/node_modules/@ethersproject/providers/lib/base-provider.js:20:58) {
reason: 'transaction failed',
code: 'CALL_EXCEPTION',
transactionHash: '0xc5f2e8393d04a254d243330f869bde0c054ef736994cd49382b62ed13d8a3995',
transaction: {
type: 2,
chainId: 137,
nonce: 135,
maxPriorityFeePerGas: BigNumber { value: "100000000000" },
maxFeePerGas: BigNumber { value: "100000000000" },
gasPrice: null,
gasLimit: BigNumber { value: "150000" },
to: '0x7A292CEF5D1b0c55177427719602027afAeBfE04',
value: BigNumber { value: "0" },
data: '0xfc57fea80000000000000000000000000000000000000000000000000000000000061a80',
accessList: [],
hash: '0xc5f2e8393d04a254d243330f869bde0c054ef736994cd49382b62ed13d8a3995',
v: 1,
r: '0xcca4b3d0a68acc7fda29acc589df48522c71aaad499cd08c433817586c35aace',
s: '0x328cbcda1a9676709627e43898faa58170cc738c9340c87120b380ff302097a0',
from: '0x223c02bf20B580f234dE37745d1C7a81AC2E5D84',
confirmations: 0,
wait: [Function (anonymous)]
},
receipt: {
to: '0x7A292CEF5D1b0c55177427719602027afAeBfE04',
from: '0x223c02bf20B580f234dE37745d1C7a81AC2E5D84',
contractAddress: null,
transactionIndex: 44,
gasUsed: BigNumber { value: "147449" },
logsBloom: '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000002000000000000000000100000080000000000000000000004000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000020000000004000000000000000000001000000000000000000000000000000100000000000000000000000800000000000000000000000080000000000000000000000100000',
blockHash: '0x48aa29ee072ff33f9f4b8fb5b40ca889354cfa4420fa939b1b3193ee048b5a1f',
transactionHash: '0xc5f2e8393d04a254d243330f869bde0c054ef736994cd49382b62ed13d8a3995',
logs: [ [Object] ],
blockNumber: 47188057,
confirmations: 1,
cumulativeGasUsed: BigNumber { value: "26483883" },
effectiveGasPrice: BigNumber { value: "100000000000" },
status: 0,
type: 2,
byzantium: true
}
}
我猜问题出在我授予合约使用我的 USDC 的权限,但不明白有什么问题,因为在 Remix 中效果很好。
我查过了:
const Quant = ethers.utils.parseEther("10");
// Uni = new ethers.Contract("0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", addresses.univ2abi, provider);
// console.log(await Uni);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [addresses.WMATIC_WHALE],
});
const signer = ethers.provider.getSigner(addresses.WMATIC_WHALE);
const amountIn = ethers.utils.parseUnits("25", 18);
await DAI
.connect(signer)
.transfer(Flashloan.address, amountIn);
await WMATIC
.connect(signer)
.transfer(Flashloan.address, amountIn);
const tx = await Flashloan.executeFlashLoan([
addresses.erc20Address.DAI], [Quant],
"0x");
await tx.wait();
看看我的代码,尝试使用以太币到 bigNumbers 或某些库。 也许可以帮助你