首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取错误:交换时出现错误“STF”UniswapV3失败

获取错误:交换时出现错误“STF”UniswapV3失败
EN

Stack Overflow用户
提问于 2022-11-24 12:25:48
回答 2查看 54关注 0票数 0

创建了一份合同--一份基本的合同,部署在公元前孟买。

相同的uni交换基本地址,只是有不同的地址。因为这是在公元前孟买,所以我创造了它的威玛。

然后,在批准所有的地址后,我得到这个错误,没有任何解释或选项,以了解它在哪里失败时,我试图单字。

代码语言:javascript
复制
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma abicoder v2;


import "hardhat/console.sol";

import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol';
import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';

contract SwapExamples {
    // For the scope of these swap examples,
    // we will detail the design considerations when using
    // `exactInput`, `exactInputSingle`, `exactOutput`, and  `exactOutputSingle`.

    // It should be noted that for the sake of these examples, we purposefully pass in the swap router instead of inherit the swap router for simplicity.
    // More advanced example contracts will detail how to inherit the swap router safely.

    ISwapRouter public immutable swapRouter;


    address public constant WMATIC = 0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889;
    address public constant WETH = 0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa;

    // For this example, we will set the pool fee to 0.3%.
    uint24 public constant poolFee = 3000;

    constructor(ISwapRouter _swapRouter) {
        swapRouter = _swapRouter;
    }

    /// @notice swapExactInputSingle swaps a fixed amount of WMATIC for a maximum possible amount of WETH
    /// using the WMATIC/WETH 0.3% pool by calling `exactInputSingle` in the swap router.
    /// @dev The calling address must approve this contract to spend at least `amountIn` worth of its WMATIC for this function to succeed.
    /// @param amountIn The exact amount of WMATIC that will be swapped for WETH.
    /// @return amountOut The amount of WETH received.

    function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) {
        // msg.sender must approve this contract

        // Transfer the specified amount of WMATIC to this contract.
        TransferHelper.safeTransferFrom(WMATIC, msg.sender, address(this), amountIn);

        // Approve the router to spend WMATIC.
        TransferHelper.safeApprove(WMATIC, address(swapRouter), amountIn);

        // Naively set amountOutMinimum to 0. In production, use an oracle or other data source to choose a safer value for amountOutMinimum.
        // We also set the sqrtPriceLimitx96 to be 0 to ensure we swap our exact input amount.
        ISwapRouter.ExactInputSingleParams memory params =
            ISwapRouter.ExactInputSingleParams({
                tokenIn: WMATIC,
                tokenOut: WETH,
                fee: poolFee,
                recipient: msg.sender,
                deadline: block.timestamp,
                amountIn: amountIn,
                amountOutMinimum: 0,
                sqrtPriceLimitX96: 0
            });

        // The call to `exactInputSingle` executes the swap.
        amountOut = swapRouter.exactInputSingle(params);
    }

    /// @notice swapExactOutputSingle swaps a minimum possible amount of WMATIC for a fixed amount of WETH.
    /// @dev The calling address must approve this contract to spend its WMATIC for this function to succeed. As the amount of input WMATIC is variable,
    /// the calling address will need to approve for a slightly higher amount, anticipating some variance.
    /// @param amountOut The exact amount of WETH to receive from the swap.
    /// @param amountInMaximum The amount of WMATIC we are willing to spend to receive the specified amount of WETH.
    /// @return amountIn The amount of WMATIC actually spent in the swap.
    function swapExactOutputSingle(uint256 amountOut, uint256 amountInMaximum) external returns (uint256 amountIn) {
        // Transfer the specified amount of WMATIC to this contract.
        TransferHelper.safeTransferFrom(WMATIC, msg.sender, address(this), amountInMaximum);

        // Approve the router to spend the specifed `amountInMaximum` of WMATIC.
        // In production, you should choose the maximum amount to spend based on oracles or other data sources to acheive a better swap.
        TransferHelper.safeApprove(WMATIC, address(swapRouter), amountInMaximum);

        ISwapRouter.ExactOutputSingleParams memory params =
            ISwapRouter.ExactOutputSingleParams({
                tokenIn: WMATIC,
                tokenOut: WETH,
                fee: poolFee,
                recipient: msg.sender,
                deadline: block.timestamp,
                amountOut: amountOut,
                amountInMaximum: amountInMaximum,
                sqrtPriceLimitX96: 0
            });

        // Executes the swap returning the amountIn needed to spend to receive the desired amountOut.
        amountIn = swapRouter.exactOutputSingle(params);

        // For exact output swaps, the amountInMaximum may not have all been spent.
        // If the actual amount spent (amountIn) is less than the specified maximum amount, we must refund the msg.sender and approve the swapRouter to spend 0.
        if (amountIn < amountInMaximum) {
            TransferHelper.safeApprove(WMATIC, address(swapRouter), 0);
            TransferHelper.safeTransfer(WMATIC, msg.sender, amountInMaximum - amountIn);
        }
    }
}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-25 22:31:02

两周后我就和你一样了。我还没有解决这个问题,但我有更多对你有用的数据:

