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": []
}
}}
Submitted on: 2025-11-07 12:48:01
Comments
Log in to comment.
No comments yet.