Generic ops guide. Fill addresses from your own deploys — never commit real private keys.
| Role | Env | Purpose |
|---|---|---|
| Deployer | DEPLOYER_PRIVATE_KEY |
Broadcasts deploys; temporary initial owner until multisig accept |
| Agent | AGENT_PRIVATE_KEY / AGENT_ADDRESS |
Hot key that signs swaps / RFQ |
| Owner multisig | OWNER_MULTISIG_ADDRESS |
On-chain 2-of-3 MultiSigOwner — PolicyExecutor owner |
| Owner signers | OWNER_SIGNER_{1,2,3}_* |
EOAs that propose/confirm multisig txs |
Never put any of these under NEXT_PUBLIC_*. Do not sync signer private keys to a production host.
- PolicyExecutor:
NEXT_PUBLIC_POLICY_EXECUTOR_ADDRESS/0xYOUR_POLICY_EXECUTOR - Previous PolicyExecutor (optional migrate):
NEXT_PUBLIC_OLD_POLICY_EXECUTOR_ADDRESS - MultiSigOwner (2-of-3):
OWNER_MULTISIG_ADDRESS/0xYOUR_MULTISIG - Signers:
OWNER_SIGNER_1/2/3_ADDRESSin local.envonly - Threshold: typically
2
- Immediate
setAgent/setAllowedTargetare removed from bytecode. Allowlist bootstrap is constructor-only (bootstrapTargets[]); later admin changes usequeue*+execute*afteradminDelay. - Vault allowlist is separate:
allowedVaults/queueSetAllowedVault/executeSetAllowedVault. ERC-4626 vaults must not be inallowedTargets(that path is for call targets and can drain custodied ERC20s). - RFQ sell settlement must call
consumeRfqTokenLockafter Permit2 pull sotokenAccountedrealigns.
- Propose (any signer):
MultiSigOwner.submitTransaction(policy, 0, abi.encodeCall(...)) - Confirm (second signer):
confirmTransaction(txId)until threshold - Execute:
executeTransaction(txId)
pnpm exec tsx apps/web/scripts/whitelist-ur-targets.ts
# wait adminDelay (default 1 day)
WHITELIST_PHASE=execute pnpm exec tsx apps/web/scripts/whitelist-ur-targets.tsPolicyExecutor exposes depositErc4626 / redeemErc4626 for Morpho VaultV2 yield.
- USDG (Robinhood Chain):
0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168 - Morpho Steakhouse USDG vault (public third-party):
0xBeEff033F34C046626B8D0A041844C5d1A5409dd - Bootstrap the vault via
bootstrapVaults[]at deploy (not viaallowedTargets). - Never gate on
maxDeposit/maxMint(VaultV2 often returns 0). Size withpreviewDeposit/previewRedeemand passminShares/minAssets. - Keep
ENABLE_YIELD_ROUTING=falseuntil you deploy an upgraded PolicyExecutor and pass a small deposit/redeem smoke test.
- User:
setPaused(true)on their vault - Operator: set
ENABLE_UNISWAPX_ROUTING=falseto disable RFQ - Operator: set
ENABLE_YIELD_ROUTING=falseto stop yield routing - Owner (via 2-of-3): queue
setAgentor allowlist changes after delay - Session: rotate
SESSION_SECRET
- Keep at least two signer keys safe and gas-funded.
- Prefer hardware / offline storage for signers; agent key is the only hot key on the app host.