Files
smom-dbis-138/scripts/deployment/build-gas-pmm-execution-bundle.sh
defiQUG f3d2961b97
Some checks failed
CI/CD Pipeline / Lint and Format (push) Failing after 46s
CI/CD Pipeline / Terraform Validation (push) Failing after 35s
CI/CD Pipeline / Kubernetes Validation (push) Successful in 37s
Deploy ChainID 138 / Deploy ChainID 138 (push) Failing after 1m50s
HYBX OMNL TypeScript & anchor / token-aggregation build + reconcile artifact (push) Failing after 2m19s
Validation / validate-genesis (push) Successful in 51s
Validation / validate-terraform (push) Failing after 39s
Validation / validate-kubernetes (push) Failing after 10s
CI/CD Pipeline / Solidity Contracts (push) Failing after 12m56s
Validation / validate-smart-contracts (push) Failing after 12s
CI/CD Pipeline / Security Scanning (push) Failing after 15m52s
Validation / validate-security (push) Failing after 10m59s
Validation / validate-documentation (push) Failing after 17s
Validate Token List / validate (push) Failing after 30s
OMNL reconcile anchor / Run omnl:reconcile and upload artifacts (push) Failing after 26s
Verify Deployment / Verify Deployment (push) Failing after 56s
feat: add hybx omnl stack and gas pmm tooling
2026-04-24 12:56:40 -07:00

