# ═══════════════════════════════════════════════════════════════════════════════ # ALPHIX DEPLOYMENT CONFIGURATION # ═══════════════════════════════════════════════════════════════════════════════ # # Copy this file to .env and fill in the values for your deployment. # All addresses should be checksummed. Variables are suffixed with network name. # # Deployment Scripts Order: # Testnet Mocks (optional): # testnet/00_DeployMockERC20.s.sol → TOKEN_A, TOKEN_B # testnet/01_DeployMockWETH.s.sol → MOCK_WETH # testnet/02_DeployMockYieldVault.s.sol → YIELD_SOURCE_A, YIELD_SOURCE_B # testnet/02b_DeployMockYieldVaultETH.s.sol → YIELD_SOURCE_ETH # # Main Deployment: # 00_DeployAccessManager.s.sol → ACCESS_MANAGER # 01_DeployAlphix.s.sol → ALPHIX_HOOK (for ERC20/ERC20 pools) # 01_DeployAlphixETH.s.sol → ALPHIX_HOOK (for ETH/ERC20 pools) # 02_ConfigureAndUnpause.s.sol → Roles + Unpause # 03_CreatePool.s.sol → Pool creation # 04_ConfigureReHypothecation.s.sol → Yield sources + JIT range # 05_AddLiquidity.s.sol → Add normal V4 liquidity # 05b_AddRHLiquidity.s.sol → Add rehypothecated liquidity # 05c_RemoveRHLiquidity.s.sol → Remove rehypothecated liquidity # 06_Swap.s.sol → Execute swaps (testnet - PoolSwapTest) # 06b_SwapUniversalRouter.s.sol → Execute swaps (mainnet - Universal Router) # 07_PokeFee.s.sol → Update dynamic fee # 08_TransferOwnership.s.sol → Transfer to multisig # 08b_AcceptOwnership.s.sol → Accept ownership # # ═══════════════════════════════════════════════════════════════════════════════ # ───────────────────────────────────────────────────────────────────────────────── # NETWORK CONFIGURATION # ───────────────────────────────────────────────────────────────────────────────── DEPLOYMENT_NETWORK=BASE_SEPOLIA # RPC URL (get from Alchemy/Infura/QuickNode) RPC_URL=https://base-sepolia.g.alchemy.com/v2/ # Deployer private key (USE TEST KEY ONLY!) PRIVATE_KEY=0x... # BaseScan API key for contract verification ETHERSCAN_API_KEY= # ───────────────────────────────────────────────────────────────────────────────── # UNISWAP V4 ADDRESSES (Official - https://docs.uniswap.org/contracts/v4/deployments) # ───────────────────────────────────────────────────────────────────────────────── POOL_MANAGER_BASE_SEPOLIA=0x05E73354cFDd6745C338b50BcFDfA3Aa6fA03408 POSITION_MANAGER_BASE_SEPOLIA=0x4b2c77d209d3405f41a037ec6c77f7f5b8e2ca80 UNIVERSAL_ROUTER_BASE_SEPOLIA=0x492e6456d9528771018deb9e87ef7750ef184104 POOL_SWAP_TEST_ROUTER_BASE_SEPOLIA=0x8b5bcc363dde2614281ad875bad385e0a785d3b9 CREATE2_DEPLOYER_BASE_SEPOLIA=0x4e59b44847b379578588920cA78FbF26c0B4956C # ───────────────────────────────────────────────────────────────────────────────── # ACCESS CONTROL # ───────────────────────────────────────────────────────────────────────────────── # AccessManager admin (controls roles/permissions) ACCESS_MANAGER_ADMIN_BASE_SEPOLIA= # Alphix hook owner (can pause, configure, manage pool) ALPHIX_OWNER_BASE_SEPOLIA= # Yield manager (can set yield sources) YIELD_MANAGER_BASE_SEPOLIA= # Fee poker (can call poke() to update dynamic fee) FEE_POKER_BASE_SEPOLIA= # Pauser (can pause/unpause the hook) PAUSER_BASE_SEPOLIA= # ═══════════════════════════════════════════════════════════════════════════════ # TESTNET MOCK TOKENS (Optional) # ═══════════════════════════════════════════════════════════════════════════════ # ───────────────────────────────────────────────────────────────────────────────── # MOCK TOKEN A (e.g., USDC-like) - testnet/00_DeployMockERC20.s.sol # ───────────────────────────────────────────────────────────────────────────────── # MOCK_TOKEN_NAME_BASE_SEPOLIA="Alphix Testnet USDC" # MOCK_TOKEN_SYMBOL_BASE_SEPOLIA=atUSDC # MOCK_TOKEN_DECIMALS_BASE_SEPOLIA=6 # MOCK_TOKEN_INITIAL_MINT_BASE_SEPOLIA=1000000000000 # After deployment: # TOKEN_A_BASE_SEPOLIA= # ───────────────────────────────────────────────────────────────────────────────── # MOCK TOKEN B (e.g., DAI-like) - Re-run testnet/00_DeployMockERC20.s.sol # ───────────────────────────────────────────────────────────────────────────────── # MOCK_TOKEN_NAME_BASE_SEPOLIA="Alphix Testnet DAI" # MOCK_TOKEN_SYMBOL_BASE_SEPOLIA=atDAI # MOCK_TOKEN_DECIMALS_BASE_SEPOLIA=18 # MOCK_TOKEN_INITIAL_MINT_BASE_SEPOLIA=1000000000000000000000000 # After deployment: # TOKEN_B_BASE_SEPOLIA= # ───────────────────────────────────────────────────────────────────────────────── # MOCK WETH - testnet/01_DeployMockWETH.s.sol # ───────────────────────────────────────────────────────────────────────────────── # (No config needed - hardcoded name/symbol) # After deployment: # MOCK_WETH_BASE_SEPOLIA= # ───────────────────────────────────────────────────────────────────────────────── # YIELD VAULT FOR TOKEN A - testnet/02_DeployMockYieldVault.s.sol # ───────────────────────────────────────────────────────────────────────────────── # MOCK_VAULT_ASSET_BASE_SEPOLIA= # MOCK_VAULT_NAME_BASE_SEPOLIA="Alphix Testnet USDC Vault" # MOCK_VAULT_SYMBOL_BASE_SEPOLIA=atUSDC-V # After deployment: # YIELD_SOURCE_A_BASE_SEPOLIA= # ───────────────────────────────────────────────────────────────────────────────── # YIELD VAULT FOR TOKEN B - Re-run testnet/02_DeployMockYieldVault.s.sol # ───────────────────────────────────────────────────────────────────────────────── # MOCK_VAULT_ASSET_BASE_SEPOLIA= # MOCK_VAULT_NAME_BASE_SEPOLIA="Alphix Testnet DAI Vault" # MOCK_VAULT_SYMBOL_BASE_SEPOLIA=atDAI-V # After deployment: # YIELD_SOURCE_B_BASE_SEPOLIA= # ───────────────────────────────────────────────────────────────────────────────── # ETH YIELD VAULT (WETH-based) - testnet/02b_DeployMockYieldVaultETH.s.sol # ───────────────────────────────────────────────────────────────────────────────── # MOCK_ETH_VAULT_WETH_BASE_SEPOLIA= # MOCK_ETH_VAULT_NAME_BASE_SEPOLIA="Alphix Testnet ETH Vault" # MOCK_ETH_VAULT_SYMBOL_BASE_SEPOLIA=atETH-V # After deployment: # YIELD_SOURCE_ETH_BASE_SEPOLIA= # ═══════════════════════════════════════════════════════════════════════════════ # ALPHIX HOOK DEPLOYMENT # ═══════════════════════════════════════════════════════════════════════════════ # LP token metadata TOKEN_NAME_BASE_SEPOLIA="Alphix LP Shares" TOKEN_SYMBOL_BASE_SEPOLIA=ALPHIX-LP # After deployment (00_DeployAccessManager.s.sol): # ACCESS_MANAGER_BASE_SEPOLIA= # After deployment (01_DeployAlphix.s.sol or 01_DeployAlphixETH.s.sol): # ALPHIX_HOOK_BASE_SEPOLIA= # ═══════════════════════════════════════════════════════════════════════════════ # POOL CREATION CONFIG (03_CreatePool.s.sol) # ═══════════════════════════════════════════════════════════════════════════════ # Token addresses (TOKEN0 < TOKEN1 by address, use 0x0...0 for native ETH) # For ERC20/ERC20 pool: Sort tokens by address (lower first) TOKEN0_BASE_SEPOLIA= TOKEN1_BASE_SEPOLIA= # For ETH/ERC20 pool: # TOKEN0_BASE_SEPOLIA=0x0000000000000000000000000000000000000000 # TOKEN1_BASE_SEPOLIA= # Pool parameters TICK_SPACING_BASE_SEPOLIA=60 # ───────────────────────────────────────────────────────────────────────────────── # CRITICAL: SQRT_PRICE AND JIT TICK RANGE ALIGNMENT # ───────────────────────────────────────────────────────────────────────────────── # # For balanced JIT liquidity (equal value of token0/token1), SQRT_PRICE must be # at the GEOMETRIC CENTER of the JIT tick range. This is critical for tight ranges! # # WRONG: Arbitrary sqrtPrice with arbitrary JIT range → highly skewed token ratios # (e.g., 74:1 instead of 1:1 for a 2-tick range!) # RIGHT: Calculate sqrtPrice from JIT range center, OR calculate JIT range from sqrtPrice # # FORMULA - Given JIT tick range [tickLower, tickUpper]: # centerTick = (tickLower + tickUpper) / 2 # sqrtPrice = sqrt(1.0001^centerTick) * 2^96 # # PYTHON HELPER (copy-paste to calculate): # import math # def jit_range_to_sqrt_price(tick_lower, tick_upper): # center_tick = (tick_lower + tick_upper) / 2 # return int(math.sqrt(1.0001 ** center_tick) * (2**96)) # # def sqrt_price_to_jit_range(sqrt_price_x96, half_width, tick_spacing): # price = (sqrt_price_x96 / 2**96) ** 2 # center_tick = int(math.log(price) / math.log(1.0001)) # # Round center to tick spacing # center_tick = (center_tick // tick_spacing) * tick_spacing # return (center_tick - half_width * tick_spacing, # center_tick + half_width * tick_spacing) # # EXAMPLE - For 1:1 stablecoin pool with 18dec/6dec tokens (e.g., DAI/USDC): # Price in raw terms = 10^6 / 10^18 = 1e-12 # centerTick = log(1e-12) / log(1.0001) ≈ -276325 # For tick_spacing=1 and half_width=1: JIT range = [-276326, -276324] # sqrtPrice = jit_range_to_sqrt_price(-276326, -276324) = 79224306130968649924608 # # WARNING: Using a sqrtPrice that's NOT centered in your JIT range causes extreme # asymmetry. A 2-tick range with sqrtPrice at 97% (instead of 50%) gives 74:1 ratio! # ───────────────────────────────────────────────────────────────────────────────── # Starting price: floor(sqrt(token1/token0) * 2^96) # Starting price: sqrtPriceX96 = sqrt(price_raw) * 2^96 # where price_raw = token1_amount / token0_amount (in raw wei, accounting for decimals) # MUST BE at the geometric center of JIT tick range for balanced liquidity! SQRT_PRICE_BASE_SEPOLIA=79228162514264337593543950336 # Initial liquidity amounts (in wei) AMOUNT0_BASE_SEPOLIA=1000000000000000000000 AMOUNT1_BASE_SEPOLIA=1000000000000000000000 # Number of tick spacings around current price for liquidity range LIQUIDITY_RANGE_BASE_SEPOLIA=100 # Dynamic fee settings INITIAL_FEE_BASE_SEPOLIA=3000 # Target ratio: 0.5e18 = 50% (balanced), 1e18 = 100% TARGET_RATIO_BASE_SEPOLIA=500000000000000000 # ───────────────────────────────────────────────────────────────────────────────── # JIT TICK RANGE (immutable after pool initialization) # ───────────────────────────────────────────────────────────────────────────────── # These define where JIT liquidity will be provided during swaps. # # CRITICAL: SQRT_PRICE must be at the geometric center of this range! # See the SQRT_PRICE documentation above for formulas and examples. # # RECOMMENDED WORKFLOW: # 1. Decide your target price (e.g., 1 DAI = 1 USDC) # 2. Calculate the center tick for that price # 3. Choose half_width based on desired concentration (1-5 tick spacings recommended) # 4. Set JIT_TICK_LOWER = centerTick - half_width * tickSpacing # 5. Set JIT_TICK_UPPER = centerTick + half_width * tickSpacing # 6. Calculate SQRT_PRICE using jit_range_to_sqrt_price(lower, upper) # # Full range example for tick spacing 60: min=-887220, max=887220 JIT_TICK_LOWER_BASE_SEPOLIA=-887220 JIT_TICK_UPPER_BASE_SEPOLIA=887220 # ═══════════════════════════════════════════════════════════════════════════════ # REHYPOTHECATION CONFIG (04_ConfigureReHypothecation.s.sol) # ═══════════════════════════════════════════════════════════════════════════════ # Yield sources (ERC-4626 vaults) - must match TOKEN0/TOKEN1 order # For ETH pools: YIELD_SOURCE_0 must implement IAlphix4626WrapperWeth YIELD_SOURCE_0_BASE_SEPOLIA= YIELD_SOURCE_1_BASE_SEPOLIA= # ═══════════════════════════════════════════════════════════════════════════════ # ADD LIQUIDITY CONFIG # ═══════════════════════════════════════════════════════════════════════════════ # Normal V4 liquidity (05_AddLiquidity.s.sol) LP_AMOUNT0_BASE_SEPOLIA=1000000000000000000000 LP_AMOUNT1_BASE_SEPOLIA=1000000000000000000000 LP_LIQUIDITY_RANGE_BASE_SEPOLIA=100 # Rehypothecated liquidity shares (05b_AddRHLiquidity.s.sol) RH_SHARES_BASE_SEPOLIA=1000000000000000000000 # Max token amounts to prevent overspending (required safety check) # Scale by each token's decimals (TOKEN0/TOKEN1 are ordered by address, not type). RH_AMOUNT0_MAX_BASE_SEPOLIA= RH_AMOUNT1_MAX_BASE_SEPOLIA= # Remove rehypothecated liquidity (05c_RemoveRHLiquidity.s.sol) RH_REMOVE_SHARES_BASE_SEPOLIA=1000000000000000000000 # Min token amounts for slippage protection (set to 0 for no protection) RH_REMOVE_AMOUNT0_MIN_BASE_SEPOLIA= RH_REMOVE_AMOUNT1_MIN_BASE_SEPOLIA= # ═══════════════════════════════════════════════════════════════════════════════ # OPERATIONS # ═══════════════════════════════════════════════════════════════════════════════ # Swap parameters (06_Swap.s.sol / 06b_SwapUniversalRouter.s.sol) SWAP_AMOUNT_IN_BASE_SEPOLIA=100000000000000000 SWAP_ZERO_FOR_ONE_BASE_SEPOLIA=true SWAP_MIN_OUTPUT_BASE_SEPOLIA=0 # Fee update (07_PokeFee.s.sol) CURRENT_RATIO_BASE_SEPOLIA=500000000000000000 # Ownership transfer (08_TransferOwnership.s.sol) NEW_OWNER_BASE_SEPOLIA= # ═══════════════════════════════════════════════════════════════════════════════ # WRAPPER DEPLOYMENT CONFIG # ═══════════════════════════════════════════════════════════════════════════════ # # Wrappers are ERC-4626 yield vaults that integrate with external protocols # (Aave, Sky/Spark, etc.) and can be used as yield sources for Alphix hooks. # # Deployment Scripts: # wrappers/aave/DeployAlphix4626WrapperAave.s.sol → Generic ERC20 wrapper for Aave # wrappers/aave/DeployAlphix4626WrapperWethAave.s.sol → WETH-specific wrapper for Aave # wrappers/sky/DeployAlphix4626WrapperSky.s.sol → USDS/sUSDS wrapper via Spark PSM # # ───────────────────────────────────────────────────────────────────────────────── # COMMON WRAPPER SETTINGS # ───────────────────────────────────────────────────────────────────────────────── # Fee recipient for yield fees (same for all wrappers) YIELD_TREASURY= # Initial fee in hundredths of a bip (100_000 = 10%, 50_000 = 5%) INITIAL_FEE=100000 # ───────────────────────────────────────────────────────────────────────────────── # AAVE WRAPPER - Generic ERC20 (DeployAlphix4626WrapperAave.s.sol) # ───────────────────────────────────────────────────────────────────────────────── # Aave V3 PoolAddressesProvider addresses: # Mainnet: 0x2f39d218133AFaB8F2B819B1066c7E434Ad94E9e # Arbitrum: 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb # Optimism: 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb # Polygon: 0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb # Base: 0xe20fCBdBfFC4Dd138cE8b2E6FBb6CB49777ad64D ASSET_ADDRESS= POOL_ADDRESSES_PROVIDER= SHARE_NAME="Alphix USDC Vault" SHARE_SYMBOL=alphUSDC SEED_LIQUIDITY=1000000 # After deployment: # AAVE_WRAPPER_ADDRESS= # ───────────────────────────────────────────────────────────────────────────────── # AAVE WETH WRAPPER (DeployAlphix4626WrapperWethAave.s.sol) # ───────────────────────────────────────────────────────────────────────────────── # WETH addresses: # Mainnet: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 # Arbitrum: 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1 # Optimism: 0x4200000000000000000000000000000000000006 # Polygon: 0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619 (WETH, not native MATIC) # Base: 0x4200000000000000000000000000000000000006 WETH_ADDRESS= # POOL_ADDRESSES_PROVIDER= (same as above) # SHARE_NAME="Alphix WETH Vault" # SHARE_SYMBOL=alphWETH # SEED_LIQUIDITY=1000000000000000000 # After deployment: # AAVE_WETH_WRAPPER_ADDRESS= # ───────────────────────────────────────────────────────────────────────────────── # SKY/SPARK WRAPPER - USDS/sUSDS (DeployAlphix4626WrapperSky.s.sol) # ───────────────────────────────────────────────────────────────────────────────── # Spark PSM3 addresses: # Base: 0x1601843c5E9bC251A3272907010AFa41Fa18347E SKY_PSM_ADDRESS= SKY_SHARE_NAME="Alphix sUSDS Vault" SKY_SHARE_SYMBOL=alphsUSDS SKY_SEED_LIQUIDITY=1000000000000000000 SKY_REFERRAL_CODE=0 # After deployment: # SKY_WRAPPER_ADDRESS=