#solidity #remix #hardhat
Вопрос:
Я пытаюсь начать работу с Uniswap V3. В качестве примера я взял самый простой вариант использования: при X количестве ETH сделайте обмен на DAI. К сожалению, я не в состоянии заставить его работать.
Уже есть очень похожий вопрос (без ответа), но немного другой, так как код не похож на мой.
Я использую жесткую шляпу для раскручивания основной сети, а затем подключаю Remix к localhost:8545
npx hardhat node --fork https://mainnet.infura.io/v3/{MY_API_KEY}
Конфигурация жесткого диска внизу:
solidity: {
compilers: [
{
version: "0.8.7",
settings: {
optimizer: {
enabled: true,
runs: 1000,
}
}
}
]
}
Как вы можете заметить (полный контракт в самом низу), контракт предлагает 3 оплачиваемых функции:
function convertExactEthToDai() external payable;
function convertEthToExactDai(uint256 daiAmount) external payable;
function getEstimatedETHforDAI(uint daiAmount) external payable returns (uint256);
Все они терпят неудачу, даже оцениваются, что довольно просто и читается (почти). Нет никакой конкретной причины, поэтому я слеп. Когда я выполняю функцию из Remix, я просто получаю общую ошибку "Returned error: Error: Transaction reverted without a reason string"
.
Когда я смотрю на консоль hardhat, я вижу эту ошибку:
eth_sendTransaction
Contract call: <UnrecognizedContract>
Transaction: 0xe17fd5a07ca4a0d5a0f91525a77d21152c41f4dc2a9e59feaac4fec7452ba3a1
From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
To: 0xc351628eb244ec633d5f21fbd6621e1a683b1181
Value: 0 ETH
Gas used: 52351 of 3000000
Block #13238807: 0x7471674d8b76462230d687644e20970137640a7b2fe005c264a04c2af35d4985
Error: Transaction reverted without a reason string
at <UnrecognizedContract>.<unknown> (0xb27308f9f90d607463bb33ea1bebb41c27ce5ab6)
at <UnrecognizedContract>.<unknown> (0xc351628eb244ec633d5f21fbd6621e1a683b1181)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at HardhatNode._mineBlockWithPendingTxs (D:RepositoriesTheRockfacutherock.blockchain.gettingstartednode_moduleshardhatsrcinternalhardhat-networkprovidernode.ts:1582:23)
at HardhatNode.mineBlock (D:RepositoriesTheRockfacutherock.blockchain.gettingstartednode_moduleshardhatsrcinternalhardhat-networkprovidernode.ts:435:16)
at EthModule._sendTransactionAndReturnHash (D:RepositoriesTheRockfacutherock.blockchain.gettingstartednode_moduleshardhatsrcinternalhardhat-networkprovidermoduleseth.ts:1494:18)
at HardhatNetworkProvider._sendWithLogging (D:RepositoriesTheRockfacutherock.blockchain.gettingstartednode_moduleshardhatsrcinternalhardhat-networkproviderprovider.ts:129:22)
at HardhatNetworkProvider.request (D:RepositoriesTheRockfacutherock.blockchain.gettingstartednode_moduleshardhatsrcinternalhardhat-networkproviderprovider.ts:106:18)
Похоже, контракт недействителен, однако я могу в EtherScan установить квоту и маршрутизатор
Есть идеи? Я действительно ценю это.
Вот полный контракт
// SPDX-License-Identifier: UNLICENCED
pragma solidity ^0.8.0;
pragma abicoder v2;
import "https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol";
import "https://github.com/Uniswap/uniswap-v3-periphery/blob/main/contracts/interfaces/IQuoter.sol";
interface IUniswapRouter is ISwapRouter {
function refundETH() external payable;
}
contract Uniswap3 {
IUniswapRouter public constant uniswapRouter = IUniswapRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
IQuoter public constant quoter = IQuoter(0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6);
address private constant DAI = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
address private constant WETH9 = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
function convertExactEthToDai() external payable {
require(msg.value > 0, "Must pass non 0 ETH amount");
uint256 deadline = block.timestamp 15;
address tokenIn = WETH9;
address tokenOut = DAI;
uint24 fee = 3000;
address recipient = msg.sender;
uint256 amountIn = msg.value;
uint256 amountOutMinimum = 1;
uint160 sqrtPriceLimitX96 = 0;
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams(
tokenIn,
tokenOut,
fee,
recipient,
deadline,
amountIn,
amountOutMinimum,
sqrtPriceLimitX96
);
uniswapRouter.exactInputSingle{ value: msg.value }(params);
uniswapRouter.refundETH();
// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}
function convertEthToExactDai(uint256 daiAmount) external payable {
require(daiAmount > 0, "Must pass non 0 DAI amount");
require(msg.value > 0, "Must pass non 0 ETH amount");
uint256 deadline = block.timestamp 15; // using 'now' for convenience, for mainnet pass deadline from frontend!
address tokenIn = WETH9;
address tokenOut = DAI;
uint24 fee = 3000;
address recipient = msg.sender;
uint256 amountOut = daiAmount;
uint256 amountInMaximum = msg.value;
uint160 sqrtPriceLimitX96 = 0;
ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams(
tokenIn,
tokenOut,
fee,
recipient,
deadline,
amountOut,
amountInMaximum,
sqrtPriceLimitX96
);
uniswapRouter.exactOutputSingle{ value: msg.value }(params);
uniswapRouter.refundETH();
// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}
// do not used on-chain, gas inefficient!
function getEstimatedETHforDAI(uint daiAmount) external payable returns (uint256) {
address tokenIn = WETH9;
address tokenOut = DAI;
uint24 fee = 10000;
uint160 sqrtPriceLimitX96 = 0;
return quoter.quoteExactOutputSingle(
tokenIn,
tokenOut,
fee,
daiAmount,
sqrtPriceLimitX96
);
}
// important to receive ETH
receive() payable external {}
}
Комментарии:
1. Я тоже сталкиваюсь с той же проблемой… в моем случае методы, доступные только для чтения, работают, но
payable
методы продолжают отказывать без всякой причины.