Repository navigation
Economic Security Model and Incentives
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
This document explains the economic security model that makes Sigvara agent operators accountable through staked collateral, and shows how incentives align community participants with protocol safety. The system has two related but distinct bonding paths:
- Agent stake:
SigvaraStakingholds SVR-backed collateral for each registered agent. It enforces minimum stake, unbonding, a challenge period, dispute freezing, and a fixed slash distribution. - Operator bond:
SigvaraOracleBondholds a separate performance bond for oracle operators who propose reputation scores. Governance can slash operator bonds for provably incorrect data or excessive downtime.
The design ensures that an agent cannot become Active without collateral, that slashing remains possible even during withdrawal, that victims and reporters are rewarded, and that reputation is only meaningful when backed by at-risk capital.
This page describes the contracts on main. The Arc testnet proxies have run these contracts since 26 October 2026, apart from the bound on upholding a dispute, which they take at their next upgrade. They keep the role administrators written by the September initialisation, so the timelocked grants described below do not apply there and the admin still grants the slasher, committee and staking-core roles.
The economic security logic lives primarily in four contracts and one invariant test suite:
graph TB
Identity["SigvaraIdentity<br/>Agent registration, status, operator transfers"]
Staking["SigvaraStaking<br/>Agent stake, unbonding, slash proposals"]
Reputation["SigvaraReputation<br/>Optimistic score proposals, maturity, evidence roots"]
OracleBond["SigvaraOracleBond<br/>Operator performance bond, governance slash"]
Tests["StakingInvariant.t.sol<br/>Fuzzed custody and collateral invariants"]
Identity --> Staking
Staking --> Reputation
Reputation --> Identity
Reputation --> OracleBond
Tests --> Staking
Tests --> Identity
Tests --> Reputation
Diagram sources
- SigvaraIdentity.sol:23-106
- SigvaraStaking.sol:31-142
- SigvaraReputation.sol:14-75
- SigvaraOracleBond.sol:14-45
- StakingInvariant.t.sol:18-44
Section sources
- SigvaraIdentity.sol:23-106
- SigvaraStaking.sol:31-142
- SigvaraReputation.sol:14-75
- SigvaraOracleBond.sol:14-45
- StakingInvariant.t.sol:18-44
The economic model rests on five mechanisms:
| Mechanism | Contract | Purpose |
|---|---|---|
| Bond-before-trust |
SigvaraIdentity, SigvaraStaking
|
Registration creates a PendingBond identity; only depositing at least minimumStake activates it. |
| Unbonding cooldown | SigvaraStaking |
Withdrawals queue for unbondingPeriod; queued funds remain slashable until claimed. |
| Challenge and dispute | SigvaraStaking |
A committee-initiated slash enters a challenge window; the operator may dispute, freezing the stake until the admin rules. The admin can also veto. |
| Slash distribution | SigvaraStaking |
On execution, stake is split into burn, victim reward, and reporter reward. |
| Operator accountability | SigvaraOracleBond |
Oracle operators post a separate bond; governance can slash and demote them if below the required amount. |
These components together prevent sybil-style free entry, make dishonest reporting costly, compensate harmed parties, and keep reputation tied to real economic exposure.
Section sources
- SigvaraIdentity.sol:47-56
- SigvaraIdentity.sol:295-321
- SigvaraStaking.sol:308-363
- SigvaraStaking.sol:365-461
- SigvaraStaking.sol:467-776
- SigvaraOracleBond.sol:14-45
The end-to-end economic flow connects identity, stake, attestation, reputation, and consequences.
sequenceDiagram
participant Operator as "Agent Operator"
participant Identity as "SigvaraIdentity"
participant Staking as "SigvaraStaking"
participant Oracle as "Oracle Network"
participant Reputation as "SigvaraReputation"
participant Committee as "Slashing Committee"
participant Admin as "Admin"
participant Victim as "Victim"
participant Reporter as "Reporter"
Operator->>Identity : "registerAgent(agentAddress, ed25519PubKey, signature)"
Identity-->>Operator : "didHash in PendingBond"
Operator->>Staking : "depositStake(didHash, amount >= minimumStake)"
Staking->>Identity : "updateStatus(didHash, Active)"
Oracle->>Reputation : "proposeReputation(didHash, data, evidenceRoot)"
Reputation-->>Oracle : "challenge window opens"
Note over Reputation : "Committee may reject bad proposal"
Committee->>Staking : "initiateSlash(didHash, victim, evidenceHash)"
Staking->>Identity : "updateStatus(didHash, Suspended)"
Operator->>Staking : "disputeSlash(didHash)"
Staking-->>Operator : "stake frozen while disputed"
Admin->>Staking : "resolveDispute(didHash, uphold=true)"
Staking->>Staking : "_settleSlash(didHash)"
Staking->>Identity : "updateStatus(didHash, Slashed)"
Staking->>Reputation : "zeroReputation(didHash)"
Staking-->>Victim : "credit 25% slash proceeds"
Staking-->>Reporter : "credit 25% slash proceeds"
Staking->>Staking : "burn 50% slash proceeds"
Diagram sources
- SigvaraIdentity.sol:295-321
- SigvaraIdentity.sol:344-397
- SigvaraStaking.sol:320-363
- SigvaraStaking.sol:473-528
- SigvaraStaking.sol:540-615
- SigvaraStaking.sol:712-776
- SigvaraReputation.sol:378-448
- SigvaraReputation.sol:513-557
SigvaraStaking is the core economic escrow for agents. Its key properties are:
- Only the operator of a registered agent can deposit or withdraw.
- Deposits accumulate and activate a
PendingBondagent once the balance reachesminimumStake. - Withdrawals are queued for
unbondingPeriod; they remain slashable until claimed. - A slash proposal suspends the agent immediately and starts a challenge window.
- Disputing freezes the stake rather than canceling the proposal.
- The admin, not the committee, rules on a dispute, and cannot uphold it before the challenge deadline or once it can be expired. The admin can also veto a proposal, and one that nobody executes can be lapsed by anyone 14 days after its deadline.
- After any dropped proposal the committee waits one challenge period before filing against the same agent again.
- Execution splits the total slashed amount into burn, victim, and reporter shares.
flowchart TD
Start(["Slash Initiation"]) --> CheckStake["Check active stake + queued withdrawal > 0"]
CheckStake --> |No| RevertNoStake["Revert: NoStake"]
CheckStake --> |Yes| CreateProposal["Create pending slash proposal"]
CreateProposal --> SuspendAgent["Set agent status to Suspended"]
SuspendAgent --> ChallengeWindow{"Challenge period expired?"}
ChallengeWindow --> |No| DisputePath["Operator disputes -> stake frozen"]
DisputePath --> Resolve["Admin rules: uphold or drop"]
Resolve --> |Uphold| Settle["_settleSlash()"]
Resolve --> |Drop| DropProposal["Cancel proposal, possibly clear suspension"]
ChallengeWindow --> |Yes| Execute["executeSlash()"]
Execute --> Settle
Settle --> Sweep["Zero active stake and queued withdrawal"]
Sweep --> Distribute["Burn 50%, credit victim 25%, credit reporter 25%"]
Distribute --> MarkTerminal["Mark agent Slashed and zero reputation"]
MarkTerminal --> End(["Slash Complete"])
Diagram sources
Section sources
Minimum stake prevents cheap identity creation from being economically equivalent to operating a trusted agent:
- Registration alone does not make an agent Active; it creates
PendingBond. - An agent becomes Active only after its stake reaches
minimumStake. - While Active, an operator cannot drain the stake below
minimumStakeunless it first suspends itself. - Even during unbonding, queued withdrawals remain slashable.
- If a slash drops an agent’s stake to zero, the agent becomes terminal and cannot be reactivated.
This means sybil attacks must pay real capital per agent, and malicious behavior risks that capital.
flowchart TD
Register["Register agent"] --> PendingBond["Status = PendingBond"]
PendingBond --> Deposit["Deposit stake"]
Deposit --> MeetsFloor{"Stake >= minimumStake?"}
MeetsFloor --> |No| StayPending["Remain PendingBond"]
MeetsFloor --> |Yes| Activate["Activate Active"]
Activate --> Operate["Operate under slash risk"]
Operate --> Withdraw["Initiate withdrawal"]
Withdraw --> Queue["Queue unbondingAmount"]
Queue --> Slashable{"Slash initiated?"}
Slashable --> |Yes| StillSlashable["Queued funds still slashable"]
Slashable --> |No| Claim["Claim after unbondingPeriod"]
Diagram sources
Section sources
- SigvaraIdentity.sol:47-56
- SigvaraIdentity.sol:344-397
- SigvaraStaking.sol:320-363
- SigvaraStaking.sol:377-461
When a slash executes, the contract distributes the total slashed amount as follows:
| Share | Recipient | Rationale |
|---|---|---|
| 50% | Burn address 0xdead
|
Prevents profit from slashing volume and removes tokens permanently. |
| 25% | Victim | Partially compensates the harmed counterparty. |
| 25% | Reporter | Rewards the committee member who initiated the slash. |
Proceeds are credited to accounts and withdrawn later via claimSlashProceeds. This pull-based payout avoids locking settlement behind recipients that cannot receive the token.
flowchart TD
TotalSlashed["Total slashed = active stake + queued withdrawal"] --> Half["Burn 50%"]
TotalSlashed --> VictimShare["Credit 25% to victim"]
TotalSlashed --> ReporterShare["Credit 25% to reporter"]
VictimShare --> ClaimVictim["Victim claims proceeds"]
ReporterShare --> ClaimReporter["Reporter claims proceeds"]
Diagram sources
Section sources
SigvaraOracleBond manages a separate bond for oracle operators who propose reputation scores. Its lifecycle is:
- Deposit bond →
Bonded. - Governance admits, which needs a bond of at least
bondAmount→Active. - Operator exits or is removed →
Exitingwith unbonding cooldown. - After cooldown, withdraw remaining bond.
Governance with SLASHER_ROLE can partially slash an operator’s bond. If slashing drops an active operator below bondAmount, it is demoted out of the active set. This separates operator misconduct from agent misconduct: an oracle can lose its right to propose scores even if the agent stake path is different.
The slasher role is granted through the timelock, and the registry never lets one address be both the slasher and the slash beneficiary, so no key can take a bond and pay itself. An operator can also name a signer, the key an oracle service signs with: it answers for the operator in isActiveOperator but cannot start an unbond or withdraw the bond, and the operator can clear it at once.
classDiagram
class SigvaraOracleBond {
+address svr
+uint256 bondAmount
+uint256 unbondingPeriod
+address slashBeneficiary
+uint256 activeCount
+depositBond(amount)
+admit(operator)
+initiateUnbond()
+withdrawBond()
+removeOperator(operator)
+slash(operator, amount)
+isActiveOperator(operator) bool
+bondOf(operator) uint256
}
class Operator {
+uint256 bond
+Status status
+uint256 unbondingAt
}
class Status {
<<enum>>
None
Bonded
Active
Exiting
}
SigvaraOracleBond --> Operator : "tracks"
Operator --> Status : "has"
Diagram sources
- SigvaraOracleBond.sol:77-94
- SigvaraOracleBond.sol:210-271
- SigvaraOracleBond.sol:322-378
- SigvaraOracleBond.sol:435-447
Section sources
- SigvaraOracleBond.sol:14-45
- SigvaraOracleBond.sol:210-271
- SigvaraOracleBond.sol:322-378
- SigvaraOracleBond.sol:435-447
Reputation is not just a score; it is a spendable trust signal backed by collateral:
- Scores are proposed off-chain and committed on-chain with a Merkle root over evidence.
- A proposed score sits open during a challenge window.
- Only agents with
minimumStakecan be scored. - When an agent is slashed, its reputation is zeroed.
- Maturity delays the release of earned reputation, preventing farm-and-cash-out behavior.
- Operator handovers restart maturity so buyers cannot instantly spend inherited reputation.
flowchart TD
Evidence["Off-chain payment evidence"] --> Root["Merkle evidence root"]
Root --> Propose["Oracle proposes reputation"]
Propose --> Window["Challenge window"]
Window --> Finalize["Finalize reputation"]
Finalize --> Earned["Earned score stored"]
Earned --> Mature["Matured score released over time"]
Mature --> Spend["Consumers read matured score"]
Slash["Agent slashed"] --> ZeroRep["Reputation zeroed"]
Diagram sources
- SigvaraReputation.sol:378-448
- SigvaraReputation.sol:454-504
- SigvaraReputation.sol:541-557
- SigvaraReputation.sol:696-752
Section sources
- SigvaraReputation.sol:14-75
- SigvaraReputation.sol:378-448
- SigvaraReputation.sol:454-504
- SigvaraReputation.sol:541-557
- SigvaraReputation.sol:696-752
The model exposes several trade-offs:
| Parameter | Effect of Increasing | Risk of Too High |
|---|---|---|
minimumStake |
Raises sybil cost and per-agent accountability | Reduces operator participation; smaller operators may exit. |
bondAmount (oracle) |
Increases operator accountability for false scoring | Reduces oracle supply; fewer operators proposing scores. |
| Slash severity | Makes dishonesty more expensive | May increase false-positive pressure on committees; higher stakes needed to absorb losses. |
| Challenge period | Gives operators more time to dispute | Delays justice and keeps agents suspended longer. |
| Unbonding period | Extends accountability window for queued withdrawals | Locks operator capital longer; reduces liquidity. |
| Maturity rate | Slows reputation spendability | Honest agents take longer to realize trust value. |
The code explicitly documents these tensions. For example, the slash distribution intentionally burns half the stake so no one profits from slashing volume, while still rewarding victims and reporters enough to make monitoring worthwhile.
The admin tunes these values within fixed bounds: the slash challenge period between 3 and 30 days, the unbonding period between 1 and 90 days (for both stake and operator bonds), the reputation challenge window between 1 hour and 7 days, and the maturity rate at most 100 points a day. The minimum stake and the bond amount only have to be above zero.
Section sources
- SigvaraStaking.sol:712-776
- SigvaraStaking.sol:802-836
- SigvaraReputation.sol:696-752
- whitepaper.md:123-137
| Attack Vector | Countermeasure |
|---|---|
| Free sybil identities | Agents start as PendingBond; only collateralized agents become Active. |
| Draining stake before slash | Queued withdrawals remain slashable; slash checks both active and queued amounts. |
| Escaping accountability by withdrawing | Unbonding period plus slash sweep prevents immediate escape. |
| Self-payment farming | Attestation rules require on-chain payments verified by the oracle; self-payment is refused. |
| Farm-and-cash-out reputation | Maturity releases earned reputation gradually; operator handover restarts maturity. |
| Bad oracle scoring | Optional bonded operator requirement plus governance slash path for oracle bonds. |
| Frozen stake during unresolved dispute | Dispute resolution period allows anyone to expire an unresolved freeze. |
| Pending proposal nobody executes |
expireSlash lets anyone drop it 14 days after its challenge deadline. |
| Compromised or conflicted committee | The admin rules on disputes and can veto; a dispute cannot bring a slash forward; a dropped proposal starts a one-period re-file cooldown. |
| Slasher paying itself | The slasher role is granted through the timelock and can never be held by the slash beneficiary. |
| Stolen oracle signing key | The signer cannot start an unbond or withdraw the bond, and the operator clears it in one transaction; finalization refuses what a removed or cleared key proposed. |
| Live bug while a fix is built | A guardian can pause new registrations, deposits, score proposals and bond deposits for three days at a time; exits, rulings and slash execution are never covered. |
| Admin shortening windows | Challenge and unbonding periods have minimum bounds enforced by the admin setters and the initializers, and maximum bounds so one value cannot lock every exit. |
| Recipient unable to receive slash proceeds | Proceeds are credited and pulled, not pushed. |
Section sources
- SigvaraIdentity.sol:295-321
- SigvaraStaking.sol:377-461
- SigvaraStaking.sol:473-615
- SigvaraStaking.sol:712-787
- SigvaraReputation.sol:600-631
- SigvaraReputation.sol:696-752
- SigvaraOracleBond.sol:346-378
The contracts form a directed dependency graph where identity is the anchor, staking controls collateral and status transitions, reputation depends on both identity and staking, and oracle bonding is optional but strengthens oracle accountability.
graph LR
SVR["SVR Token"] --> Staking["SigvaraStaking"]
SVR --> OracleBond["SigvaraOracleBond"]
Identity["SigvaraIdentity"] --> Staking
Staking --> Identity
Staking --> Reputation["SigvaraReputation"]
Reputation --> Identity
Reputation --> OracleBond
Diagram sources
- SigvaraStaking.sol:105-142
- SigvaraIdentity.sol:18-20
- SigvaraReputation.sol:12
- SigvaraOracleBond.sol:89-94
Section sources
- SigvaraStaking.sol:105-142
- SigvaraIdentity.sol:18-20
- SigvaraReputation.sol:12
- SigvaraOracleBond.sol:89-94
Economic security also has gas and liveness implications:
- Fee-on-transfer tokens: Both staking and oracle bond deposits measure actual received balances rather than trusting caller-provided amounts, protecting accounting integrity at the cost of extra balance reads.
- Pull-based payouts: Slash proceeds are credited and claimed, avoiding stuck settlements but requiring users to claim separately.
-
Unbounded operator lists:
getOperatorAgentsreturns an unbounded array; consumers should page usingoperatorAgentCountandgetOperatorAgentsPaged. - View calls on external registries: Reputation maturity reads operator change timestamps via a raw staticcall fallback to avoid breaking on older registry versions.
- Admin-minimum guards: Challenge and unbonding periods cannot be set below protocol-defined floors or above protocol-defined ceilings, reducing liveness risk from misconfiguration.
Common economic-security issues and their likely causes:
| Symptom | Likely Cause | Resolution |
|---|---|---|
| Agent cannot become Active after deposit | Deposit did not reach minimumStake
|
Top up stake to meet the floor. |
| Withdrawal reverts with insufficient stake | Attempting to leave active agent below minimumStake
|
Suspend first or reduce withdrawal amount. |
| Slash cannot be initiated | Agent has no active stake and no queued withdrawal, or a proposal against it was dropped less than one challenge period ago | Ensure stake exists; note that queued funds count toward slashability. Otherwise wait out the re-file cooldown. |
| Disputed stake never unfreezes | The admin did not rule within the dispute resolution period | Use expireDispute after the deadline. |
| Slash proceeds cannot be claimed | No proceeds were credited to the caller | Verify the caller is either the victim or the reporter. |
| Reputation cannot be finalized | Challenge window still active, agent became slashed, or the proposer no longer holds ORACLE_ROLE or an active operator slot | Wait for window, check identity status, or have an authorized proposer propose again. |
| Oracle cannot propose reputation | Caller is not an admitted bonded operator (or the signer of one), or an inflow pause is running | Deposit bond and get admitted through SigvaraOracleBond.admit, or wait for the pause to end. |
Section sources
- SigvaraStaking.sol:320-363
- SigvaraStaking.sol:377-461
- SigvaraStaking.sol:473-615
- SigvaraStaking.sol:781-787
- SigvaraReputation.sol:454-504
- SigvaraReputation.sol:600-631
- SigvaraOracleBond.sol:322-378
Sigvara’s economic security model ties agent credibility to real capital. Registration is cheap, but operation is not: agents must stake, operate under slash risk, and face terminal consequences when slashed. Reputation is meaningful because it is backed by stake, delayed by maturity, and verifiable through evidence roots. Oracle operators face a separate accountability layer through bonded operator status and governance slashing.
The invariant tests validate that custody balances, token conservation, slash terminality, dispute freezing, and active-agent collateralization hold across randomized sequences of actions. Together, these mechanisms make honest reporting cheaper than dishonesty and give the community aligned incentives to monitor, report, and compensate harm.
The invariant test suite drives the staking workflow through randomized operations and asserts:
- Custody equals recorded obligations: active stake, queued withdrawals, and unclaimed slash proceeds.
- Token conservation: deposits equal held balance plus claimed withdrawals plus burned and claimed slash proceeds.
- Slashed agents are fully zeroed: no stake, no queued withdrawal, and identity agrees.
- Burned balance only grows.
- Disputed agents retain a non-zero bond at risk.
- Active agents always have at least
minimumStakeacross active and queued stake.
These invariants provide mathematical guarantees about solvency, terminality, and collateralization under adversarial fuzzing.
Section sources
- Agent Registration and Lifecycle
- Contract Overview and Architecture
- Economic Security Model and Incentives
- Evidence Verification and Merkle Proofs
- Key Management and Rotation
- Maturity Mechanism and Score Release
- Proposal Workflow and Challenge System
- Score Storage and Data Model
- SigvaraIdentity Contract
- SigvaraOracleBond Contract
- SigvaraReputation Contract
- SigvaraStaking Contract
- Slashing Lifecycle and Dispute Resolution
- Stake Management Functions
- Status Management and Control
- Token and Fee Contracts
- Unbonding Period and Withdrawal Security
- Anti-Manipulation and Security Measures
- Community Flag Processing
- Evidence Sources and Verification
- External Trust Integration
- Merkle Proof System
- Oracle Score Computation
- Payment-Backed Attestations
- Scoring Model and Formulas
- Agent Creation and Key Management
- Agent Operations
- Agent Registration Workflow
- Challenge-Response Authentication
- Gate Access Control
- Integration Patterns and Examples
- SDK Overview and Setup
- Verifier Functions