#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then # shellcheck disable=SC1090 source "$SCRIPT_DIR/../lib/deployment/dotenv.sh" load_deployment_env --repo-root "$REPO_ROOT" fi POSITION_MANAGER="${POSITION_MANAGER:-}" RPC_URL="${RPC_URL:-}" TOKEN_A="${TOKEN_A:-}" TOKEN_B="${TOKEN_B:-}" AMOUNT_A="${AMOUNT_A:-}" AMOUNT_B="${AMOUNT_B:-}" FEE="${FEE:-500}" EXECUTE="${EXECUTE:-0}" DEADLINE_SECONDS="${DEADLINE_SECONDS:-3600}" RECIPIENT="${RECIPIENT:-}" PRIVATE_KEY="${PRIVATE_KEY:-}" if [[ -z "$POSITION_MANAGER" || -z "$RPC_URL" || -z "$TOKEN_A" || -z "$TOKEN_B" || -z "$AMOUNT_A" || -z "$AMOUNT_B" ]]; then echo "Required: POSITION_MANAGER RPC_URL TOKEN_A TOKEN_B AMOUNT_A AMOUNT_B" >&2 exit 1 fi if [[ -z "$RECIPIENT" ]]; then if [[ -z "$PRIVATE_KEY" ]]; then echo "Set RECIPIENT or PRIVATE_KEY" >&2 exit 1 fi RECIPIENT="$(cast wallet address --private-key "$PRIVATE_KEY")" fi lower_hex="$(printf '%s\n%s\n' "$TOKEN_A" "$TOKEN_B" | tr '[:upper:]' '[:lower:]' | sort | sed -n '1p')" upper_hex="$(printf '%s\n%s\n' "$TOKEN_A" "$TOKEN_B" | tr '[:upper:]' '[:lower:]' | sort | sed -n '2p')" token0="$lower_hex" token1="$upper_hex" amount0="$AMOUNT_A" amount1="$AMOUNT_B" if [[ "${TOKEN_A,,}" != "$token0" ]]; then amount0="$AMOUNT_B" amount1="$AMOUNT_A" fi case "$FEE" in 100) tick_spacing=1 ;; 500) tick_spacing=10 ;; 3000) tick_spacing=60 ;; 10000) tick_spacing=200 ;; *) echo "Unsupported fee tier for tick-spacing inference: $FEE" >&2 exit 1 ;; esac min_tick=-887272 max_tick=887272 tick_lower=$(( (min_tick / tick_spacing) * tick_spacing )) tick_upper=$(( (max_tick / tick_spacing) * tick_spacing )) deadline="$(($(date +%s) + DEADLINE_SECONDS))" echo "Funding Uniswap v3 pool" echo " token0: $token0 amount0: $amount0" echo " token1: $token1 amount1: $amount1" echo " fee: $FEE ticks: [$tick_lower, $tick_upper]" echo " recipient: $RECIPIENT" if [[ "$EXECUTE" != "1" ]]; then echo "Dry run only." echo "Approve token0:" echo " cast send \"$token0\" 'approve(address,uint256)' \"$POSITION_MANAGER\" \"$amount0\" --rpc-url \"$RPC_URL\" --private-key \"\$PRIVATE_KEY\"" echo "Approve token1:" echo " cast send \"$token1\" 'approve(address,uint256)' \"$POSITION_MANAGER\" \"$amount1\" --rpc-url \"$RPC_URL\" --private-key \"\$PRIVATE_KEY\"" echo "Mint position:" echo " cast send \"$POSITION_MANAGER\" \"mint((address,address,uint24,int24,int24,uint256,uint256,uint256,uint256,address,uint256))\" \"($token0,$token1,$FEE,$tick_lower,$tick_upper,$amount0,$amount1,0,0,$RECIPIENT,$deadline)\" --rpc-url \"$RPC_URL\" --private-key \"\$PRIVATE_KEY\" -vv" exit 0 fi if [[ -z "$PRIVATE_KEY" ]]; then echo "PRIVATE_KEY is required when EXECUTE=1" >&2 exit 1 fi cast send "$token0" \ "approve(address,uint256)" \ "$POSITION_MANAGER" \ "$amount0" \ --rpc-url "$RPC_URL" \ --private-key "$PRIVATE_KEY" \ -q cast send "$token1" \ "approve(address,uint256)" \ "$POSITION_MANAGER" \ "$amount1" \ --rpc-url "$RPC_URL" \ --private-key "$PRIVATE_KEY" \ -q cast send "$POSITION_MANAGER" \ "mint((address,address,uint24,int24,int24,uint256,uint256,uint256,uint256,address,uint256))" \ "($token0,$token1,$FEE,$tick_lower,$tick_upper,$amount0,$amount1,0,0,$RECIPIENT,$deadline)" \ --rpc-url "$RPC_URL" \ --private-key "$PRIVATE_KEY" \ -vv