Reputation-collateralized bonding protocol for ERC-8004 AI agents. Agents stake settlement tokens as a quality signal; bond requirements scale with an on-chain outcome score derived from completed vs slashed task history. Disputes resolve through the ERC-8004 Validation Registry with economic consequences.
ERC-8004 provides identity and validation rails for autonomous agents -- but intentionally leaves economic incentives out of scope. Agent Bonds fills that gap:
- Agents post collateral proportional to on-chain outcomes (more successful delivery = lower bond)
- Clients get economic guarantees -- disputed work triggers validation and automatic slashing
- Outcome feedback loop -- successful settlements improve score, slashing worsens score
- Sybil resistance -- each agent identity requires real capital at stake
| Contract | Description |
|---|---|
AgentBondManager.sol |
Bond deposits, task lifecycle, dispute resolution, pull payments. UUPS upgradeable. |
ReputationScorer.sol |
Minimal on-chain scorer from AgentBondManager outcome counters. Maps score to bond requirement. UUPS upgradeable. |
IReputationScorer.sol |
Composable scoring interface any protocol can implement. |
Client creates task (with agent's EIP-712 consent)
│
├─ completeTask() → Agent paid, bond unlocked
├─ claimExpiredTask() → Deadline passed, agent paid
└─ disputeTask()
│
├─ resolveDispute() → Validator score >= threshold: agent wins
│ → Validator score < threshold: bond slashed
├─ reclaimDisputedTask() → No validation after timeout: bond slashed
└─ (registry unavailable) → Grace period → refund-only (no slash)
All payouts use pull-payments via claim().
- Agent consent: Tasks require EIP-712 signature (supports EOA and ERC-1271 smart wallets)
- Parameter snapshots:
minPassingScore,slashBps,disputePeriod,registryGracePeriod, and validation policy modes are captured per-task at creation/dispute time -- admin changes don't affect in-flight tasks - Bounded admin controls: Dispute period capped at 90 days, slash basis points at 10,000, scorer slash multiplier bounded at deployment
- Registry failure handling: Grace window prevents immediate slashing during validation registry outages
- Task-scoped validator commitment: Each task binds a single
committedValidator; only that validator's response can resolve disputes - Pull payments: Eliminates stuck-task risk from reverting recipients
- Reentrancy protection: Transient storage lock on all state-mutating external functions
Agent Bonds uses the official ERC-8004 ValidationRegistryUpgradeable deployed on Sepolia, Base Sepolia, OP Sepolia, and other networks listed at erc-8004/erc-8004-contracts.
Compatibility assumptions enforced by AgentBondManager:
- Validation finality defaults to
ResponseHashRequired(setValidationFinalityPolicy(0)), soresponseHash == 0is treated as no final response. - Optional mode
AnyStatusRecord(setValidationFinalityPolicy(1)) treats any returned status record as final. - Status lookup failure handling defaults to
CanonicalUnknownAsMissing(setStatusLookupFailurePolicy(0)), which classifies failed status reads by checking whetherrequestHashexists ingetAgentValidations(agentId). - Fallback policies are configurable:
AlwaysMissing(1) orAlwaysUnavailable(2).
Requires Foundry.
forge install
forge build
forge test -v- OpenZeppelin Contracts Upgradeable v5 (UUPS, SignatureChecker, Initializable)
- Solidity 0.8.24
Both contracts deploy behind ERC-1967 proxies (UUPS pattern). Foundry scripts handle the full lifecycle.
cp .env.example .env
# Edit .env with your values (RPC URLs, registry addresses, parameters)| Variable | Description |
|---|---|
DEPLOYER_ADDRESS |
Deployer EOA |
IDENTITY_REGISTRY |
ERC-8004 Identity Registry |
VALIDATION_REGISTRY |
ERC-8004 Validation Registry |
SCORER_PRIOR_VALUE |
Prior value dampener for outcome scoring |
SCORER_SLASH_MULTIPLIER_BPS |
Slash severity multiplier used by scorer (10000-100000) |
DISPUTE_PERIOD |
Dispute window in seconds (max 90 days) |
MIN_PASSING_SCORE |
Minimum validation score to pass dispute (1-100) |
SLASH_BPS |
Slash percentage in basis points (max 10000) |
VALIDATION_FINALITY_POLICY |
0=ResponseHashRequired, 1=AnyStatusRecord |
STATUS_LOOKUP_FAILURE_POLICY |
0=CanonicalUnknownAsMissing, 1=AlwaysMissing, 2=AlwaysUnavailable |
DEPLOYMENT_SALT_SECRET |
Required bytes32 secret used for deterministic deployment salts |
SALT_TAG |
Optional namespace tag for deterministic deployments (e.g. v2) |
The deploy.sh wrapper handles env loading, network resolution, signer selection, and chains the Solidity scripts together.
# Pre-flight checks
./script/deploy.sh preflight --network base-sepolia
# Dry-run (no broadcast)
./script/deploy.sh dry-run --network base-sepolia
# Predict deterministic addresses without deploying
./script/deploy.sh predict --network base-sepolia
# Deploy with Ledger (default)
./script/deploy.sh deploy --network base-sepolia
# Deploy with Foundry keystore
./script/deploy.sh deploy --network base-sepolia --account deployer
# Deploy with a new deterministic salt namespace
./script/deploy.sh deploy --network base-sepolia --salt-tag v2
# Post-deployment verification only
./script/deploy.sh smoke-test --network base-sepolia
# Upgrade AgentBondManager proxy
./script/deploy.sh upgrade --network base-sepolia --target manager
# Upgrade ReputationScorer proxy
./script/deploy.sh upgrade --network base-sepolia --target scorerWhen --salt-tag is set, deployment artifacts are isolated per namespace using a tag-hash filename under deployments/, so multiple deterministic namespaces can coexist on the same chain without clobbering each other.
Signing options: Ledger (default) or Foundry encrypted keystore (--account <name>). To import a key into the keystore:
cast wallet import deployer --interactiveUnaudited. This code has been through multiple internal review rounds but has not been formally audited. Use on testnet. See SECURITY.md to report vulnerabilities.