Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions audit-prep/06-deployment-manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ The machine-readable record of every deployment, on all chains, is [`deployments
| `stealth-registry` | Frozen/no upgrade path. | Verify user mappings cannot be changed by maintainers. |
| `stealth-sender` | 3-of-5 multisig, 7-day timelock for upgrades, pause mechanism for emergencies. | Verify pause and upgrade powers are scoped and observable. |
| `wraith-names` | 3-of-5 multisig, 7-day timelock, eventually renounceable. | Verify state migration and replay storage safety under upgrades. |
| `stealth-splitter` | Frozen/no upgrade path. | Verify no admin role, no pause, no upgrade interface; `init` only stores the announcer once. |
| `stealth-batch-sender` | No upgrade path. Pause admin set once by `init`; signer-rotation multisig set once by `init_multisig`, 7-day timelock. | Verify the multisig can only rotate its own signers and the pause admin can only pause and unpause `batch_send`. |

Planned guardians from `stellar/GOVERNANCE.md`:

Expand Down
35 changes: 31 additions & 4 deletions audit-prep/DEPLOYMENT_MANIFEST.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ soroban contract invoke \
**Purpose:** Batch operations
**Dependencies:** stealth-announcer
**Init Required:** Yes
**Configuration:** Announcer address
**Configuration:** Pause admin address, announcer address, optional asset policy

```bash
soroban contract deploy \
Expand All @@ -173,12 +173,26 @@ soroban contract deploy \

# Returns: CONTRACT_ID_BATCH_SENDER

# Neither `init` nor `init_multisig` checks the caller (see AUTHORIZATION_MATRIX.md):
# the first call sets the value for good, so run both right after deploy.

# `admin` is the pause admin. It cannot be changed later.
soroban contract invoke \
--id CONTRACT_ID_BATCH_SENDER \
--network mainnet \
--source [DEPLOYER_SECRET_KEY] \
-- init \
--admin [PAUSE_ADMIN_ADDRESS] \
--announcer CONTRACT_ID_ANNOUNCER

# Signer set for signer rotation only (see Governance Configuration).
soroban contract invoke \
--id CONTRACT_ID_BATCH_SENDER \
--network mainnet \
--source [DEPLOYER_SECRET_KEY] \
-- init_multisig \
--signers '[SIGNER_ADDRESSES]' \
--threshold [THRESHOLD]
```

---
Expand All @@ -197,6 +211,19 @@ soroban contract invoke \
- No upgrade mechanism
- Immutable forever

**stealth-splitter:**
- No admin role
- No pause
- No upgrade mechanism
- `init` stores the announcer address once; a second call returns `AlreadyInitialized`

### Non-Upgradeable Contracts (Pause Admin)

**stealth-batch-sender:**
- No upgrade mechanism
- **Pause admin:** one address, set once by `init`. `pause` and `unpause` stop or resume `batch_send` and nothing else. No function changes the admin after `init`.
- **Governance multisig:** the signer set and threshold are set once by `init_multisig`. The multisig only rotates its own signer set: a current signer proposes, a quorum of current signers approves, and after a 7-day timelock (`ROTATION_TIMELOCK_SECS`, ledger timestamp) a signer executes; any signer can cancel a pending rotation. It cannot pause the contract, change the pause admin, or upgrade the code.

### Upgradeable Contracts (Multisig + Timelock)

**stealth-sender:**
Expand Down Expand Up @@ -366,7 +393,7 @@ A keeper bot will monitor and extend storage rent:
### Emergency Procedures

**Scenario 1: Critical Vulnerability Discovered**
1. Pause affected contracts (if upgradeable)
1. Pause affected contracts that have a pause function
2. Notify community via status page
3. Develop and test fix
4. Deploy fix via upgrade process
Expand All @@ -379,7 +406,7 @@ A keeper bot will monitor and extend storage rent:
4. Ensure adequate treasury funding

**Scenario 3: Admin Key Compromise**
1. Emergency multisig rotation
1. Emergency multisig rotation. The stealth-batch-sender pause admin cannot be replaced: if that key is compromised, deploy a new batch sender and move integrations to it.
2. Audit all recent admin actions
3. Notify community
4. Investigate compromise vector
Expand Down Expand Up @@ -436,7 +463,7 @@ sha256sum deployed.wasm

If critical issues are discovered post-deployment:

### For Frozen Contracts (announcer, registry)
### For Frozen and Non-Upgradeable Contracts (announcer, registry, splitter, batch sender)
**No rollback possible.** Must deploy new version with different address.

**Mitigation:**
Expand Down
4 changes: 2 additions & 2 deletions audit-prep/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,12 @@ contracts/

5. **stealth-splitter** (~300 LOC)
- Payment splitting across multiple recipients
- **Status:** Upgradeable
- **Status:** Frozen (no upgrade path, no admin)
- **Blast Radius:** High (handles user assets)

6. **stealth-batch-sender** (~150 LOC)
- Optimized batch operations
- **Status:** Upgradeable
- **Status:** Non-upgradeable (pause admin and a signer-rotation multisig, see DEPLOYMENT_MANIFEST.md)
- **Blast Radius:** High (handles user assets)

## Audit Timeline
Expand Down
4 changes: 2 additions & 2 deletions stellar/MIGRATION_V0_TO_V1.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ Wraith Protocol contract architecture separates immutable core components (froze
| `stealth-announcer` | **Frozen (Immutable)** | None | No | Stateless (Events Only) |
| `stealth-registry` | **Frozen (Immutable)** | None | No | `persistent()` with TTL auto-extension |
| `stealth-sender` | **Timelocked + Multisig** | 3-of-5 Multisig | **Yes** (`DataKey::Paused`) | `instance()` for config; token transfers |
| `stealth-batch-sender` | **Timelocked + Multisig** | 3-of-5 Multisig | **Yes** (`DataKey::Paused`) | `instance()` for config |
| `stealth-splitter` | **Timelocked + Multisig** | 3-of-5 Multisig | **Yes** (`DataKey::Paused`) | `persistent()` for split definitions |
| `stealth-batch-sender` | **Non-upgradeable (Pause Admin)** | None | **Yes** (`DataKey::Paused`, pause admin) | `instance()` for config |
| `stealth-splitter` | **Frozen (Immutable)** | None | No | `instance()` for split definitions |
| `stealth-vault` | **Timelocked + Multisig** | 3-of-5 Multisig | **Yes** (`DataKey::Paused`) | `persistent()` for time-locked deposits |
| `wraith-names` | **Timelocked + Multisig** | 3-of-5 Multisig | **Yes** (`DataKey::Paused`) | `persistent()` for name & reverse records |
| `wraith-asset-policy` | **Admin Managed** | Admin Address | No | `instance()` admin, `persistent()` allowlist |
Expand Down
Loading