Repository navigation
SigvaraOracleBond Contract
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
This document explains the SigvaraOracleBond contract, which manages oracle operator admission and performance bonding for the Sigvara oracle network. It is a separate accounting and slashing path from agent staking: it bonds oracle operators who propose reputation scores, not the agents whose scores are computed.
The contract defines a four-state lifecycle for operators: None, Bonded, Active, Exiting. Operators deposit SVR to become Bonded, governance admits them into the Active set, and they may initiate unbonding or be removed by governance. A designated slasher can slash active or exiting operators; slashing below the minimum bond demotes an operator out of the active set. The contract emits events for every state change and economic action, and its isActiveOperator view enforces both status and current bond level. An operator can also name a signer, the key an oracle service signs with, so the key on a server need not be the key that holds the bond.
The broader system uses this registry as an optional gate on score proposals: when configured, only an admitted, bonded operator, or the signer it has named, that holds ORACLE_ROLE may propose reputation updates. Oracle scoring itself is off-chain; the on-chain layer stores proposed and finalized scores, evidence roots, maturity, and committee challenges.
This page describes the contract on main. The Arc testnet proxy has run it since 26 October 2026, so its signer registry is live, though neither operator has named a signer. Its role administrators were written by the September initialisation, so the slasher grant and the slash-beneficiary change are not timelocked there.
Section sources
The relevant codebase parts are:
- Core contracts under
src/:-
SigvaraOracleBond.sol: operator bonding, admission, slashing, and unbonding. -
SigvaraReputation.sol: optimistic score proposal, challenge window, evidence roots, and optional operator-bond gating.
-
- Deployment script under
script/:-
DeployOracleBond.s.sol: deploys the proxy, initializes parameters, validates role separation, and records the proxy address. On chain 5042 it also refuses the default bond amount or one under 2,500,000 SVR, an unbonding period outside 1 to 90 days, and a missing or unseparated guardian.
-
- Tests under
test/:-
SigvaraOracleBond.t.sol: covers initialization, deposit/admit, slashing, unbonding, admin setters, signers, incumbent behavior, and storage layout pinning. -
OracleBondInvariant.t.sol: five stateful invariants over arbitrary sequences of deposits, signers, slashes and exits.
-
- Documentation:
-
docs/reputation-model.md: describes the six-factor score, maturity, oracle epochs, and multi-operator design. -
docs/arc.md: deployment runbook notes and operational guidance around bonding, admission order, and live behavior. -
archive/token-launch/docs/tokenomics.md: high-level tokenomics context for oracle operator bonds. -
oracle/RUNBOOK-second-operator.md: practical testnet operator onboarding, bond floor changes, and failure modes.
-
graph TB
subgraph "On-chain Contracts"
OB["SigvaraOracleBond"]
REP["SigvaraReputation"]
ID["SigvaraIdentity"]
STK["SigvaraStaking"]
SVR["SVR Token"]
end
subgraph "Off-chain"
ORA["Oracle Network<br/>Scoring + Evidence"]
GOV["Governance / Committee"]
end
SVR --> OB
GOV --> OB
ORA --> REP
REP --> OB
REP --> ID
STK --> REP
Diagram sources
Section sources
SigvaraOracleBond implements:
- Operator lifecycle management:
- Deposit bond: moves SVR into the contract and sets operator to Bonded. It is refused while a guardian pause is running.
- Admit: governance promotes a Bonded operator with sufficient bond to Active.
- Initiate unbonding: operator signals exit and starts cooldown.
- Withdraw bond: after cooldown, operator clears their record and receives remaining SVR. Any signer the operator named is released.
- Remove operator: governance forces an operator into Exiting.
- Signer registry: an Active operator names one signer with
setSigner, andclearSignerremoves it in any status.
- Slashing:
- Slasher reduces an operator’s bond and transfers slashed tokens to the slash beneficiary.
- If an Active operator falls below the required bond, they are demoted to Bonded and removed from the active count.
- If the bond reaches zero, the operator record is reset to None and any signer is released.
- Governance parameters:
- Minimum bond amount (zero is refused).
- Unbonding period (between 1 and 90 days, in
initializeand in the setter). - Slash beneficiary (changed through the timelock, and never an address that holds the slasher role).
- Read-only checks:
-
isActiveOperator(operator)returns true only if the operator is Active and their bond meets the current requirement. A registered signer is answered for as the operator that named it. -
bondOf(operator)returns the recorded bond. -
signerOf(operator)andoperatorOfSigner(signer)read the signer registry in each direction.
-
Key roles:
- DEFAULT_ADMIN_ROLE: admits/removes operators, sets the bond amount and the unbonding period, and revokes any role except UPGRADER_ROLE at once.
- SLASHER_ROLE: slashes operator bonds. It is administered by UPGRADER_ROLE, so a grant takes the timelock's delay.
- UPGRADER_ROLE: authorizes UUPS upgrades, grants SLASHER_ROLE and its own role, and sets the slash beneficiary.
- GUARDIAN_ROLE: pauses new bond deposits for three days at a time, and nothing else.
Events emitted:
- BondDeposited
- OperatorAdmitted
- OperatorSlashed
- UnbondInitiated
- BondWithdrawn
- OperatorRemoved
- BondAmountUpdated
- UnbondingPeriodUpdated
- SlashBeneficiaryUpdated
- SignerSet
- SignerCleared
Errors cover invalid addresses, zero amounts, wrong operator status, insufficient bond, slash exceeding bond, unbonding still active, no bond, an unbonding period outside its bounds, signer conflicts, and a slasher that is also the slash beneficiary.
Section sources
- SigvaraOracleBond.sol:56-145
- SigvaraOracleBond.sol:205-271
- SigvaraOracleBond.sol:322-378
- SigvaraOracleBond.sol:384-447
The bonding contract is designed to work alongside SigvaraReputation and the identity/staking layers:
- SigvaraOracleBond owns the operator bond ledger and slashing logic.
- SigvaraReputation optionally requires proposers to be active operators through
IOperatorSet.isActiveOperator. - Governance controls admission and parameter changes.
- The oracle network computes scores off-chain and proposes them on-chain within a challenge window.
- The slash mechanism ensures operators have skin in the game for false or unreliable reporting.
sequenceDiagram
participant OP as "Oracle Operator"
participant OB as "SigvaraOracleBond"
participant GOV as "Governance"
participant REP as "SigvaraReputation"
participant SLP as "Slasher"
participant BEN as "Slash Beneficiary"
OP->>OB : "depositBond(amount)"
OB-->>OP : "BondDeposited"
GOV->>OB : "admit(operator)"
OB-->>GOV : "OperatorAdmitted"
OP->>REP : "proposeReputation(...)"
REP->>OB : "isActiveOperator(operator)"
OB-->>REP : "true/false"
REP-->>OP : "ScoreProposed"
SLP->>OB : "slash(operator, amount)"
OB->>BEN : "transfer slashed SVR"
OB-->>SLP : "OperatorSlashed(demoted?)"
Diagram sources
- SigvaraOracleBond.sol:210-234
- SigvaraOracleBond.sol:323-331
- SigvaraOracleBond.sol:351-378
- SigvaraReputation.sol:378-448
- SigvaraReputation.sol:600-604
An operator begins by approving SVR and calling depositBond. The contract credits the actual received amount, handles fee-on-transfer differences safely, and transitions the operator from None to Bonded. Governance then calls admit, which verifies that the operator is Bonded and has at least bondAmount. On success, the operator becomes Active and increments the active count.
Important operational detail: raising bondAmount does not retroactively remove incumbents’ status, but isActiveOperator re-reads the bond requirement live. Therefore, an incumbent below the new threshold immediately fails the active-operator check even though their stored status remains Active until explicitly removed or slashed.
flowchart TD
Start(["Operator Registration"]) --> Approve["Approve SVR to contract"]
Approve --> Deposit["Call depositBond(amount)"]
Deposit --> StatusCheck{"Status == Exiting?"}
StatusCheck --> |Yes| RevertDeposit["Revert WrongStatus"]
StatusCheck --> |No| Transfer["Transfer SVR into contract"]
Transfer --> Credit["Credit received amount"]
Credit --> SetBonded["Set status = Bonded if None"]
SetBonded --> EmitDeposit["Emit BondDeposited"]
EmitDeposit --> Admit["Governance calls admit(operator)"]
Admit --> CheckBonded{"Status == Bonded and bond >= bondAmount?"}
CheckBonded --> |No| RevertAdmit["Revert InsufficientBond or WrongStatus"]
CheckBonded --> |Yes| SetActive["Set status = Active<br/>activeCount++"]
SetActive --> EmitAdmit["Emit OperatorAdmitted"]
EmitAdmit --> End(["Operator can propose scores"])
Diagram sources
Section sources
- SigvaraOracleBond.sol:205-234
- SigvaraOracleBond.sol:322-331
- SigvaraOracleBond.sol:425-443
- arc.md:307-324
The operator is whoever holds the bond: a cold key or a Safe. The signer is the key an oracle service uses to propose, finalize and charge, and it lives on a host. Before the two were separated they were one address, so whoever took the service's key could also start an unbond and withdraw once the cooldown ran.
-
setSigner(signer)is callable only by anActiveoperator, one governance has admitted and which still holds its bond. It names one signer and replaces any earlier one. The signer must be an address nobody else uses in the registry: it cannot hold a bond record, name a signer, or be another operator's signer (SignerNotFree). -
isActiveOperator(signer)then answers for the operator that named it. Every function that moves the bond stays with the operator, and a signer cannot post a bond of its own (depositBondrevertsAlreadySigner). -
clearSigner()works in any status,Exitingincluded, and takes effect in the same block. The former signer's next propose or charge is refused, and the proposals it still has waiting out their challenge window will no longer finalize. - The signer is released when the operator withdraws its bond or is slashed to nothing.
removeOperatordoes not release it. - Naming a signer grants no role anywhere.
ORACLE_ROLEstays a separate governance decision on each contract, and the signer needs it as well.
An operator that never names a signer behaves exactly as before.
Section sources
SigvaraOracleBond does not compute oracle performance metrics directly. Instead, it provides the economic enforcement layer for operators who participate in the performance monitoring pipeline implemented off-chain by the oracle network and consumed by SigvaraReputation.
The reputation model defines six factors: fee activity, success rate, tenure, external trust, community standing, and trust propagation. Scores are proposed off-chain, committed on-chain with evidence roots, subject to a challenge window, and mature over time. When the operator-bond registry is configured, only admitted, bonded operators (or the signer one has named) may propose scores. Finalization stays permissionless, but it refuses a proposal whose proposer no longer holds ORACLE_ROLE or is no longer an active operator or signer, so removing an operator or clearing its signer also ends what that key has pending. A proposal from an authorized proposer replaces it.
flowchart TD
Scan["Oracle scans chain logs and attestations"] --> Compute["Compute six-factor score"]
Compute --> Evidence["Build Merkle evidence root"]
Evidence --> Propose["Call proposeReputation(...)"]
Propose --> Gate["SigvaraReputation checks ORACLE_ROLE"]
Gate --> BondGate["If configured, check isActiveOperator()"]
BondGate --> Pending["Store pending score + evidence root"]
Pending --> Challenge["Challenge window opens"]
Challenge --> Finalize["Anyone finalizes after window"]
Finalize --> Mature["Matured score grows toward earned score"]
Diagram sources
- reputation-model.md:362-421
- SigvaraReputation.sol:378-448
- SigvaraReputation.sol:600-631
- SigvaraReputation.sol:696-752
Section sources
- reputation-model.md:7-17
- reputation-model.md:226-267
- reputation-model.md:362-421
- SigvaraReputation.sol:16-75
- SigvaraReputation.sol:378-504
Slashing is the primary penalty mechanism enforced by SigvaraOracleBond. A slasher can reduce an operator’s bond for provably incorrect reputation data or extended downtime. Slashed SVR is transferred to the slash beneficiary.
Key behaviors:
- Slashing is permissioned to SLASHER_ROLE. The role is administered by UPGRADER_ROLE, so the admin cannot install a slasher in the next transaction, but can revoke one at once. The registry never lets one address be both the slasher and the slash beneficiary.
- Slashing cannot exceed the operator’s bond.
- If an Active operator’s bond drops below
bondAmount, they are demoted to Bonded and removed from the active set. - If slashing reduces the bond to zero, the operator record is cleared to None and any signer is released.
- Slashing works during unbonding, preventing operators from escaping accountability simply by initiating withdrawal.
flowchart TD
SlashStart["Slasher calls slash(operator, amount)"] --> Validate["Validate bond > 0, amount > 0, amount <= bond"]
Validate --> Reduce["Reduce operator.bond by amount"]
Reduce --> DemoteCheck{"Status == Active and bond < bondAmount?"}
DemoteCheck --> |Yes| Demote["Set status = Bonded<br/>activeCount--"]
DemoteCheck --> |No| KeepStatus["Keep current status"]
KeepStatus --> ZeroCheck{"bond == 0?"}
Demote --> ZeroCheck
ZeroCheck --> |Yes| ClearRecord["Set status = None<br/>unbondingAt = 0<br/>Release the signer"]
ZeroCheck --> |No| Transfer["Transfer amount to slashBeneficiary"]
ClearRecord --> Transfer
Transfer --> Emit["Emit OperatorSlashed"]
Emit --> SlashEnd(["Penalty applied"])
Diagram sources
Section sources
Governance controls operator admission and key parameters:
- Admitting operators: DEFAULT_ADMIN_ROLE calls
admit(operator). - Removing operators: DEFAULT_ADMIN_ROLE calls
removeOperator(operator). The operator's signer, if it has one, stays reserved until the operator withdraws or is slashed to nothing. - Setting minimum bond: DEFAULT_ADMIN_ROLE calls
setBondAmount(newBondAmount). Zero is refused. - Adjusting unbonding period: DEFAULT_ADMIN_ROLE calls
setUnbondingPeriod(newPeriod). The period must be between 1 day and 90 days (PeriodTooShort,PeriodTooLong), as it must be ininitialize. - Changing slash beneficiary: UPGRADER_ROLE, which the timelock holds, calls
setSlashBeneficiary(newBeneficiary), because the call decides where value flows. It refuses the zero address and any address that holds SLASHER_ROLE (SlasherIsBeneficiary).
The contract also supports UUPS upgrades via UPGRADER_ROLE. That role administers itself and SLASHER_ROLE, so installing a slasher takes the timelock's delay, while the admin can still revoke one at once (TimelockedGrants).
In the broader system, SigvaraReputation can be pointed at the operator-bond registry via setOperatorBond, which also needs UPGRADER_ROLE and not the admin role. Once enabled, proposing a score requires the caller to hold ORACLE_ROLE and pass isActiveOperator, either as an admitted operator or as the signer one has named. This is the integration point where trusted oracle networks are enforced economically.
Section sources
A typical onboarding flow is:
- Operator acquires SVR and approves the bond contract.
- Operator calls
depositBond(amount). - Governance calls
admit(operator). - Governance grants ORACLE_ROLE on SigvaraReputation and/or SigvaraEpochFees.
- Operator begins proposing reputation scores.
If the bond is held by a cold key or a Safe, the operator calls setSigner(signingKey) once admitted and governance grants ORACLE_ROLE to the signing key instead.
Operational guidance emphasizes ordering: raise the bond floor only after ensuring existing operators remain above the new threshold, because isActiveOperator evaluates live.
Section sources
- SigvaraOracleBond.sol:210-234
- SigvaraOracleBond.sol:323-331
- RUNBOOK-second-operator.md:169-213
- arc.md:307-324
Performance evaluation is primarily off-chain. The oracle network computes six-factor scores, proposes them on-chain, and commits evidence roots. Consumers read matured scores via getTotalScore. Disagreements between operators are intended to surface during the challenge window, enabling committee intervention.
Section sources
When misbehavior is established:
- Slasher calls
slash(operator, amount). - Contract reduces the bond and transfers slashed tokens to the slash beneficiary.
- If the operator was Active and now falls below the bond requirement, they are demoted.
- If the bond reaches zero, the operator record is cleared and any signer is released.
- Events allow off-chain monitoring of penalties and demotions.
Section sources
The economic model ties oracle credibility to a bond of SVR:
- Operators must post a defined bond before being admitted.
- Misreporting or prolonged downtime can trigger slashing.
- Slashed bonds reduce the operator’s ability to propose scores if they fall below the minimum.
- The unbonding period prevents operators from withdrawing collateral before accountability is resolved.
- The bond is separate from agent stakes, ensuring oracle misconduct is penalized independently of agent misconduct.
The tokenomics documentation states that each oracle operator must stake a defined amount of SVR as a performance bond, managed via this dedicated contract. Slashing applies for provably incorrect reputation data or extended downtime.
Section sources
SigvaraOracleBond emits clear events for all state and economic transitions:
- BondDeposited(operator, amount, newBond)
- OperatorAdmitted(operator)
- OperatorSlashed(operator, amount, remaining, demoted)
- UnbondInitiated(operator, claimableAt)
- BondWithdrawn(operator, amount)
- OperatorRemoved(operator)
- BondAmountUpdated(newBondAmount)
- UnbondingPeriodUpdated(newPeriod)
- SlashBeneficiaryUpdated(newBeneficiary)
- SignerSet(operator, signer)
- SignerCleared(operator, signer)
These events enable off-chain monitoring dashboards, alerting systems, and audit trails for operator status changes and penalty enforcement.
Section sources
- SigvaraOracleBond.sol:106-118
- SigvaraOracleBond.sol:210-234
- SigvaraOracleBond.sol:240-271
- SigvaraOracleBond.sol:323-378
- SigvaraOracleBond.sol:398-419
The design balances quality assurance with openness:
- Quality assurance:
- Only admitted, bonded operators may propose scores when the registry is configured.
- Slashing removes economic incentives for false reporting.
- Challenge windows and evidence roots allow verification and committee intervention.
- Openness:
- Any party meeting technical requirements and posting the required bond can apply for admission.
- Governance admits operators rather than a single deployer controlling the entire set.
- The operator-bond requirement is optional: leaving the registry unset allows a single-operator mode, while enabling it introduces multi-operator accountability.
The architecture encourages multiple bonded operators, with one proposer per epoch and others recomputing from committed evidence to detect divergence.
Section sources
Potential collusion risks include:
- Multiple operators coordinating to submit inflated scores.
- Wash trading to inflate fee activity or success metrics.
- Colluding counterparties to boost propagation or external trust.
Mitigations:
- Bonds create direct economic loss for malicious operators.
- Slashing removes colluders from the active set.
- Reputation scoring includes decay, caps, priors, and external trust dependencies that resist simple wash cycles.
- Challenge windows and evidence roots allow independent verification.
- Propagation deliberately inherits only external trust, reducing reflexivity.
However, collusion is not fully eliminated. The documentation acknowledges that weights bound cheap attacks, while only an executing slashing path bounds expensive ones. Multi-operator disagreement and committee oversight are part of the defense-in-depth strategy.
Section sources
- Fee-on-transfer tokens:
depositBondreads balance delta instead of trusting the requested amount, preventing over-crediting. - Zero bond edge case: slashing to zero resets the operator record to avoid permanently bricking the address.
- Unbonding safety: slashing remains possible during unbonding, preventing escape from accountability.
- Live bond checks:
isActiveOperatorenforces current bond level, so raising the requirement binds immediately on the gating call. - Admin safeguards: zero bond amount is rejected; zero slash beneficiary address is rejected; the unbonding period is held between 1 and 90 days; the slash beneficiary can only be changed through the timelock.
- Role separation: the registry refuses one address as both slasher and slash beneficiary, in
initialize, in every grant of SLASHER_ROLE and insetSlashBeneficiary. The deployment script stops on that pairing on every chain before anything is sent (both addresses default to the deployer, so state at least one), and on mainnet also refuses a deployer that holds either role. On testnet it only warns about the deployer. - Stolen signing key: a signer cannot start an unbond or withdraw the bond, and the operator ends its access in one transaction with
clearSignerorsetSigner. - Seized bonds: the admin cannot install a slasher or repoint the beneficiary without the timelock's delay, so a compromised admin cannot slash every operator and pay itself in one batch.
Section sources
- SigvaraOracleBond.sol:216-234
- SigvaraOracleBond.sol:366-378
- SigvaraOracleBond.sol:384-419
- DeployOracleBond.s.sol:148-172
SigvaraOracleBond depends on:
- OpenZeppelin upgradeable access control (through
TimelockedGrants) and UUPS upgradeability. -
InflowGuard, for the guardian's pause on bond deposits. - ERC20 interfaces for SVR.
- SafeERC20 for secure token transfers.
- ReentrancyGuard for protection against reentrant calls.
It integrates with:
- SigvaraReputation and SigvaraEpochFees via the IOperatorSet interface, which this contract implements.
- Governance through DEFAULT_ADMIN_ROLE and SLASHER_ROLE.
- Deployment scripts for proxy setup and parameter initialization.
classDiagram
class SigvaraOracleBond {
+address svr
+uint256 bondAmount
+uint256 unbondingPeriod
+address slashBeneficiary
+uint256 activeCount
+depositBond(amount)
+initiateUnbond()
+withdrawBond()
+setSigner(signer)
+clearSigner()
+admit(operator)
+removeOperator(operator)
+slash(operator, amount)
+setBondAmount(newBondAmount)
+setUnbondingPeriod(newPeriod)
+setSlashBeneficiary(newBeneficiary)
+isActiveOperator(operator) bool
+bondOf(operator) uint256
}
class SigvaraReputation {
+proposeReputation(...)
+finalizeReputation(...)
+rejectReputation(...)
+setOperatorBond(address)
+getTotalScore(bytes32) uint8
}
class SVRToken {
+balanceOf(address) uint256
+safeTransferFrom(...)
+safeTransfer(...)
}
SigvaraOracleBond --> SVRToken : "uses IERC20"
SigvaraReputation --> SigvaraOracleBond : "checks IOperatorSet.isActiveOperator"
Diagram sources
- SigvaraOracleBond.sol:46-53
- SigvaraOracleBond.sol:89-94
- SigvaraOracleBond.sol:210-447
- SigvaraReputation.sol:12
- SigvaraReputation.sol:600-604
Section sources
- SigvaraOracleBond.sol:1-53
- SigvaraOracleBond.sol:89-94
- SigvaraReputation.sol:12
- SigvaraReputation.sol:600-604
- Constant-time operator index lookup: operator mapping access is O(1).
- Live bond checks:
isActiveOperatoravoids unbounded loops by reading current bond and status. - Gas efficiency: slashing and withdrawals use SafeERC20 and emit events for off-chain tracking.
- Storage layout pinning: tests verify slot positions to prevent accidental upgrade-related storage corruption.
- Off-chain scoring: heavy computation is intentionally kept off-chain; on-chain logic focuses on verification, governance, and economic enforcement.
Recommendations:
- Monitor event emissions for operator status changes and slashing.
- Track active operator count and bond levels.
- Ensure RPC providers support the required log ranges and receipt horizons for oracle operations.
- Avoid lowering LOG_CHUNK_SIZE unnecessarily; provider throttling is better addressed by pacing.
Section sources
Common issues and resolutions:
- Operator cannot propose scores after bond floor increase:
- Check
isActiveOperator; if false, top up the bond before raising the floor. - Verify the operator’s bond meets the new requirement.
- Check
- Operator stuck in Exiting state:
- Wait until
block.timestamp >= unbondingAt + unbondingPeriod. - Call
withdrawBondto clear the record.
- Wait until
- Slashing reverts:
- Ensure slasher has SLASHER_ROLE.
- Ensure slash amount does not exceed operator bond.
- Zero bond after slashing:
- Operator record is reset to None; operator must redeposit and be readmitted.
- Deployment warnings:
- If the slasher and the slash beneficiary are the same address, the script stops on every chain; both default to the deployer, so state at least one of them.
- On mainnet the script also stops if the deployer holds either role; separate roles are required.
-
setSignerreverts:-
WrongStatus: the caller is not an Active operator. -
SignerNotFree: the address already has a bond record, names a signer, is another operator's signer, or is the caller. - Use
clearSigner(any status) to drop a signer; it revertsNoSignerwhen there is none.
-
-
depositBondrevertsInflowsPausedUntil: the guardian has paused new bonds; the pause ends by itself after three days.depositBondalso revertsAlreadySignerfor an address that is some operator's signer.
Section sources
- RUNBOOK-second-operator.md:169-213
- SigvaraOracleBond.sol:240-271
- SigvaraOracleBond.sol:351-378
- DeployOracleBond.s.sol:148-172
SigvaraOracleBond provides the economic backbone for oracle operator accountability. It separates operator bonding from agent staking, enforces admission through governance, and enables slashing for misbehavior. Combined with SigvaraReputation’s optimistic scoring, evidence roots, challenge windows, and maturity mechanics, the system balances decentralization with quality assurance.
Operators must post meaningful collateral, maintain active status, and face economic penalties for false or unreliable reporting. Governance retains control over admission and parameters, while the live bond check ensures that policy changes bind immediately. Event emissions and tests provide transparency and reliability for operators, consumers, and auditors.
| Function | Access | Purpose | Key Behavior |
|---|---|---|---|
depositBond(amount) |
Operator | Post or top up bond | Transfers SVR, sets Bonded, emits BondDeposited; closed while an inflow pause runs |
initiateUnbond() |
Operator | Signal exit | Sets Exiting, starts cooldown, emits UnbondInitiated |
withdrawBond() |
Operator | Claim bond after cooldown | Clears record and signer, transfers remaining SVR |
setSigner(signer) |
Active operator | Name the key that signs | Replaces any earlier signer, requires an address nobody else uses, emits SignerSet |
clearSigner() |
Operator, any status | Stop anyone signing for the operator | Takes effect in the same block, emits SignerCleared |
admit(operator) |
DEFAULT_ADMIN_ROLE | Admit bonded applicant | Requires Bonded and sufficient bond, sets Active |
removeOperator(operator) |
DEFAULT_ADMIN_ROLE | Force exit | Sets Exiting, emits OperatorRemoved |
slash(operator, amount) |
SLASHER_ROLE | Partially slash bond | Transfers to beneficiary, demotes if needed |
setBondAmount(newBondAmount) |
DEFAULT_ADMIN_ROLE | Update minimum bond | Rejects zero, emits BondAmountUpdated |
setUnbondingPeriod(newPeriod) |
DEFAULT_ADMIN_ROLE | Update cooldown | Rejects under 1 day or over 90 days, emits UnbondingPeriodUpdated |
setSlashBeneficiary(newBeneficiary) |
UPGRADER_ROLE | Update payee | Rejects zero address and any holder of SLASHER_ROLE, emits SlashBeneficiaryUpdated |
pauseInflows() |
GUARDIAN_ROLE | Pause new bonds | Closes depositBond for 3 days; resumeInflows() (guardian or admin) lifts it early |
isActiveOperator(operator) |
View | Check active and bonded | Returns true only if Active and bond >= bondAmount; a registered signer answers for its operator |
bondOf(operator) |
View | Read bond | Returns operator bond |
signerOf(operator), operatorOfSigner(signer)
|
View | Read the signer registry | Zero means no signer |
Section sources
- Initialization and role assignment.
- Deposit and admit flows.
- Slashing reductions, demotions, and beneficiary transfers.
- Unbonding cooldown and withdrawal.
- Admin-only setters and zero-value guards.
- Incumbent behavior under bond changes.
- Signer registry: naming, replacing, clearing, and the conflicts it refuses.
- Five stateful invariants in
OracleBondInvariant.t.sol: signer mappings stay symmetric, a signer is never also an operator, standing comes only from a bonded Active operator, no signer outlives its operator's record, andactiveCountand custody still add up. - Storage layout pinning for upgrade safety.
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