Five contracts form the mandate court. MandateRegistry and AgentRegistry hold the registry state. AgentBonding holds collateral. ActionGate is the enforcement hub. TraceCommitment is the immutable evidence log.
DeploymentContract addresses
0G MainnetChain ID 16661 · 0G Mainnet · Deployed on 0G Mainnet
MandateRegistryMandateRegistry
Stores mandate definitions. Each mandate defines the asset, max amount, allowed targets, blocked recipients, and action type rules. DAO-owned.
Methods
createMandate(name, asset, maxAmount, targets[], blocked[], allowedActions[], forbiddenActions[])→ uint256 mandateId
Caller becomes the DAO owner of the mandate.setActive(mandateId, active)
Only DAO owner. Pauses or restores a mandate.requireActive(mandateId)→ Mandate memory
Reverts MandateInactive if mandate is paused.allowedTargets(mandateId, target)→ bool
View: is this address an allowed target?blockedRecipients(mandateId, recipient)→ bool
View: is this address a blocked recipient?allowedActionTypes(mandateId, actionType)→ bool
View: is this bytes32 action type allowed?forbiddenActionTypes(mandateId, actionType)→ bool
View: is this bytes32 action type forbidden?Events
MandateCreatedmandateId (indexed), dao (indexed), name, asset, maxAmount
TargetAllowedmandateId (indexed), target (indexed), allowed
RecipientBlockedmandateId (indexed), recipient (indexed), blocked
ActionTypeRulemandateId (indexed), actionType (indexed), allowed, forbidden
AgentRegistryAgentRegistry
Agent passport registry. Each registered agent gets a uint256 token ID (agentId). Caller becomes agent owner.
Methods
registerAgent(label, metadataURI)→ uint256 agentId
Assigns sequential agentId. Caller is owner.setActive(agentId, active)
Only agent owner. Deactivates an agent — blocks new proposals.ownerOf(agentId)→ address
Reverts InvalidAgent if not registered.isActive(agentId)→ bool
Reverts InvalidAgent if not registered.Events
AgentRegisteredagentId (indexed), owner (indexed), label, metadataURI
AgentStatusChangedagentId (indexed), active
AgentBondingAgentBonding
Holds agent bond balances and compliance scores. Only ActionGate can slash or reward. Bond is ETH posted by the agent owner.
Methods
postBond(agentId)
payable. Caller must be agent owner. Initialises compliance score to 800 on first bond.slash(agentId, amount)→ uint256 slashed
Only ActionGate. Burns up to slashAmount from bond. Returns actual wei slashed.rewardApproval(agentId)
Only ActionGate. Score +5 per approved action, capped at 1000.setActionGate(actionGate)
One-time setter. Reverts if already set.bondBalance(agentId)→ uint256
View: current bond balance in wei.complianceScore(agentId)→ uint256
View: current compliance score (0–1000).Events
BondPostedagentId (indexed), funder (indexed), amount, newBalance
AgentSlashedagentId (indexed), amount, newBalance
ComplianceScoreUpdatedagentId (indexed), oldScore, newScore
ActionGateSetactionGate (indexed)
Constants
STARTING_SCORE800
APPROVAL_REWARD5
SLASH_PENALTY200
ActionGateActionGate
Central enforcement hub. Evaluates action proposals against mandate clauses, commits traces, rewards or slashes agents, emits verdict events.
Methods
submitAction(proposal)→ (Verdict verdict, uint256 reasonBitmap, uint256 slashed)
Evaluates all 6 mandate clauses. Commits trace. Approved: score +5. Rejected: bond slashed, bitmap set.preview(proposal)→ (Verdict verdict, uint256 reasonBitmap)
View — simulate evaluation without state changes.evaluate(proposal, mandate)→ uint256 reasonBitmap
Public view — isolated clause evaluation. Returns 0 if all clauses pass.Events
ActionApprovedactionId (indexed), agentId (indexed), mandateId (indexed), traceRoot, storageURI
ActionRejectedactionId (indexed), agentId (indexed), mandateId (indexed), traceRoot, storageURI, reasonBitmap, slashed
Constants
VIOLATION_AMOUNT1 << 0
VIOLATION_TARGET1 << 1
VIOLATION_RECIPIENT1 << 2
VIOLATION_ACTION_NOT_ALLOWED1 << 3
VIOLATION_ACTION_FORBIDDEN1 << 4
VIOLATION_ASSET1 << 5
TraceCommitmentTraceCommitment
Immutable on-chain trace registry. Stores traceRoot + storageURI + verdict for every committed action. Each actionId can only be committed once.
Methods
commitTrace(actionId, agentId, mandateId, traceRoot, storageURI, verdict)
Only ActionGate. Reverts TraceAlreadyCommitted if actionId already committed.getCommitment(actionId)→ Commitment memory
View — retrieve full commitment record by actionId.setActionGate(actionGate)
One-time setter.Events
TraceCommittedactionId (indexed), agentId (indexed), mandateId (indexed), traceRoot, storageURI, verdict
Deployment modelDeployment order and wiring
01Deploy MandateRegistry
No dependencies.
02Deploy AgentRegistry
No dependencies.
03Deploy AgentBonding(agentRegistry)
Depends on AgentRegistry address.
04Deploy TraceCommitment
No constructor dependencies.
05Deploy ActionGate(mandateRegistry, agentRegistry, bonding, traceCommitment)
Central hub — depends on all four.
06AgentBonding.setActionGate(actionGate)
One-time wiring. Reverts if called again.
07TraceCommitment.setActionGate(actionGate)
One-time wiring. Reverts if called again.