#!/usr/bin/env bash # Parse Deployment Output # Extracts contract addresses from Forge deployment output and broadcast logs set -euo pipefail # Configuration PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" BROADCAST_DIR="${PROJECT_ROOT}/broadcast" CONTRACT_ADDRESSES_FILE="${PROJECT_ROOT}/contracts-deployed.json" # Colors for output # Logging function log() { log_success "[$(date +'%Y-%m-%d %H:%M:%S')] $1" } error() { log_error "[ERROR] $1" exit 1 } warn() { log_warn "[WARNING] $1" } # Initialize contract addresses file init_contract_addresses() { if [ ! -f "$CONTRACT_ADDRESSES_FILE" ]; then echo "{}" > "$CONTRACT_ADDRESSES_FILE" fi } # Extract contract address from broadcast log extract_from_broadcast() { local script_name=$1 local contract_name=$2 local chain_id=${3:-138} local broadcast_file="${BROADCAST_DIR}/${script_name}/${chain_id}/run-latest.json" if [ ! -f "$broadcast_file" ]; then return 1 fi # Try to extract from transactions local address=$(jq -r ".transactions[] | select(.contractName == \"$contract_name\" or .contractName == \"${contract_name}Contract\") | .contractAddress" "$broadcast_file" 2>/dev/null | head -n 1 || echo "") if [ -n "$address" ] && [ "$address" != "null" ]; then echo "$address" return 0 fi # Try to extract from returns address=$(jq -r ".returns.${contract_name,,}Address // .returns.${contract_name} // empty" "$broadcast_file" 2>/dev/null || echo "") if [ -n "$address" ] && [ "$address" != "null" ]; then echo "$address" return 0 fi return 1 } # Parse Deploy.s.sol output parse_deploy_script() { log "Parsing Deploy.s.sol deployment output..." # Check if broadcast log exists local deploy_script="Deploy.s.sol" local chain_id=138 # Extract WETH local weth_address=$(extract_from_broadcast "$deploy_script" "WETH" "$chain_id" || echo "") if [ -n "$weth_address" ]; then log "Found WETH address: $weth_address" jq ".weth = \"$weth_address\"" "$CONTRACT_ADDRESSES_FILE" > "${CONTRACT_ADDRESSES_FILE}.tmp" && mv "${CONTRACT_ADDRESSES_FILE}.tmp" "$CONTRACT_ADDRESSES_FILE" fi # Extract Multicall local multicall_address=$(extract_from_broadcast "$deploy_script" "Multicall" "$chain_id" || echo "") if [ -n "$multicall_address" ]; then log "Found Multicall address: $multicall_address" jq ".multicall = \"$multicall_address\"" "$CONTRACT_ADDRESSES_FILE" > "${CONTRACT_ADDRESSES_FILE}.tmp" && mv "${CONTRACT_ADDRESSES_FILE}.tmp" "$CONTRACT_ADDRESSES_FILE" fi # Extract Oracle Aggregator local oracle_address=$(extract_from_broadcast "$deploy_script" "Aggregator" "$chain_id" || echo "") if [ -z "$oracle_address" ]; then oracle_address=$(extract_from_broadcast "$deploy_script" "Oracle" "$chain_id" || echo "") fi if [ -n "$oracle_address" ]; then log "Found Oracle address: $oracle_address" jq ".oracle = \"$oracle_address\"" "$CONTRACT_ADDRESSES_FILE" > "${CONTRACT_ADDRESSES_FILE}.tmp" && mv "${CONTRACT_ADDRESSES_FILE}.tmp" "$CONTRACT_ADDRESSES_FILE" fi # Extract Proxy local proxy_address=$(extract_from_broadcast "$deploy_script" "Proxy" "$chain_id" || echo "") if [ -n "$proxy_address" ]; then log "Found Proxy address: $proxy_address" jq ".proxy = \"$proxy_address\"" "$CONTRACT_ADDRESSES_FILE" > "${CONTRACT_ADDRESSES_FILE}.tmp" && mv "${CONTRACT_ADDRESSES_FILE}.tmp" "$CONTRACT_ADDRESSES_FILE" fi } # Parse individual deployment scripts parse_individual_scripts() { log "Parsing individual deployment scripts..." local chain_id=138 # Parse WETH if [ -f "${BROADCAST_DIR}/DeployWETH.s.sol/${chain_id}/run-latest.json" ]; then local weth_address=$(extract_from_broadcast "DeployWETH.s.sol" "WETH" "$chain_id" || echo "") if [ -n "$weth_address" ]; then log "Found WETH address: $weth_address" jq ".weth = \"$weth_address\"" "$CONTRACT_ADDRESSES_FILE" > "${CONTRACT_ADDRESSES_FILE}.tmp" && mv "${CONTRACT_ADDRESSES_FILE}.tmp" "$CONTRACT_ADDRESSES_FILE" fi fi # Parse Multicall if [ -f "${BROADCAST_DIR}/DeployMulticall.s.sol/${chain_id}/run-latest.json" ]; then local multicall_address=$(extract_from_broadcast "DeployMulticall.s.sol" "Multicall" "$chain_id" || echo "") if [ -n "$multicall_address" ]; then log "Found Multicall address: $multicall_address" jq ".multicall = \"$multicall_address\"" "$CONTRACT_ADDRESSES_FILE" > "${CONTRACT_ADDRESSES_FILE}.tmp" && mv "${CONTRACT_ADDRESSES_FILE}.tmp" "$CONTRACT_ADDRESSES_FILE" fi fi # Parse Oracle if [ -f "${BROADCAST_DIR}/DeployOracle.s.sol/${chain_id}/run-latest.json" ]; then local oracle_address=$(extract_from_broadcast "DeployOracle.s.sol" "Aggregator" "$chain_id" || echo "") if [ -z "$oracle_address" ]; then oracle_address=$(extract_from_broadcast "DeployOracle.s.sol" "Oracle" "$chain_id" || echo "") fi if [ -n "$oracle_address" ]; then log "Found Oracle address: $oracle_address" jq ".oracle = \"$oracle_address\"" "$CONTRACT_ADDRESSES_FILE" > "${CONTRACT_ADDRESSES_FILE}.tmp" && mv "${CONTRACT_ADDRESSES_FILE}.tmp" "$CONTRACT_ADDRESSES_FILE" fi fi # Parse CCIP Router if [ -f "${BROADCAST_DIR}/DeployCCIPRouter.s.sol/${chain_id}/run-latest.json" ]; then local ccip_address=$(extract_from_broadcast "DeployCCIPRouter.s.sol" "CCIPRouter" "$chain_id" || echo "") if [ -n "$ccip_address" ]; then log "Found CCIP Router address: $ccip_address" jq ".ccipRouter = \"$ccip_address\"" "$CONTRACT_ADDRESSES_FILE" > "${CONTRACT_ADDRESSES_FILE}.tmp" && mv "${CONTRACT_ADDRESSES_FILE}.tmp" "$CONTRACT_ADDRESSES_FILE" fi fi } # Main function main() { log "Parsing deployment output..." # Initialize contract addresses file init_contract_addresses # Parse Deploy.s.sol if it exists if [ -f "${BROADCAST_DIR}/Deploy.s.sol/138/run-latest.json" ]; then parse_deploy_script fi # Parse individual scripts parse_individual_scripts # Display results log "Contract addresses:" cat "$CONTRACT_ADDRESSES_FILE" | jq '.' log "Parsing completed" } # Run main function main "$@"