Quick Start
DeFiPy’s primitives are organized into two layers — Core Primitives and Agentic Primitives — both dispatching across Uniswap V2, Uniswap V3, Balancer, and Stableswap through a unified interface.
Core Primitives are the execution layer. They handle pool initialization, swapping, liquidity management, and quoting — the operations that mutate pool state. See the Core Primitives Overview for the full availability grid.
Agentic Primitives are the analytics layer. They answer questions about positions, risk, and pool health without mutating state — 21 stateless, typed functions that return structured dataclass results. They’re callable identically from a notebook or from an LLM via MCP. See the Agentic Primitives Overview for the full catalog and executable examples.
This Quick Start covers the essential Core Primitives for getting started — Join, Swap, and pool setup — for each protocol. Additional Core Primitives (AddLiquidity, RemoveLiquidity, SwapDeposit, WithdrawSwap, LPQuote) are referenced in the notes at the end of each section, with links to their full tutorials.
Uniswap V2
Section titled “Uniswap V2”The Abstract Interface simplifies Uniswap V2 operations, such as pool creation and liquidity management. While the Primitive Interface offers detailed control (e.g., via UniswapFactory and UniswapExchange), the Abstract Interface streamlines these tasks, as partially reflected in Example 1, which sets up a pool and adds liquidity.
Key Classes
-
Class:
defipy.erc.ERC20- Purpose: Represents tokens in the liquidity pool, defined by a symbol and address.
- Usage:
ERC20(symbol, address) - Example:
tkn = ERC20("TKN", "0x111")
-
Class:
defipy.utils.data.UniswapExchangeData- Purpose: Encapsulates configuration data for the pool, including the token pair and pool symbol.
- Usage:
UniswapExchangeData(tkn0, tkn1, symbol, address) - Example:
exch_data = UniswapExchangeData(tkn0=eth, tkn1=tkn, symbol="LP", address="0x3")
-
Class:
defipy.cpt.factory.UniswapFactory- Purpose: Manages the creation of new Uniswap liquidity pools.
- Usage:
UniswapFactory(name, address) - Example:
factory = UniswapFactory("ETH pool factory", "0x2")
Abstract Interface Operations
-
Class:
defipy.process.Join-
Purpose: Simplifies initial liquidity addition to Uniswap V2 pools.
-
Methods:
apply(pool, user: str, amount0: float, amount1: float)- Parameters:
pool: Pool instance (e.g., created via Primitive Interface).user: User address.amount0: Amount of token0.amount1: Amount of token1.
- Parameters:
-
Output: Liquidity added to the pool.
-
-
Class:
defipy.process.Swap-
Purpose: Facilitates token swaps in Uniswap V2 pools.
-
Methods:
-
apply(pool, user: str, token_in: str, token_out: str, amount_in: float)- Parameters:
pool: Pool instance.user: User address.token_in: Input token symbol.amount_in: Input amount.
- Parameters:
-
Output: Tokens swapped.
-
-
Example 1: Uniswap V2 Setup and Liquidity Addition
from defipy import ERC20, UniswapFactory, UniswapExchangeData, Join, Swap
# Step 1: Define tokenstkn = ERC20("TKN", "0x111")eth = ERC20("ETH", "0x999")
# Step 2: Initialize factoryfactory = UniswapFactory("ETH pool factory", "0x2")
# Step 3: Set up exchange data for V2exch_data = UniswapExchangeData(tkn0=eth, tkn1=tkn, symbol="LP", address="0x3")
# Step 4: Deploy poollp = factory.deploy(exch_data)
# Step 5: Add initial liquidityjoin = Join()join.apply(lp, "user", 1000, 10000)
# Step 6: Perform swapswap = Swap()out = swap.apply(lp, tkn, "user", 10)
# Check reserves and liquiditylp.summary()Uniswap V3
Section titled “Uniswap V3”The Abstract Interface shines in Uniswap V3 by simplifying complex operations like adding liquidity within specific price ranges. Example 2 demonstrates this with the Join class, abstracting the detailed tick management required by the Primitive Interface.
Key Classes
-
Class:
defipy.erc.ERC20- Purpose: Represents tokens in the liquidity pool, defined by a symbol and address.
- Usage:
ERC20(symbol, address) - Example:
tkn = ERC20("TKN", "0x111")
-
Class:
defipy.utils.data.UniswapExchangeData- Purpose: Encapsulates configuration data for the pool, including the token pair and pool symbol.
- Usage:
UniswapExchangeData(tkn0, tkn1, symbol, address, version, tick_spacing, fee)) - Example:
exch_data = UniswapExchangeData(tkn0=eth, tkn1=tkn, symbol="LP", address="0x811", version='V3', tick_spacing=60, fee=3000)
-
Class:
defipy.cpt.factory.UniswapFactory- Purpose: Manages the creation of new Uniswap liquidity pools.
- Usage:
UniswapFactory(name, address) - Example:
factory = UniswapFactory("ETH pool factory", "0x2")
Abstract Interface Operations
-
Class:
defipy.process.Join-
Purpose: Adds initial liquidity to Uniswap V3 pools across specified tick ranges.
-
Methods:
apply(pool, user: str, amount0: float, amount1: float, lwr_tick: int, upr_tick: int)- Parameters:
pool: Uniswap V3 pool instance.user: User address.amount0: Amount of token0.amount1: Amount of token1.lwr_tick: Lower tick of the price range.upr_tick: Upper tick of the price range.
- Parameters:
-
Output: Liquidity added to the specified range.
-
-
Class:
defipy.process.Swap-
Purpose: Executes swaps in Uniswap V3 pools.
-
Methods:
apply(pool, user: str, token_in: str, token_out: str, amount_in: float)- Parameters:
pool: Pool instance.user: User address.token_in: Input token symbol.amount_in: Input amount.
- Parameters:
-
Output: Tokens swapped.
-
Example 2a: Uniswap V3 Setup and Liquidity Addition
from defipy import ERC20, UniswapFactory, UniswapExchangeData, Join, Swap, UniV3Utils
# Step 1: Define tokens and parameterseth = ERC20("ETH", "0x93")tkn = ERC20("TKN", "0x111")tick_spacing = 60fee = 3000 # 0.3% fee tier
# Step 2: Set up exchange data for V3exch_data = UniswapExchangeData(tkn0=eth, tkn1=tkn, symbol="LP", address="0x811", version='V3', tick_spacing=tick_spacing, fee=fee)
# Step 3: Initialize factoryfactory = UniswapFactory("ETH pool factory", "0x2")
# Step 4: Deploy poollp = factory.deploy(exch_data)
# Step 5: Add initial liquidity within tick rangelwr_tick = UniV3Utils.getMinTick(tick_spacing)upr_tick = UniV3Utils.getMaxTick(tick_spacing)join = Join()join.apply(lp, "user", 1000, 10000, lwr_tick, upr_tick)
# Step 6: Perform swapswap = Swap()out = swap.apply(lp, tkn, "user", 10)
# Check reserves and liquiditylp.summary()Example 2b: Uniswap V3 Setup and Liquidity Addition with Custom Price Ticks
from defipy import ERC20, UniswapFactory, UniswapExchangeData, UniV3Utils, UniV3Helperfrom defipy import Join, Swap
# Step 1: Define tokens and parameterseth = ERC20("ETH", "0x93")tkn = ERC20("TKN", "0x111")tick_spacing = 60fee = 3000 # 0.3% fee tieramt_eth = 1000amt_tkn = 10000
# Step 2: Set up exchange data for V3exch_data = UniswapExchangeData(tkn0=eth, tkn1=tkn, symbol="LP", address="0x811", version='V3', tick_spacing=tick_spacing, fee=fee)
# Step 3: Initialize factoryfactory = UniswapFactory("ETH pool factory", "0x2")
# Step 4: Deploy poollp = factory.deploy(exch_data)
# Step 5: Add initial liquidity within custom tick rangeinit_price = amt_tkn/amt_ethlwr_tick = UniV3Helper().get_price_tick(lp, -1, init_price, 1000)upr_tick = UniV3Helper().get_price_tick(lp, 1, init_price, 1000)join = Join()join.apply(lp, "user", amt_eth, amt_tkn, lwr_tick, upr_tick)
# Step 6: Perform swapswap = Swap()out = swap.apply(lp, tkn, "user", 10)
# Check reserves and liquiditylp.summary()Balancer
Section titled “Balancer”For Balancer, the Abstract Interface simplifies multi-token pool management, such as joining weighted pools. Example 3 code block shows pool setup and liquidity addition, which could leverage Abstract Interface classes like Join for streamlined operations.
Key Classes
-
Class:
defipy.erc.ERC20- Purpose: Represents tokens in the liquidity pool, defined by a symbol and address.
- Usage:
ERC20(symbol, address) - Example:
tkn = ERC20("TKN", "0x111")
-
Class:
defipy.utils.data.BalancerVault- Purpose: Manages tokens and their weights.
- Usage:
BalancerVault() - Methods:
add_token(token, denorm_weight) - Example:
vault.add_token(dai, 10))
-
Class:
defipy.utils.data.BalancerExchangeData- Purpose: Encapsulates configuration data for the pool, including the pool’s vault and symbol.
- Usage:
BalancerExchangeData(vault, symbol, address) - Example:
exch_data = BalancerExchangeData(vault=vault, symbol="BSP", address="0x3")
-
Class:
defipy.cpt.factory.BalancerFactory- Purpose: Deploys new Balancer pools.
- Usage:
BalancerFactory(name, address) - Example:
factory = BalancerFactory("ETH pool factory", "0x2")
Abstract Interface Operations
-
Class:
defipy.process.Join-
Purpose: Adds initial liquidity to Balancer weighted pools.
- Methods:
apply(pool, user: str, amount: float)- Parameters:
pool: Balancer pool instance.user: User address.amount: Input shares.
- Parameters:
- Methods:
-
Output: Liquidity added proportionally to weights.
-
-
Class:
defipy.process.Swap-
Purpose: Executes swaps in Balancer pools.
-
Methods:
apply(pool, user: str, token_in: str, token_out: str, amount_in: float)- Parameters:
pool: Pool instance.token_in: Input token symbol.token_out: Output token symbol.user: User address.amount_in: Input token amount.
- Parameters:
-
Output: Tokens swapped.
-
Example 3: Balancer Setup and Liquidity Addition
from defipy import ERC20, BalancerVault, BalancerFactory, BalancerExchangeData, Join, Swap, Proc
# Step 1: Define tokensdai = ERC20("DAI", "0x111")usdc = ERC20("USDC", "0x999")
# Step 2: Deposit token amountsdai.deposit(None, 10000)usdc.deposit(None, 20000)
# Step 3: Setup vaultvault = BalancerVault()vault.add_token(dai, 10) # Denormalized weight for DAIvault.add_token(usdc, 40) # Denormalized weight for WETH
# Step 4: Set up exchange data for Balancerexch_data = BalancerExchangeData(vault=vault, symbol="BSP", address="0x3")
# Step 5: Initialize factor for Balancerbfactory = BalancerFactory("WETH pool factory", "0x2")
# Step 6: Deploy poollp = bfactory.deploy(exch_data)
# Step 7: Join pool with initial liquidityjoin = Join()join.apply(lp, "user", 100) # Issue 100 pool shares
# Step 8: Perform swapswap = Swap(Proc.SWAPIN)out = swap.apply(lp, dai, usdc, "user", 10)
# Check reserves and liquiditylp.summary()StableSwap
Section titled “StableSwap”StableSwap operations, optimized for stablecoins, are simplified by the Abstract Interface, particularly for liquidity addition and swaps. Example 4 demonstrates pool setup and liquidity addition, adaptable to the Abstract Interface.
Key Classes
-
Class:
defipy.erc.ERC20- Purpose: Represents tokens in the liquidity pool, defined by a symbol and address.
- Usage:
ERC20(symbol, address) - Example:
tkn = ERC20("TKN", "0x111")
-
Class:
defipy.utils.data.StableswapVault- Purpose: Manages tokens and their weights.
- Usage:
StableswapVault() - Methods:
add_token(token, denorm_weight) - Example:
vault.add_token(dai, 10))
-
Class:
defipy.utils.data.StableswapExchangeData- Purpose: Encapsulates configuration data for the pool, including the pool’s vault and symbol.
- Usage:
StableswapExchangeData(vault, symbol, address) - Example:
exch_data = StableswapExchangeData(vault=vault, symbol="SSP", address="0x3")
-
Class:
defipy.cpt.factory.StableswapFactory- Purpose: Deploys new Balancer pools.
- Usage:
StableswapFactory(name, address) - Example:
factory = StableswapFactory("ETH pool factory", "0x2")
Abstract Interface Operations
-
Class:
defipy.process.Join-
Purpose: Adds initial liquidity to StableSwap pools.
-
Methods:
apply(pool, user: str, token: str, ampl_coeff: float)- Parameters:
pool: StableSwap pool instance.user: User address.token: Token symbol to add.ampl_coeff: Amplification coefficient.
- Parameters:
-
Output: Liquidity added.
-
-
Class:
defipy.process.Swap-
Purpose: Executes swaps in StableSwap pools with low slippage.
-
Methods:
apply(pool, user: str, token_in: str, token_out: str, amount_in: float)- Parameters:
pool: Pool instance.token_in: Input token symbol.token_out: Output token symbol.user: User address.amount_in: Input amount.
- Parameters:
-
Output: Tokens swapped.
-
Example 4: StableSwap Setup and Operations
from defipy import ERC20, StableswapVault, StableswapFactory, StableswapExchangeData, Join, Swap
# Step 1: Define stablecoins and parametersdai = ERC20("DAI", "0x111", 18)usdc = ERC20("USDC", "0x222", 6)AMPL_COEFF = 2000
# Step 2: Deposit token amountsdai.deposit(None, 10000)usdc.deposit(None, 20000)
# Step 3: Setup Stableswap vault and add tokenssgrp = StableswapVault()sgrp.add_token(dai)sgrp.add_token(usdc)
# Step 4: Set up exchange data for Stableswapexch_data = StableswapExchangeData(vault = sgrp, symbol="LP", address="0x011")
# Step 5: Initialize factor for Balancerfactory = StableswapFactory("Stableswap factory", "0x2")
# Step 6: Deploy poollp = factory.deploy(exch_data)
# Step 7: Join pool with initial liquidityjoin = Join()join.apply(lp, "user", AMPL_COEFF)
# Step 8: Perform swapswap = Swap()out = swap.apply(lp, dai, usdc, "user", 10)
# Check reserves and liquiditylp.summary()