Executing Trades
Executing trades on the blockchain mutates state, costs gas, and requires cryptographic signatures. uniswap-python streamlines this by building the transaction, handling nonces, estimating gas, and managing token allowances.
To execute trades, your Uniswap client must be initialized with a valid address and private_key.
Slippage Tolerance
Because Ethereum blocks take time to mine, the price of an asset can change between the moment you submit your transaction and the moment it is confirmed.
To prevent your trade from executing at an unfavorable price (due to natural volatility or malicious front-running/sandwich attacks), you must define a slippage tolerance.
- If you set
slippage=0.01(1%), the trade will revert if the price moves against you by more than 1%. - You can set a global default during initialization (
Uniswap(..., default_slippage=0.01)), or override it on a per-trade basis.
Exact Input: make_trade
Use make_trade when you want to sell a precise amount of tokens.
from uniswap.fee import FeeTier
# Sell exactly 1 ETH for USDC
tx_hash = uniswap.make_trade(
input_token=ETH,
output_token=USDC,
qty=1 * 10**18, # The exact amount of ETH to sell
fee=FeeTier.TIER_3000, # V3 pool fee
slippage=0.005 # Tight slippage of 0.5%
)
# The returned value is a HexBytes object of the transaction hash
print(f"Transaction broadcasted: {tx_hash.hex()}")
Exact Output: make_trade_output
Use make_trade_output when you need to purchase a precise amount of tokens, regardless of the exact cost (up to your slippage limit).
# Buy exactly 1,000 USDC using ETH
tx_hash = uniswap.make_trade_output(
input_token=ETH,
output_token=USDC,
qty=1000 * 10**6, # The exact amount of USDC to receive
fee=FeeTier.TIER_3000,
slippage=0.01
)
Advanced Trade Parameters
Both trade functions accept additional arguments for specialized workflows:
Custom Recipient
By default, the tokens you buy are sent back to the address that initialized the Uniswap client. You can send the output to a different wallet by passing the recipient argument.
cold_wallet = Web3.to_checksum_address("0xColdWalletAddress...")
uniswap.make_trade(
input_token=ETH,
output_token=DAI,
qty=10**18,
recipient=cold_wallet,
fee=FeeTier.TIER_3000
)
Fee-on-Transfer Tokens (V2 Only)
Some altcoins feature "tokenomics" that burn a percentage of the token or reflect it to holders on every transfer. Standard Uniswap V2 router functions will fail with these tokens because the router receives less than it expects.
If you are interacting with V2 and trading a deflationary token, set fee_on_transfer=True.
uniswap.make_trade(
input_token=DEFLATIONARY_TOKEN,
output_token=ETH,
qty=1000 * 10**18,
fee_on_transfer=True # Tells V2 Router to use supportingFeeOnTransferTokens functions
)
Note: V3 does not natively support fee-on-transfer tokens in the same way, and passing this flag to a V3 client will raise an exception.
Automatic Approvals
Before a smart contract (like the Uniswap Router) can move your ERC20 tokens, you must explicitly approve it to do so.
uniswap-python utilizes a @check_approval decorator. When you call make_trade, the library checks your current allowance. If the allowance is insufficient, it automatically builds, signs, and broadcasts an approve transaction, waits for the block to confirm, and then executes your trade.
If you want to manually trigger an approval (e.g., to batch approvals when gas is cheap), you can do so:
# Approves the Uniswap router to spend your DAI
# Approves the maximum uint256 value by default so you don't have to approve again
uniswap.approve(DAI)
# Or approve a specific amount
# uniswap.approve(DAI, max_approval=500 * 10**18)
Common Pitfalls
- Insufficient Balance: If you attempt to trade more than your wallet holds, the library will pre-emptively raise an
InsufficientBalanceexception before sending the transaction. - Transaction Timeouts: The library enforces a default 10-minute deadline for trades. If the network is heavily congested and your transaction sits in the mempool for >10 minutes, the Uniswap contract will reject it to protect you from stale pricing.
- Gas Estimation Failures: If a trade is guaranteed to revert (e.g., due to extreme slippage or zero liquidity), the
eth_estimateGascall will fail. Ensure you are quoting prices before executing.