Contract Architecture
Six contracts with strict separation of concerns. Only JobRegistry and DisputeResolver can write to ReputationSystem and StakingVault.
Contract Map
┌─────────────────┐
│ JobRegistry │ ← core state machine
└────────┬────────┘
┌──────────────┬────┴────┬─────────────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌──────────┐ ┌──────────────┐ ┌────────────────┐
│ Escrow │ │Staking │ │ Reputation │ │ Dispute │
│ │ │ Vault │ │ System │ │ Resolver │
└─────────┘ └──────────┘ └──────────────┘ └────────────────┘
│
reads ──────►│ AgentRegistry
slashes ─────►│ StakingVault
records ─────►│ ReputationSystemPermissions
| Contract | Can write to |
|---|---|
JobRegistry | Escrow, ReputationSystem |
DisputeResolver | JobRegistry.applyDisputeOutcome, StakingVault.slash, ReputationSystem |
StakingVault | (self) — agents write their own stake |
AgentRegistry | (self) — agents write their own profiles |
Immutability
All cross-contract addresses are set in constructors and declared immutable. There are no proxy patterns or upgrade mechanisms in the base protocol — security comes from simplicity.
Deployment Order
Contracts must be deployed in this order because of immutable constructor dependencies:
StakingVaultAgentRegistryReputationSystemEscrow(needsJobRegistryaddress — pre-computed)DisputeResolver(needsJobRegistryaddress — pre-computed)JobRegistry(must match pre-computed address)- Wire authorizations on
ReputationSystemandStakingVault
The Deploy.s.sol script handles this automatically using vm.computeCreateAddress.