seal. Docs Try the sandbox ↗
Mainnet is not yet live. Explore with demo funds or test tokens. Review status ↗

Guardian multisig

One canonical Safe is the guardian: it administers asset admission, swap routes and capped fees, and receives all accrued yield, deposit, withdrawal, swap and margin fees. Safe 1.4.1 and 1.5.0 are supported, with a threshold of at least two. The fresh-Safe helper deploys a 1.4.1 wallet starting at 2-of-3. No SEAL token is required.

The guardian address is immutable. Owners and the threshold can change through transactions approved by the Safe's existing quorum. Choose and verify owners out of band, keep keys under independent custody and rehearse losing one signer. These scripts never generate production keys. SEAL verifier routes are fixed permanently.

Configured guardian

The Ethereum and Base profiles set authorities.guardian to 0x4aD16f55fD27d488e0fF9Eb95Be15F4482d839a9. This is the protocol administration role, exposed as GUARDIAN() by the contracts. This same address receives every protocol fee. Editing these profiles sets the authority for future deployments; the pool's guardian is immutable after construction.

A read-only Ethereum check at block 26255939 found a 4-of-6 Safe v1.5.0, with singleton 0xFf51A5898e281Db6DfC7855790607438dF2ca44b and fallback handler 0x3EfCBb83A4A7AfcB4F68D501E2c2203a38be77f4. Deployment and monitoring validate the canonical proxy and singleton runtime hashes, require no modules, transaction guard or module guard, and allow either no fallback handler or the pinned 1.5.0 compatibility handler. The 1.5.0 singleton and handler pins come from Safe's deployment registry.

Only the guardian address is configured. Guardian owners and the exact threshold are read from the Safe; there is no multisigs.guardian signer list or fixed 4-of-6 requirement. Authorized signer changes and threshold changes remain valid as long as the Safe still requires at least two signatures. The profile's multisigs.version describes the fresh-Safe helper's 1.4.1 deployment template, not the version of an existing guardian.

At Base block 52988249, this address had no deployed code. The Base setting is a planned address and requires a separately deployed and verified Safe on Base. An Ethereum Safe cannot directly call Base contracts; Safe's multi-chain deployment flow can deploy a compatible Safe at the same address on another network. Recheck both networks before deployment.

Prepare a fresh 2-of-3 Safe

Create a local signer JSON file with three actual public addresses:

{
  "guardian": ["<address D>", "<address E>", "<address F>"]
}

Then, from the repository root:

node --experimental-strip-types scripts/ops/setup-native-safes.ts \
  seal-pool/packages/contracts/deployments/profiles/base.json \
  /absolute/path/to/signers.json \
  seal-pool/packages/contracts/deployments/fresh-safe-profile.json

Use the Ethereum profile for Ethereum. The tool validates all three entries, rejects duplicate owners within a role, chooses a fresh random deployment salt, and resets authority addresses. It refuses to overwrite the output. No RPC request, signature or transaction is sent.

From seal-pool/packages/contracts, set the profile/output paths and a funded deployer address, then simulate the existing factory script:

export SEAL_NATIVE_PROFILE="$PWD/deployments/fresh-safe-profile.json"
export SEAL_SAFE_OUTPUT="$PWD/deployments/fresh-safe-addresses.json"
export SEAL_DEPLOYER="<funded deployment wallet address>"
forge script script/DeploySafes.s.sol:DeploySafes \
  --rpc-url "$SEAL_RPC_URL" --sender "$SEAL_DEPLOYER"

Review the simulated addresses, owners, thresholds, target chain and factory/singleton hashes. To actually deploy, run the same command with an explicitly selected signer (for example --account <local-keystore-name>) and --broadcast. Keep signing credentials outside profiles and source control. Reusing the exact profile salt/initializer predicts the same addresses; use a newly prepared profile for a fresh Safe.

DeploySafes.s.sol checks the guardian configuration before starting deployment. The proxy is initialized in its creation transaction, without setup delegatecalls, modules, guard, fallback handler, payment or temporary deployer ownership. Ethereum and Base are the only supported production targets. If a network failure interrupts submission, inspect receipts before retrying.

After successful receipts, verify the canonical Safe onchain and copy its address into the reviewed profile's authorities.guardian. Signer arrays are deployment inputs for a fresh Safe, not permanent owner pins. The checked-in profiles are not deployment-ready; see the configured guardian's qualification status above.

Add, remove or replace signers

Safe already implements adding owners, removing owners and replacing them. The existing owners approve a Safe self-call. A new signer cannot grant itself access, and one signer cannot make a change under a 2-of-3 threshold.

For a deployed protocol, create a local request such as:

{
  "role": "guardian",
  "ownerChange": {
    "action": "add",
    "owner": "<new signer address>",
    "threshold": 2
  }
}

Prepare it without signing or publishing:

node --experimental-strip-types scripts/ops/prepare-native-safe.ts \
  /absolute/path/to/client-config.json \
  /absolute/path/to/reviewed-profile.json \
  /absolute/path/to/owner-change.json \
  /absolute/path/to/unsigned-owner-change.json

Other actions are remove with owner and the resulting threshold, replace with owner and replacement, or threshold with the new number. The script reads the live owner-list order and nonce, derives removal/replacement's predecessor, validates the canonical wallet configuration, and compares the local transaction hash with Safe's own hash. Signers must review and execute the resulting transaction separately. Re-prepare if the owner list, chain or nonce changes.

Adding an owner at threshold two makes a 2-of-4 Safe. Removing one from 2-of-3 leaves 2-of-2; for a lost signer, a direct replacement keeps 2-of-3. The preparation helper refuses thresholds below two. Safe itself permits other thresholds through an authorized transaction; this is an operational policy, not a custom restriction on Safe. Guardian signer changes need no profile edit.

Before the pool exists, the same owner methods can be reviewed and executed using Safe's own interface. The SEAL administration preparer additionally requires a healthy deployed protocol.

Fee collection and deployment compatibility

Anyone can trigger accrued fee collection, but the recipient is always GUARDIAN(). Claims cannot redirect funds or sweep user backing. A failed fee transfer rolls back the claim without blocking user exits or margin closes.

The single-guardian contracts remove the separate fee-recipient constructor argument, getter and rotation functions. They require fresh deployments and matching client artifacts. Historical deployment records and verified source inputs describe the contracts actually deployed at that time; editing profiles does not change their onchain behavior.