Получение TransferHelper: ETH_TRANSFER_FAILED При взаимодействии с Uni V2 - функция платная
Решение странной проблемы с контрактом маршрутизатора Uniswap V2 (или, в частности, вспомогательной функцией safeTransferETH).
Я пытаюсь поменять местами токены, удерживаемые контрактом, на uniswap для Ether, используя функцию swapExactTokensForETH, предоставляемую маршрутизатором uniswap v2 (код функции присутствует в github uniswap в router1: https://github.com/Uniswap/v2-periphery /blob/master/contracts/UniswapV2Router01.sol ). Вызываемая функция выглядит следующим образом:
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
override
ensure(deadline)
returns (uint[] memory amounts)
{
require(path[path.length - 1] == WETH, 'UniswapV2Router: INVALID_PATH');
amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path);
require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');
TransferHelper.safeTransferFrom(path[0], msg.sender, UniswapV2Library.pairFor(factory, path[0], path[1]), amounts[0]);
_swap(amounts, path, address(this));
IWETH(WETH).withdraw(amounts[amounts.length - 1]);
TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
}
Единственная часть этого кода, которая выдает ошибку, - это
TransferHelper.safeTransferETH
функция, которая выглядит следующим образом:
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
}
Мой код выглядит следующим образом:
function uniV2ReceiveETH(address _token0, uint _amount0) public payable returns (uint[] memory amountsReceived) {
require(_amount0 > 0, "Must provide tokens if we want tokens in return!");
address[] memory path = new address[](2);
path[0] = _token0;
path[1] = WETH;
IERC20 token;
token = IERC20(_token0);
if (token.balanceOf(address(this)) > 0) {
_amount0 = token.balanceOf(address(this));
}
require(token.approve(address(uniV2Router), _amount0 + 10000), "approval failed");
// Swap logic
uint amountOutMin = UniswapV2Library.getAmountsOut(address(uniV2Factory), _amount0, path)[1];
amountsReceived = uniV2Router.swapExactTokensForETH(_amount0, 1, path, address(this), deadline);
uint endBalance = address(this).balance;
// Let everyone know we're done!
emit Swap(msg.sender, _amount0, endBalance);
}
Еще несколько примечаний:
1.) Контракт без проблем получает ETH с других адресов.2.) Я использую каску и разветвленную версию основной сети для тестирования.3.) Контракт также работает с другими функциями подкачки маршрутизатора Uniswap, включая SwapExactETHForTokens и SwapExactTokensForTokens.
Спасибо за уделенное время и удачного дня.
3 ответа
Я решил эту проблему, имея
payable
fallback
функцию, определив ее как:
fallback() external payable { }
внутри моего смарт-контракта.
Добавьте к своему договору.
receive() external payable {}
fallback() external payable {}
Я решил эту проблему, добавив платную функцию получения(), поскольку без этой функции контракт не сможет получать эфир:
get() внешняя кредиторская задолженность {}
«Если вы используете Solidity 0.6.0 или более позднюю версию, рекомендуется использовать функцию получения() для явной обработки простых передач Ether. Если вы работаете с более старой версией Solidity, вы можете использовать функцию Fallback() для обработки как передача эфира, так и вызов с данными».
резервная() внешняя кредиторская задолженность {}