405 lines
14 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
PROJECT_ROOT="$(cd "$REPO_ROOT/.." && pwd)"
BUNDLE_JSON="$REPO_ROOT/config/gas-pmm-execution-bundle.json"
OUT_DIR="$PROJECT_ROOT/reports/status"
OUT_JSON="$OUT_DIR/gas-pmm-execution-bundle-latest.json"
OUT_MD="$OUT_DIR/gas-pmm-execution-bundle-latest.md"
source "$REPO_ROOT/scripts/lib/deployment/dotenv.sh"
load_deployment_env --repo-root "$REPO_ROOT"
mkdir -p "$OUT_DIR"
json_escape() {
jq -Rn --arg v "${1:-}" '$v'
}
resolve_env_from_list() {
local joined="${1:-}"
local value=""
local key
[[ -z "$joined" ]] && return 0
IFS='|' read -r -a keys <<< "$joined"
for key in "${keys[@]}"; do
if [[ -n "${!key:-}" ]]; then
value="${!key}"
break
fi
done
printf '%s' "$value"
}
hex_to_addr() {
local value="${1#0x}"
[[ ${#value} -ge 40 ]] || return 1
printf '0x%s\n' "${value: -40}"
}
code_status() {
local rpc="$1"
local address="$2"
if [[ -z "$rpc" || -z "$address" ]]; then
printf 'missing'
return
fi
local code=""
code="$(timeout 12s cast code --rpc-url "$rpc" "$address" 2>/dev/null || true)"
if [[ -n "$code" && "$code" != "0x" ]]; then
printf 'has_code'
else
printf 'no_code'
fi
}
symbol_call() {
local rpc="$1"
local address="$2"
local value
value="$(timeout 8s cast call --rpc-url "$rpc" "$address" "symbol()(string)" 2>/dev/null || true)"
value="${value#\"}"
value="${value%\"}"
printf '%s' "$value"
}
normalize_key() {
printf '%s' "$1" | tr '[:lower:]- ' '[:upper:]__'
}
append_finding() {
local finding="$1"
if [[ -n "$FINDINGS_JOINED" ]]; then
FINDINGS_JOINED+="|$finding"
else
FINDINGS_JOINED="$finding"
fi
}
emit_findings_json() {
local joined="${1:-}"
if [[ -z "$joined" ]]; then
printf '[]'
return
fi
jq -Rn --arg joined "$joined" '$joined | split("|") | map(select(length > 0))'
}
rollout_order_json="$(jq -c '[.chains[] | {chainId, network}]' "$BUNDLE_JSON")"
generated_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
json_file="$(mktemp)"
md_file="$(mktemp)"
{
echo "{"
echo " \"generatedAt\": $(json_escape "$generated_at"),"
echo " \"bundle\": $(jq '.bundleName' "$BUNDLE_JSON"),"
echo " \"description\": $(jq '.description' "$BUNDLE_JSON"),"
echo " \"poolDefaults\": $(jq '.poolDefaults' "$BUNDLE_JSON"),"
echo " \"rolloutOrder\": $rollout_order_json,"
echo " \"chains\": ["
} >"$json_file"
{
echo "# Gas PMM Execution Bundle"
echo
echo "Generated at: \`$generated_at\`"
echo
echo "This bundle covers the remaining \`22\` planned gas-family DODO PMM rows across \`11\` public chains."
echo
echo "Execution posture:"
echo
echo "- Each chain has two target pools: wrapped-native self-quote and wrapped-native versus stable."
echo "- The current expected pool addresses are still scaffold slots, so \`no_code\` is the normal pre-deploy state."
echo "- Stable-quote pool creation needs a fresh \`STABLE_PRICE_1E18\` input at execution time."
echo "- Wrapped-native quote defaults in this bundle use the repo's canonical or documented live contracts instead of the old \`0xaa...\` placeholders."
echo "- The deploy step reuses the legacy integration constructor slots; those seed addresses are only deployment anchors, while the gas pairs themselves are created through generic \`createPool(...)\` calls."
} >"$md_file"
first_chain=1
chain_count=0
ready_count=0
blocked_count=0
while IFS= read -r chain_row; do
chain_id="$(jq -r '.chainId' <<<"$chain_row")"
network="$(jq -r '.network' <<<"$chain_row")"
chain_key="$(jq -r '.chainKey' <<<"$chain_row")"
rpc_envs_joined="$(jq -r '.rpcEnv | join("|")' <<<"$chain_row")"
integration_env="$(jq -r '.integrationEnv' <<<"$chain_row")"
dvm_envs_joined="$(jq -r '.dodoVendingMachineEnv | join("|")' <<<"$chain_row")"
rpc="$(resolve_env_from_list "$rpc_envs_joined")"
integration="${!integration_env:-}"
dvm="$(resolve_env_from_list "$dvm_envs_joined")"
base_symbol="$(jq -r '.baseToken.symbol' <<<"$chain_row")"
base_address="$(jq -r '.baseToken.address' <<<"$chain_row")"
wrapped_symbol="$(jq -r '.wrappedNativeQuote.symbol' <<<"$chain_row")"
wrapped_envs_joined="$(jq -r '.wrappedNativeQuote.env | join("|")' <<<"$chain_row")"
wrapped_default="$(jq -r '.wrappedNativeQuote.default' <<<"$chain_row")"
wrapped_note="$(jq -r '.wrappedNativeQuote.note' <<<"$chain_row")"
wrapped_address="$(resolve_env_from_list "$wrapped_envs_joined")"
wrapped_address="${wrapped_address:-$wrapped_default}"
stable_symbol="$(jq -r '.stableQuote.symbol' <<<"$chain_row")"
stable_envs_joined="$(jq -r '.stableQuote.env | join("|")' <<<"$chain_row")"
stable_default="$(jq -r '.stableQuote.default' <<<"$chain_row")"
stable_note="$(jq -r '.stableQuote.note' <<<"$chain_row")"
stable_address="$(resolve_env_from_list "$stable_envs_joined")"
stable_address="${stable_address:-$stable_default}"
integration_status="$(code_status "$rpc" "$integration")"
dvm_status="$(code_status "$rpc" "$dvm")"
base_status="$(code_status "$rpc" "$base_address")"
wrapped_status="$(code_status "$rpc" "$wrapped_address")"
stable_status="$(code_status "$rpc" "$stable_address")"
wrapped_pair_row="$(jq -c '.pairs[] | select(.quoteSymbol == $quote)' --arg quote "$wrapped_symbol" <<<"$chain_row")"
stable_pair_row="$(jq -c '.pairs[] | select(.quoteSymbol == $quote)' --arg quote "$stable_symbol" <<<"$chain_row")"
wrapped_pair_name="$(jq -r '.pair' <<<"$wrapped_pair_row")"
stable_pair_name="$(jq -r '.pair' <<<"$stable_pair_row")"
wrapped_pool_expected="$(jq -r '.expectedPoolAddress' <<<"$wrapped_pair_row")"
stable_pool_expected="$(jq -r '.expectedPoolAddress' <<<"$stable_pair_row")"
wrapped_pool_status="$(code_status "$rpc" "$wrapped_pool_expected")"
stable_pool_status="$(code_status "$rpc" "$stable_pool_expected")"
FINDINGS_JOINED=""
[[ -z "$rpc" ]] && append_finding "missing_rpc"
[[ "$dvm_status" != "has_code" ]] && append_finding "missing_or_invalid_dodo_vending_machine"
[[ "$base_status" != "has_code" ]] && append_finding "gas_mirror_base_missing_or_no_code"
[[ "$wrapped_status" != "has_code" ]] && append_finding "wrapped_native_quote_missing_or_no_code"
[[ "$stable_status" != "has_code" ]] && append_finding "stable_quote_missing_or_no_code"
if [[ -n "$integration" && "$integration_status" == "no_code" ]]; then
append_finding "integration_env_set_but_no_code"
fi
if [[ -z "$integration" || "$integration_status" != "has_code" ]]; then
append_finding "integration_needs_deploy"
fi
[[ "$wrapped_pool_status" != "has_code" ]] && append_finding "wrapped_native_pool_not_live"
[[ "$stable_pool_status" != "has_code" ]] && append_finding "stable_quote_pool_not_live"
readiness="blocked"
if [[ -n "$rpc" && "$dvm_status" == "has_code" && "$base_status" == "has_code" && "$wrapped_status" == "has_code" && "$stable_status" == "has_code" ]]; then
readiness="ready_for_execution"
fi
if [[ "$readiness" == "ready_for_execution" ]]; then
ready_count=$((ready_count + 1))
else
blocked_count=$((blocked_count + 1))
fi
chain_count=$((chain_count + 1))
normalized_chain_key="$(normalize_key "$chain_key")"
forge_profile="default"
if [[ "$chain_id" == "25" ]]; then
forge_profile="cronos_legacy"
fi
dvm_primary_env="$(jq -r '.dodoVendingMachineEnv[0]' <<<"$chain_row")"
deploy_cmd=$(cat <<EOF
cd $REPO_ROOT
DODO_VENDING_MACHINE_ADDRESS=\${$dvm_primary_env:-$dvm} \\
OFFICIAL_USDT_ADDRESS=$stable_address \\
OFFICIAL_USDC_ADDRESS=$wrapped_address \\
COMPLIANT_USDT_ADDRESS=$base_address \\
COMPLIANT_USDC_ADDRESS=$base_address \\
FOUNDRY_PROFILE=$forge_profile \\
forge script script/dex/DeployDODOPMMIntegration.s.sol:DeployDODOPMMIntegration \\
--rpc-url $rpc \\
--chain-id $chain_id \\
--broadcast \\
--private-key "\$PRIVATE_KEY" \\
-vvv
jq -r '.transactions[] | select(.transactionType=="CREATE" and .contractName=="DODOPMMIntegration") | .contractAddress' \\
broadcast/DeployDODOPMMIntegration.s.sol/$chain_id/run-latest.json
EOF
)
create_cmd=$(cat <<EOF
cd $REPO_ROOT
INTEGRATION_ADDRESS=\${$integration_env:-REPLACE_WITH_DEPLOYED_INTEGRATION}
LP_FEE_RATE=\${LP_FEE_RATE:-3}
SELF_QUOTE_PRICE_1E18=1000000000000000000
STABLE_PRICE_1E18=\${STABLE_PRICE_1E18:-REPLACE_WITH_LIVE_${normalized_chain_key}_GAS_PRICE_1E18}
K_FACTOR=\${K_FACTOR:-500000000000000000}
ENABLE_TWAP=\${ENABLE_TWAP:-true}
cast send "\$INTEGRATION_ADDRESS" \\
"createPool(address,address,uint256,uint256,uint256,bool)" \\
$base_address \\
$wrapped_address \\
"\$LP_FEE_RATE" \\
"\$SELF_QUOTE_PRICE_1E18" \\
"\$K_FACTOR" \\
"\$ENABLE_TWAP" \\
--rpc-url $rpc \\
--private-key "\$PRIVATE_KEY" \\
--legacy \\
-vv
cast send "\$INTEGRATION_ADDRESS" \\
"createPool(address,address,uint256,uint256,uint256,bool)" \\
$base_address \\
$stable_address \\
"\$LP_FEE_RATE" \\
"\$STABLE_PRICE_1E18" \\
"\$K_FACTOR" \\
"\$ENABLE_TWAP" \\
--rpc-url $rpc \\
--private-key "\$PRIVATE_KEY" \\
--legacy \\
-vv
EOF
)
verify_cmd=$(cat <<EOF
cast code --rpc-url $rpc $wrapped_pool_expected
cast code --rpc-url $rpc $stable_pool_expected
cast call --rpc-url $rpc \${$integration_env:-REPLACE_WITH_DEPLOYED_INTEGRATION} 'pools(address,address)(address)' $base_address $wrapped_address
cast call --rpc-url $rpc \${$integration_env:-REPLACE_WITH_DEPLOYED_INTEGRATION} 'pools(address,address)(address)' $base_address $stable_address
EOF
)
if [[ $first_chain -eq 0 ]]; then
echo "," >>"$json_file"
fi
first_chain=0
cat >>"$json_file" <<EOF
{
"chainId": $chain_id,
"network": $(json_escape "$network"),
"chainKey": $(json_escape "$chain_key"),
"rpc": $(json_escape "$rpc"),
"readiness": $(json_escape "$readiness"),
"blockingFindings": $(emit_findings_json "$FINDINGS_JOINED"),
"integrationEnv": $(json_escape "$integration_env"),
"integrationAddress": $(json_escape "$integration"),
"integrationStatus": $(json_escape "$integration_status"),
"dodoVendingMachine": {
"envCandidates": $(jq '.dodoVendingMachineEnv' <<<"$chain_row"),
"address": $(json_escape "$dvm"),
"status": $(json_escape "$dvm_status")
},
"baseToken": {
"symbol": $(json_escape "$base_symbol"),
"address": $(json_escape "$base_address"),
"status": $(json_escape "$base_status"),
"symbolOnChain": $(json_escape "$(symbol_call "$rpc" "$base_address")")
},
"wrappedNativeQuote": {
"symbol": $(json_escape "$wrapped_symbol"),
"envCandidates": $(jq '.wrappedNativeQuote.env' <<<"$chain_row"),
"address": $(json_escape "$wrapped_address"),
"default": $(json_escape "$wrapped_default"),
"status": $(json_escape "$wrapped_status"),
"symbolOnChain": $(json_escape "$(symbol_call "$rpc" "$wrapped_address")"),
"note": $(json_escape "$wrapped_note")
},
"stableQuote": {
"symbol": $(json_escape "$stable_symbol"),
"envCandidates": $(jq '.stableQuote.env' <<<"$chain_row"),
"address": $(json_escape "$stable_address"),
"default": $(json_escape "$stable_default"),
"status": $(json_escape "$stable_status"),
"symbolOnChain": $(json_escape "$(symbol_call "$rpc" "$stable_address")"),
"note": $(json_escape "$stable_note")
},
"pairs": [
{
"pair": $(json_escape "$wrapped_pair_name"),
"expectedPoolAddress": $(json_escape "$wrapped_pool_expected"),
"poolCodeStatus": $(json_escape "$wrapped_pool_status"),
"executionPriceMode": "self_quote_fixed_1e18"
},
{
"pair": $(json_escape "$stable_pair_name"),
"expectedPoolAddress": $(json_escape "$stable_pool_expected"),
"poolCodeStatus": $(json_escape "$stable_pool_status"),
"executionPriceMode": "live_stable_spot_required"
}
],
"commands": {
"deployIntegration": $(json_escape "$deploy_cmd"),
"createPools": $(json_escape "$create_cmd"),
"verifyPools": $(json_escape "$verify_cmd")
}
}
EOF
{
echo
echo "## $network ($chain_id)"
echo
echo "Readiness: \`$readiness\`"
echo
echo "| Item | Address | Status |"
echo "| --- | --- | --- |"
echo "| DODO vending machine | \`${dvm:-unset}\` | \`$dvm_status\` |"
echo "| Integration env \`$integration_env\` | \`${integration:-unset}\` | \`$integration_status\` |"
echo "| $base_symbol | \`$base_address\` | \`$base_status\` |"
echo "| $wrapped_symbol | \`$wrapped_address\` | \`$wrapped_status\` |"
echo "| $stable_symbol | \`$stable_address\` | \`$stable_status\` |"
echo "| Pool $wrapped_pair_name | \`$wrapped_pool_expected\` | \`$wrapped_pool_status\` |"
echo "| Pool $stable_pair_name | \`$stable_pool_expected\` | \`$stable_pool_status\` |"
echo
echo "Blocking findings:"
if [[ -n "$FINDINGS_JOINED" ]]; then
IFS='|' read -r -a findings_array <<< "$FINDINGS_JOINED"
for finding in "${findings_array[@]}"; do
echo "- \`$finding\`"
done
else
echo "- None"
fi
echo
echo "Quote token notes:"
echo
echo "- $wrapped_symbol: $wrapped_note"
echo "- $stable_symbol: $stable_note"
echo
echo "Deploy integration:"
echo
echo '```bash'
echo "$deploy_cmd"
echo '```'
echo
echo "Create pools:"
echo
echo '```bash'
echo "$create_cmd"
echo '```'
echo
echo "Verify pools:"
echo
echo '```bash'
echo "$verify_cmd"
echo '```'
} >>"$md_file"
done < <(jq -c '.chains[]' "$BUNDLE_JSON")
{
echo
echo " ],"
echo " \"summary\": {"
echo " \"chains\": $chain_count,"
echo " \"pairs\": $((chain_count * 2)),"
echo " \"readyForExecution\": $ready_count,"
echo " \"blocked\": $blocked_count"
echo " }"
echo "}"
} >>"$json_file"
jq . "$json_file" >"$OUT_JSON"
mv "$md_file" "$OUT_MD"
rm -f "$json_file"
echo "Wrote:"
echo " $OUT_JSON"
echo " $OUT_MD"