UniswapV3Swap

Description:

Decentralized Finance (DeFi) protocol contract providing Swap, Liquidity, Factory functionality.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/uniswapV2swapdemo.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.17;\r
\r
/**\r
 * @title UniswapV3SwapDemo\r
 * @notice Educational contract demonstrating Uniswap V3 swap functionality with SwapRouter02\r
 * @dev This contract shows both direct (single-hop) and multi-hop swaps using SwapRouter02\r
 * \r
 * SEPOLIA TESTNET ADDRESSES:\r
 * - Uniswap V3 SwapRouter02: 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E\r
 * - WETH: 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14\r
 * - USDC: 0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8\r
 * \r
 * HOW TO USE:\r
 * 1. Deploy with SwapRouter02 address: 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E\r
 * 2. Send tokens to contract (e.g., transfer WETH to contract address)\r
 * 3. Call swapDirect() or swapMultiHop() with appropriate parameters\r
 * 4. Use withdrawToken() to retrieve swapped tokens\r
 * \r
 * KEY DIFFERENCE FROM SWAPROUTER V1:\r
 * - SwapRouter02 does NOT include deadline in the params struct\r
 * - Deadline is handled by the router's multicall wrapper\r
 * - This provides more flexibility for complex transaction batching\r
 */\r
\r
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";\r
import {TransferHelper} from "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol";\r
\r
// SwapRouter02 interface (different from V1!)\r
interface IV3SwapRouter {\r
    struct ExactInputSingleParams {\r
        address tokenIn;\r
        address tokenOut;\r
        uint24 fee;\r
        address recipient;\r
        uint256 amountIn;\r
        uint256 amountOutMinimum;\r
        uint160 sqrtPriceLimitX96;\r
    }\r
\r
    struct ExactInputParams {\r
        bytes path;\r
        address recipient;\r
        uint256 amountIn;\r
        uint256 amountOutMinimum;\r
    }\r
\r
    function exactInputSingle(ExactInputSingleParams calldata params)\r
        external\r
        payable\r
        returns (uint256 amountOut);\r
\r
    function exactInput(ExactInputParams calldata params)\r
        external\r
        payable\r
        returns (uint256 amountOut);\r
}\r
\r
contract UniswapV3Swap {\r
    \r
    // ========== STATE VARIABLES ==========\r
    \r
    address public owner;\r
    IV3SwapRouter public immutable swapRouter;\r
    \r
    /**\r
     * @notice Uniswap V3 pool fee tiers (in hundredths of a basis point)\r
     * @dev Fee tiers determine which pool to use for swaps\r
     * \r
     * Common fee tiers:\r
     * - 500 (0.05%): Stablecoin pairs (USDC/DAI, USDT/USDC)\r
     * - 3000 (0.3%): Most standard pairs (ETH/USDC, WBTC/ETH)\r
     * - 10000 (1%): Exotic or low-liquidity pairs\r
     */\r
    uint24 public constant POOL_FEE_LOW = 500;      // 0.05% - for stablecoins\r
    uint24 public constant POOL_FEE_MEDIUM = 3000;  // 0.3% - most common\r
    uint24 public constant POOL_FEE_HIGH = 10000;   // 1% - exotic pairs\r
    \r
    \r
    // ========== EVENTS ==========\r
    \r
    /**\r
     * @notice Emitted when a direct swap completes successfully\r
     * @param tokenIn Address of input token\r
     * @param tokenOut Address of output token\r
     * @param amountIn Amount of input tokens swapped\r
     * @param amountOut Amount of output tokens received\r
     * @param poolFee Fee tier used for the swap\r
     */\r
    event DirectSwapExecuted(\r
        address indexed tokenIn,\r
        address indexed tokenOut,\r
        uint256 amountIn,\r
        uint256 amountOut,\r
        uint24 poolFee\r
    );\r
    \r
    /**\r
     * @notice Emitted when a multi-hop swap completes successfully\r
     * @param tokenIn Address of input token (first token in path)\r
     * @param tokenOut Address of output token (last token in path)\r
     * @param amountIn Amount of input tokens swapped\r
     * @param amountOut Amount of output tokens received\r
     * @param pathLength Length of the swap path in bytes\r
     */\r
    event MultiHopSwapExecuted(\r
        address indexed tokenIn,\r
        address indexed tokenOut,\r
        uint256 amountIn,\r
        uint256 amountOut,\r
        uint256 pathLength\r
    );\r
    \r
    /**\r
     * @notice Emitted when tokens are withdrawn from contract\r
     * @param token Address of token withdrawn\r
     * @param to Recipient address\r
     * @param amount Amount withdrawn\r
     */\r
    event TokensWithdrawn(\r
        address indexed token,\r
        address indexed to,\r
        uint256 amount\r
    );\r
    \r
    \r
    // ========== CONSTRUCTOR ==========\r
    \r
    /**\r
     * @notice Initialize the swap demo contract\r
     * @param _swapRouter Address of Uniswap V3 SwapRouter02\r
     * \r
     * FOR SEPOLIA: Use 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E (SwapRouter02)\r
     */\r
    constructor(address _swapRouter) {\r
        require(_swapRouter != address(0), "Invalid router address");\r
        owner = msg.sender;\r
        swapRouter = IV3SwapRouter(_swapRouter);\r
    }\r
    \r
    \r
    // ========== MODIFIERS ==========\r
    \r
    modifier onlyOwner() {\r
        require(msg.sender == owner, "Only owner can call this function");\r
        _;\r
    }\r
    \r
    \r
    // ========== MAIN SWAP FUNCTIONS ==========\r
    \r
    /**\r
     * @notice Execute a direct (single-hop) swap between two tokens\r
     * @dev Use this when a direct trading pair exists with good liquidity\r
     * \r
     * @param tokenIn Address of token to swap from (you must have this in contract)\r
     * @param tokenOut Address of token to receive\r
     * @param poolFee Fee tier of the pool to use (500, 3000, or 10000)\r
     * @param amountIn Amount of tokenIn to swap\r
     * @param amountOutMinimum Minimum amount of tokenOut to receive (slippage protection)\r
     * @return amountOut Actual amount of tokenOut received\r
     * \r
     * EXAMPLE USAGE (WETH → USDC on Sepolia):\r
     * - tokenIn: 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14 (WETH)\r
     * - tokenOut: 0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8 (USDC)\r
     * - poolFee: 3000 (0.3%)\r
     * - amountIn: 1000000000000000000 (1 WETH)\r
     * - amountOutMinimum: 0 (for testing; in production calculate expected output)\r
     * \r
     * HOW IT WORKS:\r
     * 1. Contract approves SwapRouter02 to spend tokenIn\r
     * 2. SwapRouter02 executes swap on Uniswap V3 pool\r
     * 3. tokenOut is sent directly to this contract\r
     * 4. Remaining tokenIn (if any) stays in contract\r
     * \r
     * KEY DIFFERENCE FROM SWAPROUTER V1:\r
     * SwapRouter02 doesn't require deadline in params. The router handles\r
     * deadline validation internally, making the interface cleaner.\r
     */\r
    function swapDirect(\r
        address tokenIn,\r
        address tokenOut,\r
        uint24 poolFee,\r
        uint256 amountIn,\r
        uint256 amountOutMinimum\r
    ) external onlyOwner returns (uint256 amountOut) {\r
        // Validate inputs\r
        require(tokenIn != address(0), "Invalid tokenIn address");\r
        require(tokenOut != address(0), "Invalid tokenOut address");\r
        require(amountIn > 0, "Amount must be greater than 0");\r
        \r
        // Check contract has enough tokens\r
        uint256 balance = IERC20(tokenIn).balanceOf(address(this));\r
        require(balance >= amountIn, "Insufficient token balance in contract");\r
        \r
        // Approve the router to spend tokenIn\r
        // TransferHelper is a safe way to approve tokens\r
        TransferHelper.safeApprove(tokenIn, address(swapRouter), amountIn);\r
        \r
        // Set up swap parameters for SwapRouter02\r
        // NOTE: No deadline in struct! SwapRouter02 handles deadline differently\r
        IV3SwapRouter.ExactInputSingleParams memory params = IV3SwapRouter\r
            .ExactInputSingleParams({\r
                tokenIn: tokenIn,              // Token we're selling\r
                tokenOut: tokenOut,            // Token we're buying\r
                fee: poolFee,                  // Pool fee tier\r
                recipient: address(this),      // Send output tokens to this contract\r
                amountIn: amountIn,            // Exact amount of tokenIn to swap\r
                amountOutMinimum: amountOutMinimum, // Minimum tokenOut to receive (slippage)\r
                sqrtPriceLimitX96: 0           // No price limit (accept any price)\r
            });\r
        \r
        // Execute the swap\r
        // SwapRouter02 uses payable function (for ETH swaps), pass 0 for ERC20 swaps\r
        amountOut = swapRouter.exactInputSingle(params);\r
        \r
        // Emit event with swap details\r
        emit DirectSwapExecuted(tokenIn, tokenOut, amountIn, amountOut, poolFee);\r
        \r
        return amountOut;\r
    }\r
    \r
    \r
    /**\r
     * @notice Execute a multi-hop swap through multiple pools\r
     * @dev Use this when no direct pair exists or when routing through intermediate tokens gives better rates\r
     * \r
     * @param tokenIn Address of initial token to swap from\r
     * @param tokenOut Address of final token to receive\r
     * @param path Encoded swap path (see encoding instructions below)\r
     * @param amountIn Amount of tokenIn to swap\r
     * @param amountOutMinimum Minimum amount of tokenOut to receive\r
     * @return amountOut Actual amount of tokenOut received\r
     * \r
     * PATH ENCODING:\r
     * The path is a tightly packed bytes array with format:\r
     * [tokenA (20 bytes)][fee (3 bytes)][tokenB (20 bytes)][fee (3 bytes)][tokenC (20 bytes)]\r
     * \r
     * Each token address is 20 bytes (40 hex characters)\r
     * Each fee is 3 bytes (6 hex characters)\r
     * \r
     * EXAMPLE 1: USDC → WETH → DAI\r
     * If swapping USDC to DAI through WETH:\r
     * - USDC address (20 bytes): 0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8\r
     * - Fee tier 0.05% (3 bytes): 0x0001f4 (500 in hex)\r
     * - WETH address (20 bytes): 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14\r
     * - Fee tier 0.3% (3 bytes): 0x000bb8 (3000 in hex)\r
     * - DAI address (20 bytes): 0x68194a729C2450ad26072b3D33ADaCbcef39D574\r
     * \r
     * Combined path (63 bytes):\r
     * 0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C80001f4fFf9976782d46CC05630D1f6eBAb18b2324d6B14000bb868194a729C2450ad26072b3D33ADaCbcef39D574\r
     * \r
     * EXAMPLE 2: Token A → Token B → Token C → Token D (3 swaps)\r
     * Path would be 83 bytes: A(20) + fee(3) + B(20) + fee(3) + C(20) + fee(3) + D(20)\r
     * \r
     * WHY USE MULTI-HOP?\r
     * - Direct pair doesn't exist (e.g., obscure token → another obscure token)\r
     * - Better price through routing (sometimes A→B→C is better than A→C direct)\r
     * - Higher liquidity through major pairs (route through WETH/USDC for better execution)\r
     * \r
     * TRADE-OFFS:\r
     * - Pro: Access any token pair, often better rates\r
     * - Con: Higher gas costs (each hop costs more gas)\r
     * - Con: More complex to set up\r
     */\r
    function swapMultiHop(\r
        address tokenIn,\r
        address tokenOut,\r
        bytes memory path,\r
        uint256 amountIn,\r
        uint256 amountOutMinimum\r
    ) external onlyOwner returns (uint256 amountOut) {\r
        // Validate inputs\r
        require(tokenIn != address(0), "Invalid tokenIn address");\r
        require(tokenOut != address(0), "Invalid tokenOut address");\r
        require(amountIn > 0, "Amount must be greater than 0");\r
        require(path.length >= 43, "Path too short (min: tokenA + fee + tokenB = 43 bytes)");\r
        \r
        // Check contract has enough tokens\r
        uint256 balance = IERC20(tokenIn).balanceOf(address(this));\r
        require(balance >= amountIn, "Insufficient token balance in contract");\r
        \r
        // Approve the router to spend tokenIn\r
        TransferHelper.safeApprove(tokenIn, address(swapRouter), amountIn);\r
        \r
        // Set up multi-hop swap parameters for SwapRouter02\r
        // NOTE: No deadline in struct! SwapRouter02 handles deadline differently\r
        IV3SwapRouter.ExactInputParams memory params = IV3SwapRouter\r
            .ExactInputParams({\r
                path: path,                    // Encoded path with tokens and fees\r
                recipient: address(this),      // Send final output to this contract\r
                amountIn: amountIn,            // Exact amount of first token to swap\r
                amountOutMinimum: amountOutMinimum // Minimum final token to receive\r
            });\r
        \r
        // Execute the multi-hop swap\r
        // SwapRouter02 uses payable function (for ETH swaps), pass 0 for ERC20 swaps\r
        amountOut = swapRouter.exactInput(params);\r
        \r
        // Emit event with swap details\r
        emit MultiHopSwapExecuted(tokenIn, tokenOut, amountIn, amountOut, path.length);\r
        \r
        return amountOut;\r
    }\r
    \r
    \r
    // ========== HELPER FUNCTIONS ==========\r
    \r
    /**\r
     * @notice Get the balance of any ERC20 token held by this contract\r
     * @param token Address of the token to check\r
     * @return balance Token balance of this contract\r
     * \r
     * USE THIS to check:\r
     * - How much tokenIn you have before swapping\r
     * - How much tokenOut you received after swapping\r
     */\r
    function getTokenBalance(address token) external view returns (uint256) {\r
        return IERC20(token).balanceOf(address(this));\r
    }\r
    \r
    /**\r
     * @notice Withdraw tokens from the contract\r
     * @param token Address of token to withdraw\r
     * @param amount Amount to withdraw (use 0 to withdraw all)\r
     * \r
     * IMPORTANT: Always withdraw your swapped tokens after testing!\r
     */\r
    function withdrawToken(address token, uint256 amount) external onlyOwner {\r
        if (amount == 0) {\r
            // Withdraw full balance if amount is 0\r
            amount = IERC20(token).balanceOf(address(this));\r
        }\r
        require(amount > 0, "No tokens to withdraw");\r
        \r
        // Safe transfer to owner\r
        TransferHelper.safeTransfer(token, owner, amount);\r
        \r
        emit TokensWithdrawn(token, owner, amount);\r
    }\r
    \r
    /**\r
     * @notice Withdraw ETH from the contract\r
     * @param amount Amount to withdraw (use 0 to withdraw all)\r
     */\r
    function withdrawETH(uint256 amount) external onlyOwner {\r
        if (amount == 0) {\r
            amount = address(this).balance;\r
        }\r
        require(amount > 0, "No ETH to withdraw");\r
        \r
        payable(owner).transfer(amount);\r
    }\r
    \r
    /**\r
     * @notice Allow contract to receive ETH\r
     * @dev Required to receive ETH from unwrapping WETH or direct transfers\r
     */\r
    receive() external payable {}\r
    \r
    \r
    // ========== VIEW FUNCTIONS ==========\r
    \r
    /**\r
     * @notice Get contract configuration details\r
     * @return _owner Owner address\r
     * @return _swapRouter SwapRouter address\r
     * @return contractBalance ETH balance of contract\r
     */\r
    function getContractInfo() external view returns (\r
        address _owner,\r
        address _swapRouter,\r
        uint256 contractBalance\r
    ) {\r
        return (\r
            owner,\r
            address(swapRouter),\r
            address(this).balance\r
        );\r
    }\r
}\r
\r
\r
/**\r
 * ============================================\r
 * STEP-BY-STEP USAGE GUIDE FOR REMIX\r
 * ============================================\r
 * \r
 * 1. COMPILE THE CONTRACT\r
 *    - Open Remix IDE (remix.ethereum.org)\r
 *    - Create new file: UniswapV3SwapDemo.sol\r
 *    - Paste this code\r
 *    - Compiler: Select 0.8.17 or higher\r
 *    - Click "Compile UniswapV3SwapDemo.sol"\r
 * \r
 * 2. DEPLOY TO SEPOLIA\r
 *    - Switch MetaMask to Sepolia network\r
 *    - In Remix Deploy tab, select "Injected Provider - MetaMask"\r
 *    - Constructor parameter _swapRouter: 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E\r
 *    - Click "Deploy"\r
 *    - Confirm transaction in MetaMask\r
 *    - Copy deployed contract address\r
 * \r
 * 3. FUND THE CONTRACT WITH TOKENS\r
 *    Option A - Use your WETH:\r
 *    - In MetaMask, send WETH to your deployed contract address\r
 *    - Send a small amount first (e.g., 0.01 WETH = 10000000000000000 wei)\r
 * \r
 *    Option B - Get test WETH from faucet or wrap ETH:\r
 *    - Use Sepolia faucet to get test ETH\r
 *    - Wrap ETH to WETH at 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14\r
 * \r
 * 4. CHECK TOKEN BALANCE\r
 *    - In Remix, expand your deployed contract\r
 *    - Call getTokenBalance with WETH address: 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14\r
 *    - Confirm you see your token balance\r
 * \r
 * 5. EXECUTE A DIRECT SWAP (WETH → USDC example)\r
 *    - Click swapDirect\r
 *    - tokenIn: 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14 (WETH)\r
 *    - tokenOut: 0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8 (USDC - verify this address!)\r
 *    - poolFee: 3000 (for 0.3%)\r
 *    - amountIn: 1000000000000000 (0.001 WETH)\r
 *    - amountOutMinimum: 0 (for testing only!)\r
 *    - Click "transact"\r
 *    - Confirm in MetaMask\r
 *    - Wait for transaction confirmation\r
 * \r
 * 6. CHECK OUTPUT BALANCE\r
 *    - Call getTokenBalance with USDC address: 0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8\r
 *    - You should see USDC balance increased\r
 * \r
 * 7. WITHDRAW YOUR TOKENS\r
 *    - Call withdrawToken\r
 *    - token: [address of token you want to withdraw]\r
 *    - amount: 0 (to withdraw all)\r
 *    - Tokens will be sent to your wallet (owner address)\r
 * \r
 * ============================================\r
 * TROUBLESHOOTING\r
 * ============================================\r
 * \r
 * ERROR: "Insufficient token balance in contract"\r
 * → You need to send tokens to the contract first (step 3)\r
 * \r
 * ERROR: "STF" (SafeTransfer Failed) during swap\r
 * → The pool for this token pair might not exist\r
 * → Try a different fee tier (500, 3000, or 10000)\r
 * → Make sure both tokens are available on Sepolia\r
 * \r
 * ERROR: Transaction fails with high gas estimate\r
 * → Pool liquidity might be too low\r
 * → Try swapping a smaller amount\r
 * → Use multi-hop through WETH\r
 * \r
 * ERROR: "Too little received" \r
 * → Your amountOutMinimum is set too high\r
 * → For testing, set amountOutMinimum to 0\r
 * → In production, calculate expected output with 1-5% slippage\r
 * \r
 * ============================================\r
 * ADVANCED: MULTI-HOP SWAP EXAMPLE\r
 * ============================================\r
 * \r
 * To swap USDC → WETH → DAI:\r
 * \r
 * 1. Build the path manually or use a helper:\r
 *    - Use online tool: uniswap.org/developers/sdk/guides/routing\r
 *    - Or construct manually (see path encoding above)\r
 * \r
 * 2. Call swapMultiHop:\r
 *    - tokenIn: 0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8 (USDC)\r
 *    - tokenOut: 0x68194a729C2450ad26072b3D33ADaCbcef39D574 (DAI)\r
 *    - path: [your encoded path from step 1]\r
 *    - amountIn: [amount of USDC to swap]\r
 *    - amountOutMinimum: 0 (for testing)\r
 * \r
 * ============================================\r
 * KEY LEARNING POINTS\r
 * ============================================\r
 * \r
 * 1. APPROVALS: Before Uniswap can swap your tokens, you must approve the SwapRouter\r
 *    - This is done automatically in the contract with TransferHelper.safeApprove\r
 * \r
 * 2. POOL FEES: Different pairs have different fee tiers\r
 *    - Stablecoins typically use 0.05% (500)\r
 *    - Most pairs use 0.3% (3000)\r
 *    - Exotic pairs use 1% (10000)\r
 * \r
 * 3. SLIPPAGE: amountOutMinimum protects you from unfavorable price movement\r
 *    - Set to 0 for testing only\r
 *    - Production: calculate expected output and subtract 1-5%\r
 * \r
 * 4. DEADLINE: Transactions have a time limit (we use 5 minutes)\r
 *    - Prevents transactions from executing at stale prices\r
 * \r
 * 5. PATH ENCODING: Multi-hop swaps pack tokens and fees into bytes\r
 *    - This is why path looks like a long hex string\r
 *    - Each hop adds 23 bytes (20 for token + 3 for fee)\r
 */\r
