Repository navigation
Development and Testing
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
This document provides comprehensive development and testing guidance for Sigvara’s codebase. It covers Foundry setup, project structure, compilation settings, and the full testing infrastructure across Solidity contracts, the oracle service, and the TypeScript SDK. It also explains unit tests, integration tests, fuzzing, invariant testing patterns, test organization with helpers and fixtures, debugging techniques, gas analysis, performance profiling, code style guidelines, pull request workflows, security considerations, and examples of effective testing for smart contracts and oracle services.
The repository is organized into clear layers:
- On-chain protocol contracts under
src/ - Foundry-based tests under
test/, including unit, E2E, upgrade, fork, and invariant suites - Oracle service under
oracle/with Node.js modules and tests - TypeScript SDK under
packages/sdk/with Vitest tests - Deployment scripts under
script/ - Repository checks and tools under
scripts/(includingscripts/fetch-deps.sh, which fetches the Solidity dependencies, andscripts/check-docs.mjs) and worked examples underexamples/ - Documentation under
docs/and site assets undersite/ - Archive token-launch contracts under
archive/token-launch/
graph TB
A["Repository Root"] --> B["src/ (Solidity contracts)"]
A --> C["test/ (Foundry tests)"]
A --> D["oracle/ (Node.js oracle)"]
A --> E["packages/sdk/ (TypeScript SDK)"]
A --> F["script/ (Deployment scripts)"]
A --> G["docs/ (Protocol documentation)"]
A --> H["site/ (Public site assets)"]
A --> I["archive/token-launch/ (Legacy token contracts)"]
Diagram sources
Section sources
Sigvara’s core on-chain components are:
- Identity registry managing agent identity, operator control, Ed25519 keys, and status transitions
- Reputation registry storing computed scores and challenge windows
- Staking core managing bonds, slashing, unbonding, and slash proceeds distribution
- Oracle bond contract controlling who can propose reputation updates when enabled
These contracts use UUPS proxies and role-based access control. The README documents their roles and interactions, while the build document provides historical context and interface summaries.
Section sources
The system integrates ERC-8004 identity and feedback registries with Sigvara’s computed reputation and staked-slashing layer. The oracle computes normalized scores from payment-backed attestations and community signals, proposes them to the reputation registry, and the slashing committee enforces accountability through staking and slashing.
graph TB
subgraph "Signal Sources"
CA["CounterAudit<br/>work-outcome attestations"]
WD["Watchdog scanners<br/>rug / abuse flags"]
end
subgraph "ERC-8004"
EID["Identity Registry"]
EREP["Reputation Registry"]
end
subgraph "Sigvara Protocol"
OR["Reputation Oracle"]
REP["SigvaraReputation"]
ST["SigvaraStaking"]
ID["SigvaraIdentity"]
OB["SigvaraOracleBond"]
end
CONS["SDK Consumers"]
CA --> OR
WD --> OR
EID --> OR
EREP --> OR
OR --> REP
ST --> REP
ST --> ID
OB --> OR
REP --> CONS
Diagram sources
Foundry configuration defines source/output directories, library remappings, optimizer settings, solc version, fuzz runs, CI fuzz intensity, filesystem permissions, and RPC endpoints for Arc testnet/mainnet.
Key points:
- Source directory:
src - Output directory:
out - Libraries:
lib - Remappings include OpenZeppelin contracts and forge-std
- Optimizer enabled with 200 runs
- Solidity compiler version 0.8.24
- EVM version
cancun, set explicitly so a Foundry upgrade cannot change what is compiled - Fuzz runs: 1000 default, 5000 in CI profile
- Filesystem read-write permission for deployments directory
- RPC endpoints for Arc testnet and mainnet
flowchart TD
Start(["Foundry Config"]) --> Src["src = 'src'"]
Start --> Out["out = 'out'"]
Start --> Libs["libs = ['lib']"]
Start --> Remap["Remappings for OpenZeppelin and forge-std"]
Start --> Opt["optimizer = true, runs = 200"]
Start --> Solc["solc_version = '0.8.24'"]
Start --> FS["fs_permissions for './deployments'"]
Start --> Fuzz["fuzz.runs = 1000"]
Start --> CIFuzz["profile.ci fuzz.runs = 5000"]
Start --> RPC["rpc_endpoints arc_testnet / arc_mainnet"]
Diagram sources
Section sources
The repository includes three primary test surfaces:
- Contract tests using Foundry (unit, fuzz, E2E, upgrade, invariants)
- Oracle tests using Node.js built-in test runner
- SDK tests using Vitest
Commands:
- Contracts:
forge testandFOUNDRY_PROFILE=ci forge test - Oracle:
cd oracle && node --test - SDK:
cd packages/sdk && npx vitest run
The README enumerates these commands and counts, while package manifests define scripts and dependencies. As of 22 October 2026 the contract suite has 654 tests (each of the 11 invariants counts once), the oracle suite 751 and the SDK suite 168. Without a fork URL, 647 of the contract tests run and 7 skip, and 8 of the SDK tests, the integration tests, skip without a live deployment.
The Solidity dependencies are fetched into lib/ before the first build with sh scripts/fetch-deps.sh. It fetches OpenZeppelin and forge-std each by commit, because lib/ is gitignored and there are no submodules.
Section sources
Unit tests validate individual contract functions in isolation using Foundry’s in-memory EVM. They do not require external networks or deployed contracts. Two fork suites are the exception: test/SlashDrillFork.t.sol forks Arc testnet on every run, so it needs the arc_testnet endpoint in foundry.toml to answer, and test/SplitAuthorityFork.t.sol skips its seven tests unless you pass --fork-url https://rpc.testnet.arc.io. Typical usage:
- Run all contract tests:
forge test - Increase fuzz density:
FOUNDRY_PROFILE=ci forge test
These tests cover identity operations, reputation proposals, staking flows, and edge cases.
Section sources
The E2E suite covers the full agent lifecycle: registration, staking, reputation proposal/finalization, slashing, and zero-reputation enforcement. It deploys mock tokens and proxy implementations, wires roles, and asserts state transitions and distributions.
Key scenarios:
- Full happy path register → stake → propose/finalize → slash → zero
- Slash dispute and reinstatement
- Reputation challenge rejection
- Unbonding period enforcement
- Slash sweeping unbonding queue
- Multiple epochs of score evolution
- Multiple independent agents
sequenceDiagram
participant Test as "E2EIntegrationTest"
participant Identity as "SigvaraIdentity"
participant Reputation as "SigvaraReputation"
participant Staking as "SigvaraStaking"
participant Token as "MockSVR"
Test->>Token : mint(operator, amount)
Test->>Identity : registerAgent(agentAddress, pubKey, signature)
Test->>Staking : depositStake(didHash, MIN_STAKE)
Test->>Reputation : proposeReputation(didHash, data, evidenceRoot)
Test->>Reputation : finalizeReputation(didHash)
Test->>Staking : initiateSlash(didHash, victim, evidence)
Test->>Staking : executeSlash(didHash)
Staking-->>Token : burn 50%
Staking-->>Victim : credit 25%
Staking-->>Committee : credit 25%
Diagram sources
Section sources
Fuzz testing drives randomized inputs against contract functions to uncover edge cases. The Foundry configuration sets default fuzz runs and a higher CI profile. Use:
- Default fuzz:
forge test - CI fuzz intensity:
FOUNDRY_PROFILE=ci forge test
The README documents running fuzz at higher intensity.
Section sources
Invariant tests assert properties that must hold after any reachable sequence of actions. The suite targets the staking contract with handlers that exercise deposits, withdrawals, slash initiation/dispute/execution, status changes, and time progression.
Important invariants:
- Custody matches recorded obligations (stake + queued withdrawals + unclaimed proceeds)
- Token conservation (deposits equal held + claimed + burned + pulled)
- Slashed agents fully zeroed (no stake, no queue)
- Burned balance only grows
- Disputed agents stay bonded
- Active agents are collateralized (at least minimum stake)
The handler rules on disputes as the admin and also drives expireSlash. A second campaign, OracleBondInvariantTest, covers the operator bond registry with five more invariants: signer mappings stay symmetric, a signer is never also an operator, an address has standing only through a bonded Active operator, nobody is left signing for nobody, and the active count and custody still add up. Together the two hold the 11 invariants. Run it with forge test --match-contract OracleBondInvariantTest.
flowchart TD
Start(["Invariant Suite"]) --> Seed["Seed bonds for agents"]
Seed --> Target["Target handler contract"]
Target --> Actions["Randomized actions:<br/>deposit, withdraw, slash, dispute, resolve, expire, cancel, claim"]
Actions --> Assert["Assert invariants:<br/>custodyMatchesRecordedObligations<br/>tokenConservation<br/>slashedAgentsFullyZeroed<br/>burnedOnlyGrows<br/>disputedAgentsStayBonded<br/>activeAgentsAreCollateralised"]
Diagram sources
Section sources
The oracle service is a Node.js application with its own test suite using the built-in test runner. Package scripts define start and test. Dependencies include dotenv and ethers.
Usage:
- Run oracle tests:
cd oracle && node --test
Section sources
The TypeScript SDK uses Vitest for unit and integration tests. Configuration enables globals and Node environment. Scripts include build, test, and typecheck.
Usage:
- Run SDK tests:
cd packages/sdk && npx vitest run
Section sources
The testing infrastructure depends on:
- Foundry toolchain for Solidity compilation and testing
- OpenZeppelin contracts for upgradeable proxies and ERC20 mocks
- Forge-std for testing utilities
- Node.js runtime for oracle tests
- Vitest for SDK tests
graph TB
Foundry["Foundry Toolchain"] --> Contracts["Solidity Contracts"]
Foundry --> Tests["Contract Tests"]
OpenZeppelin["OpenZeppelin Contracts"] --> Contracts
ForgeStd["Forge-Std"] --> Tests
NodeJS["Node.js Runtime"] --> OracleTests["Oracle Tests"]
Vitest["Vitest"] --> SDKTests["SDK Tests"]
Diagram sources
Section sources
- Compiler optimization: Enabled with 200 runs; adjust based on deployment needs.
- Fuzz intensity: Default 1000 runs; CI profile increases to 5000 runs for deeper coverage.
- Gas analysis: Use Foundry’s built-in tools (
forge inspect,forge snapshot) to analyze gas usage and regressions. - Profiling: Leverage
forge test -vvvfor verbose output and trace execution paths during failures. - Oracle performance: Ensure efficient chain reads and caching strategies; monitor metrics and logs in production.
Common issues and resolutions:
- RPC endpoint misconfiguration: Verify Arc testnet/mainnet URLs in Foundry config.
- Fee estimation errors: Retry
forge scriptwith--legacyif fee estimation behaves unexpectedly. - Chain metadata unknown: Avoid adding Etherscan entries for unsupported chain IDs until native support ships.
- Test failures due to time-sensitive logic: Use
vm.warpto advance block timestamps in tests. - Role misassignment: Ensure admin grants correct roles to staking core, oracle, and committee addresses. On main the staking-core, committee and slasher roles are administered by
UPGRADER_ROLE, which the timelock holds on a real deployment, so the admin alone cannot grant them there.
Section sources
Sigvara’s development and testing infrastructure combines robust Foundry configurations, comprehensive contract tests, fuzzing, invariants, and parallel test suites for the oracle and SDK. Following the documented setup, testing patterns, and security practices ensures reliable development, audit readiness, and safe deployment.
- Solidity: Follow Foundry conventions, use consistent naming, and keep functions focused.
- TypeScript: Use strict typing, linting, and Vitest best practices.
- Node.js: Modularize oracle components, add tests per module, and handle errors gracefully.
- Branching strategy: Feature branches off main, PRs reviewed before merge.
- CI checks: Ensure all tests pass (contracts, oracle, SDK) along with
scripts/check-docs.mjs,scripts/check-headers.mjs,scripts/check-evidence-fixture.mjsand Slither, which fails the build on High findings only. - Documentation: Update relevant docs for protocol changes.
- Security: Include audit notes and threat model updates where applicable.
- Access control: Restrict privileged roles to timelock or multisig on mainnet.
- Upgradeability: Use UUPS proxies controlled by governance.
- Reentrancy: Apply guards where necessary.
- Oracle trust: Validate payment-backed attestations and evidence roots.
- Slashing fairness: Ensure dispute windows and frozen bonds prevent escape.
Section sources
- Complete unit, integration, fuzz, and invariant tests.
- Verify role assignments and upgrade paths.
- Review oracle validation logic and evidence handling.
- Confirm slashing distributions and unbonding enforcement.
- Document known weaknesses and mitigation strategies.
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