Doubt in uniswap swap function

I am currently working on a project involving token swapping. swap doesn’t working . Is there any mistake in my code ? I am using Ethereum sepolia test net. but the swap not woring and giving an error that transation failed. Please help if any one knows.

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.20;
pragma abicoder v2;

import “https://github.com/Uniswap/v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol”;

interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
}

contract SingleSwap {
address public constant routerAddress = 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E;
ISwapRouter public immutable swapRouter = ISwapRouter(routerAddress);

address public constant LINK = 0x779877A7B0D9E8603169DdbD7836e478b4624789;
address public constant WETH = 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14;
address public constant USD = 0x6f14C02Fc1F78322cFd7d707aB90f18baD3B54f5;

IERC20 public WETHToken = IERC20(WETH);

uint24 public constant poolFee = 3000;

constructor() {}

function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) {

    WETHToken.approve(address(swapRouter), amountIn);

    ISwapRouter.ExactInputSingleParams memory params =
        ISwapRouter.ExactInputSingleParams({
            tokenIn: WETH,
            tokenOut: USD,
            fee: poolFee,
            recipient: address(this),
            deadline: block.timestamp,
            amountIn: amountIn,
            amountOutMinimum: 0,
            sqrtPriceLimitX96: 0
        });

    amountOut = swapRouter.exactInputSingle(params);
}

function swapExactOutputSingle(uint256 amountOut, uint256 amountInMaximum) external returns (uint256 amountIn) {

    WETHToken.approve(address(swapRouter), amountInMaximum);

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

    amountIn = swapRouter.exactOutputSingle(params);

    if (amountIn < amountInMaximum) {
        WETHToken.approve(address(swapRouter), 0);
        WETHToken.transfer(address(this), amountInMaximum - amountIn);
    }
}

}

please help if you guys know.

1. Incorrect Import Statement

The import statement should use double quotes and refer to the correct URL without spaces. Also, it’s good practice to specify the branch or commit hash to ensure the contract’s version doesn’t change unexpectedly.

import "https://github.com/Uniswap/v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol";

2. Incorrect Contract Address

Ensure the addresses for the router, LINK, WETH, and USD tokens are correct on the Sepolia testnet. The addresses in your code need verification as they might not be valid on the Sepolia network.

3. Approving Tokens

In the swapExactOutputSingle function, you should transfer the excess tokens back to the caller, not to the contract itself. Also, ensure you’re handling the approval correctly.

4. Error Handling and Debugging

Add error handling and debug logs to help identify where the transaction might be failing.

5. Setting Up the Contract Correctly

Ensure that your contract is correctly deployed and that the addresses you are using are for tokens and the router that actually exist on the Sepolia testnet.

Here’s a revised version of your contract with some improvements:

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.20;
pragma abicoder v2;

import "https://github.com/Uniswap/v3-periphery/blob/main/contracts/interfaces/ISwapRouter.sol";

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function approve(address spender, uint256 amount) external returns (bool);
}

contract SingleSwap {
    address public constant routerAddress = 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E; // Verify this address
    ISwapRouter public immutable swapRouter = ISwapRouter(routerAddress);

    address public constant LINK = 0x779877A7B0D9E8603169DdbD7836e478b4624789; // Verify this address
    address public constant WETH = 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14; // Verify this address
    address public constant USD = 0x6f14C02Fc1F78322cFd7d707aB90f18baD3B54f5; // Verify this address

    IERC20 public WETHToken = IERC20(WETH);

    uint24 public constant poolFee = 3000;

    constructor() {}

    function swapExactInputSingle(uint256 amountIn) external returns (uint256 amountOut) {
        require(WETHToken.transferFrom(msg.sender, address(this), amountIn), "Transfer failed");
        WETHToken.approve(address(swapRouter), amountIn);

        ISwapRouter.ExactInputSingleParams memory params =
            ISwapRouter.ExactInputSingleParams({
                tokenIn: WETH,
                tokenOut: USD,
                fee: poolFee,
                recipient: msg.sender, // Changed to msg.sender to send tokens to the user
                deadline: block.timestamp,
                amountIn: amountIn,
                amountOutMinimum: 0,
                sqrtPriceLimitX96: 0
            });

        amountOut = swapRouter.exactInputSingle(params);
    }

    function swapExactOutputSingle(uint256 amountOut, uint256 amountInMaximum) external returns (uint256 amountIn) {
        require(WETHToken.transferFrom(msg.sender, address(this), amountInMaximum), "Transfer failed");
        WETHToken.approve(address(swapRouter), amountInMaximum);

        ISwapRouter.ExactOutputSingleParams memory params =
            ISwapRouter.ExactOutputSingleParams({
                tokenIn: WETH,
                tokenOut: USD,
                fee: poolFee,
                recipient: msg.sender, // Changed to msg.sender to send tokens to the user
                deadline: block.timestamp,
                amountOut: amountOut,
                amountInMaximum: amountInMaximum,
                sqrtPriceLimitX96: 0
            });

        amountIn = swapRouter.exactOutputSingle(params);

        if (amountIn < amountInMaximum) {
            WETHToken.approve(address(swapRouter), 0);
            WETHToken.transfer(msg.sender, amountInMaximum - amountIn); // Return excess to sender
        }
    }
}

Additional Steps: mysedgwick

  • Verify Contract Addresses: Ensure that the token addresses (LINK, WETH, USD) and the router address are correct on the Sepolia testnet.

  • Check Token Balances and Approvals: Ensure the contract has enough token balance and approvals to execute the swap.

  • Debugging: Add events and require statements to debug and understand where the failure might be occurring.

  • Test in Segments: Test smaller parts of your contract to ensure each segment works correctly.

By following these steps, you can better diagnose the issue and ensure your contract works as expected.