Repository navigation
Economic Security
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
This document explains Sigvara’s economic security model: how stake and bonds back reputation claims, how misbehavior is punished, and how the system prevents operators from escaping accountability through withdrawals or exits. It covers two separate but complementary mechanisms:
- Agent staking: a slashable bond behind each agent identity that enables slashing when an operator makes false or harmful reputation claims.
- Oracle operator bonding: a performance bond for oracle participants that can be slashed for provably incorrect data or prolonged downtime, with demotion out of the active operator set if the bond falls below the required amount.
The design intentionally separates these paths so agent-level accountability and oracle-operator accountability are enforced independently.
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 three contracts and supporting documentation:
-
SigvaraStaking.sol: manages agent stake deposits, unbonding, slash proposals, dispute resolution, and slash execution. -
SigvaraOracleBond.sol: manages oracle operator bonds, admission, exit cooldowns, partial slashing, and active-set eligibility. -
SigvaraReputation.sol: stores and matures reputation scores, gates proposal rights on bonded oracles, and zeroes scores after slashing. -
docs/reputation-model.mdanddocs/slash-drill.mddescribe scoring incentives and provide an end-to-end slash drill.
graph TB
Staking["SigvaraStaking.sol"]
Bond["SigvaraOracleBond.sol"]
Reputation["SigvaraReputation.sol"]
Identity["SigvaraIdentity.sol"]
SVR["SVR Token (ERC-20)"]
Staking --> Identity
Staking --> Reputation
Staking --> SVR
Bond --> SVR
Reputation --> Identity
Reputation --> Bond
Diagram sources
Section sources
- Agent stake: Operators deposit SVR to back an agent identity. The stake must meet a minimum to activate the agent. Stake remains slashable even while queued for withdrawal during the unbonding period.
- Slash lifecycle: A committee member initiates a slash; the agent is suspended; a challenge window opens; the operator may dispute; if undisputed, anyone can execute the slash. Execution burns half the stake and credits the other half to victim and reporter. The admin can veto a proposal at any point, and one that nobody executes can be lapsed by anyone 14 days after its deadline.
- Dispute resolution: Disputes freeze the stake and move the proposal to an admin ruling. If the admin does not rule within a bounded period, anyone can expire the dispute to unfreeze the bond.
- Unbonding: Withdrawals are queued and become claimable only after the unbonding period. During this time, they remain slashable.
- Oracle operator bond: Separate from agent stake. Operators post a bond, get admitted by governance, and can be partially slashed. Slashing can demote an operator below the required bond amount. An operator can name a signer, so the key that signs scores need not be the key that holds the bond.
- Reputation gating: Only bonded agents can be scored. When an operator set is configured, only admitted bonded oracles, or the signers they have named, may propose scores. Slashing zeros the agent’s reputation.
Section sources
- SigvaraStaking.sol:31-45
- SigvaraStaking.sol:308-461
- SigvaraStaking.sol:467-787
- SigvaraOracleBond.sol:14-45
- SigvaraOracleBond.sol:205-378
- SigvaraReputation.sol:14-75
- SigvaraReputation.sol:369-557
The economic security architecture ties three layers together:
- Identity layer: Determines whether an agent exists and its status (Active, PendingBond, Suspended, Slashed).
-
Economic layer: Holds collateral behind behavior.
- Agent stake backs identity activity and reputation claims.
- Oracle operator bond backs the correctness and availability of the oracle network.
- Reputation layer: Stores scores proposed by authorized oracles, enforces maturity, and zeroes scores after slashing.
sequenceDiagram
participant Committee as "Committee"
participant Admin as "Admin"
participant Staking as "SigvaraStaking"
participant Identity as "SigvaraIdentity"
participant Operator as "Operator"
participant Reputation as "SigvaraReputation"
Committee->>Staking : "initiateSlash(didHash, victim, evidence)"
Staking->>Identity : "updateStatus(Suspended)"
Note over Staking,Identity : "Challenge window starts"
Operator->>Staking : "disputeSlash(didHash)"
Staking-->>Operator : "Proposal frozen"
Admin->>Staking : "resolveDispute(uphold)"
alt Uphold
Staking->>Staking : "_settleSlash()"
Staking->>Identity : "updateStatus(Slashed)"
Staking->>Reputation : "zeroReputation()"
else Reject
Staking->>Identity : "clearSlashSuspension()"
end
Diagram sources
- SigvaraStaking.sol:473-528
- SigvaraStaking.sol:540-615
- SigvaraStaking.sol:712-776
- SigvaraReputation.sol:536-557
The staking contract implements a complete slash lifecycle:
- Deposit stake to activate or top up an agent.
- Queue withdrawals with an unbonding cooldown.
- Initiate a slash against an agent with evidence.
- Allow the operator to dispute, freezing the stake.
- Let the admin uphold (once the challenge deadline has passed, and on
mainbefore the dispute can be expired) or reject the dispute. - Let the admin veto a pending or disputed proposal, and let anyone lapse one that nobody executes.
- Execute the slash after the challenge window if undisputed.
- Distribute proceeds: burn half, credit victim and reporter.
flowchart TD
Start(["Slash Entry"]) --> CheckPending{"Proposal already pending?"}
CheckPending --> |Yes| RevertPending["Revert: SlashAlreadyPending"]
CheckPending --> |No| CheckStake{"Total stake + queued > 0?"}
CheckStake --> |No| RevertNoStake["Revert: NoStake"]
CheckStake --> |Yes| CreateProposal["Create SlashProposal<br/>Snapshot challengeDeadline"]
CreateProposal --> SuspendAgent["Suspend agent in Identity"]
SuspendAgent --> WindowOpen["Challenge window open"]
WindowOpen --> Dispute{"Operator disputes?"}
Dispute --> |Yes| Freeze["Move to Disputed<br/>Freeze stake"]
Dispute --> |No| WaitWindow["Wait until challengeDeadline"]
Freeze --> Resolve{"Admin rules?"}
Resolve --> |Uphold| Settle["_settleSlash()"]
Resolve --> |Reject| Drop["_dropProposal()"]
Resolve --> |Timeout| Expire["expireDispute()"]
WaitWindow --> Execute["executeSlash()"]
Execute --> Settle
Settle --> Burn["Burn 50%"]
Settle --> CreditVictim["Credit 25% to victim"]
Settle --> CreditReporter["Credit 25% to reporter"]
Settle --> MarkSlashed["Mark agent Slashed<br/>Zero reputation"]
Drop --> Restore["Restore Active if still bonded"]
Expire --> Drop
Diagram sources
Key behaviors validated by tests:
- Deposits accumulate and can activate a PendingBond agent.
- Active agents cannot withdraw to zero; full exit requires suspension first.
- Queued withdrawals remain slashable; executing a slash sweeps both active and queued amounts.
- Disputes freeze stakes and keep the agent suspended.
- Early execution before the challenge window reverts.
- Slash proceeds are credited and must be claimed separately.
Section sources
- SigvaraStaking.sol:308-461
- SigvaraStaking.sol:467-787
- SigvaraStaking.t.sol:116-218
- SigvaraStaking.t.sol:229-440
- SigvaraStaking.t.sol:446-655
Withdrawals are not instant:
- An operator queues a withdrawal amount.
- The amount becomes claimable only after
unbondingPeriod. - While queued, the amount remains slashable.
- A slash in progress blocks claiming.
- Admin parameters enforce minimum unbonding periods to prevent trivial escape windows, and a maximum (90 days) so one value cannot lock every queued exit.
flowchart TD
Init(["initiateWithdrawal"]) --> Validate["Check stake, operator,<br/>no pending slash,<br/>remaining >= minimum"]
Validate --> Queue["Queue unbondingAmount<br/>Set unbondingAt"]
Queue --> Wait["Wait unbondingPeriod"]
Wait --> ClaimCheck{"Slash pending?"}
ClaimCheck --> |Yes| BlockClaim["Block claim"]
ClaimCheck --> |No| Transfer["Transfer queued amount to operator"]
Diagram sources
Section sources
When a slash is disputed:
- The proposal moves to Disputed.
- The stake remains frozen.
- The agent stays Suspended.
- The admin calls
resolveDisputeto uphold or drop the proposal. Upholding waits for the challenge deadline and, onmain, ends when the dispute can be expired; dropping is open at any time. - If the admin never rules, anyone can call
expireDisputeafter a fixed timeout. - The admin can also
vetoSlasha pending or disputed proposal, and anyone canexpireSlasha pending one 14 days after its deadline. - Dropping a proposal restores the agent to Active only if it still meets the minimum stake, and the committee then waits one challenge period before it can file against the agent again.
stateDiagram-v2
[*] --> Pending
Pending --> Disputed : "operator disputes"
Pending --> Executed : "challenge expires<br/>executeSlash"
Pending --> Cancelled : "cancelSlash, vetoSlash<br/>or expireSlash"
Disputed --> Executed : "admin uphold"
Disputed --> Cancelled : "admin reject or vetoSlash"
Disputed --> Cancelled : "timeout expireDispute"
Cancelled --> ActiveOrSuspended : "restore if bonded"
Executed --> Slashed : "agent terminal"
Diagram sources
Section sources
The oracle bond registry is separate from agent staking:
- Operators deposit SVR to become Bonded.
- Governance admits Bonded operators into Active.
- Operators can initiate unbonding or be removed by governance.
- After the unbonding cooldown, operators withdraw their remaining bond.
- A slasher can partially slash an operator’s bond.
- If an Active operator’s bond drops below the required amount, it is demoted out of the active set.
- Bonds in the unbonding cooldown remain slashable.
- An Active operator can name one signer; the signer answers for it in
isActiveOperatorbut cannot start an unbond or withdraw the bond, and the operator can clear it at once. - The slasher role is granted through the timelock and can never be held by the slash beneficiary.
classDiagram
class SigvaraOracleBond {
+depositBond(amount)
+admit(operator)
+initiateUnbond()
+withdrawBond()
+setSigner(signer)
+clearSigner()
+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
Test coverage confirms:
- Partial slashing transfers funds to the slash beneficiary.
- Slashing below the bond threshold demotes the operator.
- Slashing works during unbonding.
- Raising the bond requirement immediately affects incumbents via
isActiveOperator.
Section sources
- SigvaraOracleBond.sol:205-378
- SigvaraOracleBond.sol:398-447
- SigvaraOracleBond.t.sol:119-163
- SigvaraOracleBond.t.sol:267-302
Reputation influence is constrained by economic backing:
- Only agents with at least
minimumStakecan receive reputation updates. - New agents start with no score and must post stake before any meaningful reputation can accrue.
- Maturity delays make earned reputation spendable gradually, preventing farm-and-cash-out strategies.
- Slashing zeros all reputation factors and marks the agent as Slashed, which is terminal.
flowchart TD
Register["Register agent"] --> PendingBond["Status: PendingBond"]
PendingBond --> Deposit["Deposit stake >= minimumStake"]
Deposit --> Active["Status: Active"]
Active --> ScorePropose["Oracle proposes score"]
ScorePropose --> Challenge["Challenge window"]
Challenge --> Finalize["Finalize score"]
Finalize --> Mature["Matured score climbs toward earned score"]
Mature --> Use["Consumers gate on getTotalScore"]
Active --> SlashRisk["Misbehavior risk"]
SlashRisk --> Slash["executeSlash()"]
Slash --> ZeroRep["zeroReputation()"]
Slash --> Terminal["Status: Slashed"]
Diagram sources
- SigvaraReputation.sol:369-557
- SigvaraReputation.sol:620-631
- SigvaraReputation.sol:696-752
- reputation-model.md:268-327
Section sources
- SigvaraReputation.sol:369-557
- SigvaraReputation.sol:620-631
- SigvaraReputation.sol:696-752
- reputation-model.md:268-327
Slash penalties are designed to deter misbehavior and compensate harmed parties:
- Half of the slashable stake is burned.
- One quarter goes to the victim.
- One quarter goes to the reporter.
- The agent becomes Slashed and its reputation is zeroed.
- Both active stake and queued withdrawal are swept.
This distribution is enforced in settlement and verified by tests and the slash drill.
Section sources
Recovery depends on the outcome of dispute resolution:
- If a slash is rejected or expired, the agent can return to Active only if it still holds enough stake.
- If the stake is below the minimum after a dropped proposal, the agent remains Suspended until the operator tops up.
- For oracle operators, topping up the bond restores an operator that is still Active but below a raised requirement, without a new admission. One demoted to Bonded by a slash must top up and be admitted again.
Section sources
Representative operations include:
- Deposit stake to activate or increase backing.
- Initiate withdrawal to queue an amount for later claim.
- Claim withdrawal after the unbonding period.
- Initiate slash as a committee member.
- Dispute a slash as the operator.
- Resolve a dispute as the admin.
- Execute slash after the challenge window.
- Claim slash proceeds as victim or reporter.
- Deposit oracle bond and get admitted.
- Slash an oracle operator’s bond.
- Remove an operator or let them unbond.
These flows are exercised in the test suites and documented in the slash drill.
Section sources
- SigvaraStaking.t.sol:116-218
- SigvaraStaking.t.sol:229-440
- SigvaraStaking.t.sol:446-655
- SigvaraOracleBond.t.sol:68-113
- SigvaraOracleBond.t.sol:119-163
- slash-drill.md:201-295
Common scenarios covered by implementation and tests:
- Undisputed slash executes after the challenge window.
- Operator disputes a slash, freezing the stake.
- Admin upholds or rejects a dispute.
- Admin does not rule; dispute expires.
- Admin vetoes a pending slash, or nobody executes it and anyone lapses it after 14 days.
- Operator tries to dodge slash by queuing entire stake; slash still initiable and sweeps queued funds.
- Active agent cannot drain stake to zero; full exit requires suspension.
- Oracle operator slashed below bond threshold is demoted.
- Oracle operator slashed during unbonding remains accountable.
Section sources
The system defends against several attack patterns:
- Farm-and-cash-out: Reputation maturity and bond requirements make quick farming less profitable and more detectable.
- Sybil wash trading: Fee and success factors are capped per payer and decayed; external trust and propagation rely on independent standing.
- Exit evasion: Queued withdrawals remain slashable; slash initiation checks total stake including queued amounts.
- Veto abuse: Disputes freeze rather than cancel slashes; the freeze is bounded by dispute expiration and by the lapse of an unexecuted proposal.
- Admin manipulation: Minimum challenge and unbonding periods prevent instant slashes or instant withdrawals, ceilings stop one value from locking every exit, and the roles that move funds are granted through the timelock.
- Committee abuse: A slash pays a quarter of the bond to whoever filed it, so a compromised or mistaken committee has a reason to file. The admin can veto, the admin and not the committee rules on disputes, after a dropped proposal the committee waits one challenge period before filing again, and the admin can revoke a compromised member at once: a slash is executed only while its reporter still holds the role, so what that member had filed cannot land.
- Stolen oracle key: A signer cannot start an unbond or withdraw the bond, and finalization refuses a proposal whose proposer has been removed or had its signer cleared.
- Live bug: A guardian can pause new registrations, deposits, score proposals and bond deposits for three days at a time. Exits, claims, disputes, rulings and slash execution are never covered by the pause.
- Fee-on-transfer accounting attacks: Deposits measure actual received balance delta rather than trusting caller-supplied amounts.
Section sources
- SigvaraReputation.sol:110-128
- SigvaraReputation.sol:696-752
- SigvaraStaking.sol:105-120
- SigvaraStaking.sol:365-461
- SigvaraStaking.sol:483-487
- SigvaraStaking.sol:799-836
The economic security contracts depend on each other and on shared roles:
-
SigvaraStakingreads agent identity and calls reputation zeroing on slash. -
SigvaraReputationreads identity to validate scorable agents and optionally reads the operator bond registry to require bonded oracles. -
SigvaraOracleBondis optional for reputation proposals but essential for multi-oracle safety. - All three use OpenZeppelin upgradeable access control and UUPS proxies.
graph LR
Staking["SigvaraStaking"] --> Identity["SigvaraIdentity"]
Staking --> Reputation["SigvaraReputation"]
Reputation --> Identity
Reputation --> Bond["SigvaraOracleBond"]
Bond --> SVR["SVR Token"]
Staking --> SVR
Diagram sources
Section sources
- Slash settlement uses pull-based payouts for victim and reporter shares to avoid blocking settlement on recipient token behavior.
- Reputation maturity is computed on read, allowing scores to mature even if oracles stop proposing.
- Storage layout is append-only across upgrades to preserve live proxy mappings.
- Tests pin storage slots to detect accidental layout changes.
Common issues and their causes:
- Cannot initiate slash: Agent has no stake, a slash is already pending, or a proposal against the agent was dropped less than one challenge period ago.
- Cannot dispute slash: Challenge window expired or caller is not the operator.
- Cannot claim withdrawal: Unbonding period not elapsed or slash is pending.
-
Cannot finalize reputation: No pending score, the challenge window is still active, or the proposer no longer holds ORACLE_ROLE or an active operator slot (
ProposerNotAuthorized). - Cannot propose reputation: Agent not registered, slashed, or not bonded; oracle not admitted/bonded when operator set is configured; or an inflow pause is running.
- Oracle operator not active: Bond below required amount or not admitted.
- Slash proceeds not received: Proceeds are credited and must be claimed explicitly.
Operational guidance includes verifying roles, checking timestamps, and following the slash drill rehearsal before live action.
Section sources
- SigvaraStaking.sol:189-217
- SigvaraStaking.sol:365-461
- SigvaraStaking.sol:473-615
- SigvaraReputation.sol:239-260
- SigvaraReputation.sol:369-557
- SigvaraOracleBond.sol:126-145
- slash-drill.md:24-41
Sigvara’s economic security model ties reputation to capital. Agent stakes and oracle operator bonds create real financial consequences for misbehavior. The slash lifecycle includes a challenge window, dispute freezing, an admin ruling with a veto, and permissionless execution. Unbonding periods prevent immediate escape, and reputation maturity prevents rapid exploitation of newly built trust. Together, these mechanisms align operator incentives with honest behavior and protect consumers relying on reputation-gated decisions.
- 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