"
    },
    "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol": {
      "content": "// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.0;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';

library TransferHelper {
    /// @notice Transfers tokens from the targeted address to the given destination
    /// @notice Errors with 'STF' if transfer fails
    /// @param token The contract address of the token to be transferred
    /// @param from The originating address from which the tokens will be transferred
    /// @param to The destination address of the transfer
    /// @param value The amount to be transferred
    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) =
            token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF');
    }

    /// @notice Transfers tokens from msg.sender to a recipient
    /// @dev Errors with ST if transfer fails
    /// @param token The contract address of the token which will be transferred
    /// @param to The recipient of the transfer
    /// @param value The value of the transfer
    function safeTransfer(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST');
    }

    /// @notice Approves the stipulated contract to spend the given allowance in the given token
    /// @dev Errors with 'SA' if transfer fails
    /// @param token The contract address of the token to be approved
    /// @param to The target of the approval
    /// @param value The amount of the given token the target will be allowed to spend
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA');
    }

    /// @notice Transfers ETH to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'STE');
    }
}
"
    },
    "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)

pragma solidity >=0.4.16;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}
"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": false,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    },
    "remappings": []
  }
}}

Tags:
ERC20, DeFi, Swap, Liquidity, Factory|addr:0x199a453cdbd22a9017284338e19b94904bc1b4b1|verified:true|block:23745728|tx:0xcea71fac0e0557a75d2ab87d661212d1e2f99c12ac4aa98591ea615dfeaea0fc|first_check:1762516080

Submitted on: 2025-11-07 12:48:01

Comments

Log in to comment.

No comments yet.