我试图在孟买网络上进行https://app.uniswap.org交换,我发现孟买的SwapRouter地址可能是错的,或者不是官方uniswap网站上的主要地址(我的意思是:0xE5924A0A0A0Ece92De3Ede1F18E0157C05861564)。

我不知道他们是否在使用两个地址,但我尝试了两次,并且两次将0x68b3465833fb72A70ecDF485E04C7bD8665Fc45作为SwapRouter。如果你试图在网站上做一个交换,你可以检查它。

我的tx示例:https://mumbai.polygonscan.com/tx/0xa7e75b78ec8f5ae311d0252d0ad7412176ebe7f063df72a8f2c347543f8f2103

票数 1
EN

Stack Overflow用户

发布于 2022-11-30 21:03:02

好的,几天后我终于和exactInputSingle在孟买做了一个交换!这个测试用0.5W交换weth。我附上我的剧本:

TestSwap.sol

代码语言:javascript
复制
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma abicoder v2;
import '@uniswap/v3-core/contracts/libraries/LowGasSafeMath.sol';

import "./SwapRouter02lib/ISwapRouter02.sol";
import "./SwapRouter02lib/IV3SwapRouter.sol";
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';

contract TestSwap {
    using LowGasSafeMath for uint256;

    ISwapRouter02 public immutable uniswapRouter;

    constructor(address _uniswapRouter) {
        uniswapRouter = ISwapRouter02(_uniswapRouter);
    }

    function swapUniswap(
        address token0, 
        address token1, 
        uint256 amount, 
        uint256 fee 
    ) external returns (uint256 amountOut) {
        require(IERC20(token0).transferFrom(msg.sender, address(this), amount),"STF v2");
        require(IERC20(token0).approve(address(uniswapRouter), amount),"SA v2");

        uint256 amountMin = LowGasSafeMath.add(amount, fee);
        IV3SwapRouter.ExactInputSingleParams memory params = IV3SwapRouter.ExactInputSingleParams({
            tokenIn: token0,
            tokenOut: token1,
            fee: uint24(fee),
            recipient: msg.sender,
            amountIn: amount,
            amountOutMinimum: 0,
            sqrtPriceLimitX96: 0
        });

        (bool success, bytes memory amountBytes) = address(uniswapRouter).call(
            abi.encodeWithSelector(
                IV3SwapRouter.exactInputSingle.selector,
                params
            )
        );

        return bytesToUint(amountBytes);
    }

    function bytesToUint(bytes memory _bytes) internal pure returns (uint256 value) {
        assembly {
            value := mload(add(_bytes, 0x20))
        }
    }
}

deploy-test.js

代码语言:javascript
复制
const hre = require('hardhat');
const ethers = hre.ethers;
const { abi: abiERC20 } = require("../artifacts/contracts/IERC20.sol/IERC20.json");
const uniswapRouter = "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"; //ROUTER 02
const uniswapFactory = "0x1F98431c8aD98523631AE4a59f267346ea31F984"; //FACTORY

const wmatic = "0x9c3C9283D3e44854697Cd22D3Faa240Cfb032889"; //wmatic mumbai
const weth = "0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa"; //weth mumbai

const fee1 = 500;

const signerAddress = "0x1234567890123456789012345678901234567890";//this must be one of your address with wmatic tokens (I tested on mumbai)

async function main() {
    
    await hre.network.provider.request({
        method: 'hardhat_impersonateAccount',
        params: [signerAddress],
      });
      const signer = await ethers.provider.getSigner(signerAddress);

    var wmaticContract = new ethers.Contract(
        wmatic,
        abiERC20,
        signer
    );

    var wethContract = new ethers.Contract(
        weth,
        abiERC20,
        signer
    );

    const TestSwap = await ethers.getContractFactory("TestSwap");
    const testSwap = await TestSwap.deploy(
        uniswapRouter
    );
    await testSwap.deployed();

    console.log((await wmaticContract.balanceOf(signer._address)).toString());
    console.log((await wethContract.balanceOf(signer._address)).toString());

    console.log((await wmaticContract.balanceOf(testSwap.address)).toString());
    console.log((await wethContract.balanceOf(testSwap.address)).toString());

    const amountApprove = ethers.utils.parseEther('1'); 
    const amount = ethers.utils.parseEther('0.5');

    const GAS_PARAMS =  {
        gasLimit: "1250000",//exagerate amount of gas, must be adjusted
        gasPrice: ethers.utils.parseUnits('100','gwei').toString(),
    };
    const txApproveWMatic = await wmaticContract.connect(signer).approve(
        testSwap.address, 
        amountApprove, 
        GAS_PARAMS);
    await txApproveWMatic.wait();

    const tx = await testSwap.connect(signer).swapUniswap(
        wmatic,
        weth,
        amount,
        fee1, 
        GAS_PARAMS
    );

    console.log(tx);
    const txResponse = await tx.wait();
    console.log(txResponse);

    console.log((await wmaticContract.balanceOf(signer._address)).toString());
    console.log((await wethContract.balanceOf(signer._address)).toString());
    console.log((await wmaticContract.balanceOf(testSwap.address)).toString());
    console.log((await wethContract.balanceOf(testSwap.address)).toString());
}

main();

要运行它:

代码语言:javascript
复制
 $ npx hardhat run scripts/deploy-test.js
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74560767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档