Add MEV post-deploy config patch helper

This commit is contained in:
defiQUG
2026-04-13 15:59:41 -07:00
parent f04b860763
commit 0c58ccaf6c
2 changed files with 228 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
CONFIG_DEFAULT="$ROOT/MEV_Bot/mev-platform/config.toml"
ARTIFACT_PATH="${MEV_EXECUTION_DEPLOY_ARTIFACT:-}"
CONFIG_PATH="${MEV_CONFIG_PATH:-$CONFIG_DEFAULT}"
CHAIN_ID_OVERRIDE="${MEV_CHAIN_ID:-}"
UNISWAP_V2_ROUTER="${MEV_UNISWAP_V2_ROUTER:-}"
SUSHISWAP_ROUTER="${MEV_SUSHISWAP_ROUTER:-}"
RELAY_URL_OVERRIDE="${MEV_RELAY_URL:-}"
APPLY=0
usage() {
cat <<'EOF'
Usage: apply-mev-execution-config-from-artifact.sh [options]
Reads a deployment artifact created by deploy-mev-execution-contracts.sh and
patches the target MEV config with:
- chains.<id>.execution.executor_contract
- chains.<id>.execution.flash_loan_provider
- chains.<id>.factories[].router for uniswap_v2 and sushiswap
- optional relay_url override
Defaults to dry-run and prints a unified diff. Use --apply to modify the file.
Options:
--artifact PATH Required deployment artifact JSON
--config PATH Config TOML to patch (default: MEV_Bot/mev-platform/config.toml)
--chain ID Override chain id from artifact
--uniswap-v2-router ADR Router address for the uniswap_v2 factory entry
--sushiswap-router ADR Router address for the sushiswap factory entry
--relay-url URL Optional relay_url override
--apply Write changes in place
-h, --help Show this help
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--artifact)
ARTIFACT_PATH="$2"
shift 2
;;
--config)
CONFIG_PATH="$2"
shift 2
;;
--chain)
CHAIN_ID_OVERRIDE="$2"
shift 2
;;
--uniswap-v2-router)
UNISWAP_V2_ROUTER="$2"
shift 2
;;
--sushiswap-router)
SUSHISWAP_ROUTER="$2"
shift 2
;;
--relay-url)
RELAY_URL_OVERRIDE="$2"
shift 2
;;
--apply)
APPLY=1
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&2
exit 2
;;
esac
done
require_cmd() {
command -v "$1" >/dev/null 2>&1 || {
echo "Required command missing: $1" >&2
exit 2
}
}
require_cmd python3
require_cmd jq
require_cmd diff
if [[ -z "$ARTIFACT_PATH" ]]; then
echo "--artifact is required" >&2
exit 2
fi
if [[ ! -f "$ARTIFACT_PATH" ]]; then
echo "Artifact file not found: $ARTIFACT_PATH" >&2
exit 2
fi
if [[ ! -f "$CONFIG_PATH" ]]; then
echo "Config file not found: $CONFIG_PATH" >&2
exit 2
fi
if [[ -z "$UNISWAP_V2_ROUTER" || -z "$SUSHISWAP_ROUTER" ]]; then
echo "Both --uniswap-v2-router and --sushiswap-router are required" >&2
exit 2
fi
TMP_OUT="$(mktemp)"
cleanup() {
rm -f "$TMP_OUT"
}
trap cleanup EXIT
python3 - "$ARTIFACT_PATH" "$CONFIG_PATH" "$TMP_OUT" "$CHAIN_ID_OVERRIDE" "$UNISWAP_V2_ROUTER" "$SUSHISWAP_ROUTER" "$RELAY_URL_OVERRIDE" <<'PY'
import json
import re
import sys
from pathlib import Path
artifact_path = Path(sys.argv[1])
config_path = Path(sys.argv[2])
output_path = Path(sys.argv[3])
chain_override = sys.argv[4]
uniswap_router = sys.argv[5]
sushiswap_router = sys.argv[6]
relay_override = sys.argv[7]
artifact = json.loads(artifact_path.read_text())
text = config_path.read_text()
chain_id = int(chain_override or artifact["chain_id"])
executor_contract = artifact["executor_contract"]
flash_loan_provider = artifact["flash_loan_provider"]
chain_marker = f"[chains.{chain_id}.execution]"
if chain_marker not in text:
raise SystemExit(f"Missing execution section for chain {chain_id} in {config_path}")
def replace_line(pattern: str, replacement: str, content: str, *, required: bool = True) -> str:
updated, count = re.subn(pattern, replacement, content, flags=re.MULTILINE)
if required and count == 0:
raise SystemExit(f"Pattern not found: {pattern}")
return updated
text = replace_line(
rf'(^\s*executor_contract\s*=\s*")[^"]*(")',
rf'\g<1>{executor_contract}\g<2>',
text,
)
text = replace_line(
rf'(^\s*flash_loan_provider\s*=\s*")[^"]*(")',
rf'\g<1>{flash_loan_provider}\g<2>',
text,
)
if relay_override:
text = replace_line(
rf'(^\s*relay_url\s*=\s*")[^"]*(")',
rf'\g<1>{relay_override}\g<2>',
text,
)
def patch_factory_router(content: str, dex: str, router: str) -> str:
pattern = rf'(\{{\s*dex\s*=\s*"{re.escape(dex)}"\s*,\s*address\s*=\s*"[^"]*"\s*,)([^}}]*)\}}'
def repl(match: re.Match[str]) -> str:
prefix = match.group(1)
middle = match.group(2)
if 'router =' in middle:
middle = re.sub(r'router\s*=\s*"[^"]*"', f'router = "{router}"', middle)
else:
middle = f' router = "{router}",' + middle
return f"{prefix}{middle}}}"
updated, count = re.subn(pattern, repl, content)
if count == 0:
raise SystemExit(f"Factory entry for dex {dex} not found")
return updated
text = patch_factory_router(text, "uniswap_v2", uniswap_router)
text = patch_factory_router(text, "sushiswap", sushiswap_router)
output_path.write_text(text)
PY
echo "Prepared MEV execution config patch"
echo "artifact: $ARTIFACT_PATH"
echo "config: $CONFIG_PATH"
echo "chain: ${CHAIN_ID_OVERRIDE:-$(jq -r '.chain_id' "$ARTIFACT_PATH")}"
echo ""
if diff -u "$CONFIG_PATH" "$TMP_OUT"; then
echo "No changes needed."
fi
if [[ "$APPLY" -eq 1 ]]; then
cp "$CONFIG_PATH" "${CONFIG_PATH}.bak.$(date +%Y%m%d_%H%M%S)"
cp "$TMP_OUT" "$CONFIG_PATH"
echo ""
echo "Applied changes to $CONFIG_PATH"
fi