Skip to main content

Smart Contracts Overview

The Notareum contract stack implements the on-chain half of the protocol: resource registration, verification lifecycle, validator staking, tokenomics, fees, slashing, and access control. All contracts are written in Solidity 0.8.24, deployed behind UUPS proxies, and administered through a single AccessManager instance that concentrates role-based permissioning and timelocks in one auditable surface. The contract repository is github.com/notareum/contracts. All source is MIT-licensed.

The stack

Each contract has a single responsibility. Cross-contract calls are explicit and trust-minimized: every downstream call is guarded by AccessManager role checks or by the immutable wiring set at initialization.

Contracts

Upgrade model

All state-bearing contracts use the UUPS proxy pattern (UUPSUpgradeable). The upgrade authority is AccessManager. This gives:
  1. Implementation replaceability without migrating storage.
  2. Role-gated upgrades: only the UPGRADER role can authorize an upgrade, and the role itself is held by a timelocked governance executor.
  3. Per-contract upgrade telemetry via the standard Upgraded event.
The UUPS upgrade path is: See AccessManager for role definitions and delays.

Initialization

Every upgradeable contract exposes an initialize(...) method replacing the constructor, guarded by OpenZeppelin’s initializer modifier. Deployment order matters because of cross-wiring:
  1. NotareumAccessManager
  2. NotareumNOTAToken (owner set to AccessManager)
  3. NotareumVeNOTA (bound to NOTA token)
  4. NotareumFeeManager (bound to treasury + NOTA)
  5. NotareumSlashingManager (bound to NOTA, FeeManager)
  6. NotareumValidatorStaking (bound to NOTA, veNOTA, FeeManager, SlashingManager)
  7. NotareumNotaRegistry (bound to FeeManager)
  8. NotareumVerificationEngine (bound to NotaRegistry, ValidatorStaking, FeeManager, SlashingManager)
The deployment script in contracts/scripts/deploy.ts performs these steps deterministically and writes the resulting addresses to deployments/<network>/addresses.json.

Deployment addresses

Ethereum Sepolia is the current target testnet. Mainnet deployments are pending governance activation. See Contract Addresses reference for the canonical addresses.json fetch pattern consumed by all SDKs.

Audit status

The contracts are undergoing audit engagements with the following scope:
  • Full source audit of all nine core contracts.
  • Formal verification of core invariants (resource uniqueness, verification quorum, stake accounting, lock monotonicity).
  • Economic review of fee and slashing parameters under adversarial conditions.
Audit reports are published at github.com/notareum/audits under each completed engagement. Until the first mainnet audit completes, contracts are flagged alpha and deployed only on testnets with clearly labeled faucet-funded tokens.

Invariants enforced

Across the stack:
  • Resource uniqueness: resourceId = keccak256(abi.encodePacked(type, chainId, identifier)) maps to at most one registry entry.
  • Attestation once-per-round: a validator can submit at most one attestation per (resourceId, round).
  • Stake monotonic inside a tier: a validator inside a tier cannot go below the tier minimum without triggering tier downgrade or slashing.
  • Lock monotonicity in veNOTA: a lock can be extended or topped up, never reduced while active.
  • Fee conservation: every fee collected is routed to exactly one destination (treasury, burn, disputer), summing to 100% of the collected amount.
Each contract’s docs page restates the invariants it owns and the test files that guard them.

Gas profile

The protocol targets production gas budgets for typical operations. Current benchmarks (Solidity 0.8.24, viaIR, optimizer 200 runs, EVM Shanghai): The aggregation path in VerificationEngine scales linearly with the number of attestations; at the 15-validator institutional quorum the finalize cost is approximately 440k gas.

Event model

All state changes emit strongly-typed events consumable by indexers:
  • NotaRegistry: ResourceRegistered, ResourceUpdated, ResourceRevoked, AliasSet.
  • VerificationEngine: VerificationRequested, AttestationSubmitted, VerificationFinalized, DisputeOpened, DisputeResolved.
  • ValidatorStaking: Staked, UnstakeRequested, Unstaked, TierChanged, RewardsClaimed.
  • NOTAToken: standard ERC-20 + Minted, Burned.
  • veNOTA: LockCreated, LockIncreased, LockExtended, LockWithdrawn.
  • FeeManager: FeeCollected, FeeParametersUpdated, TreasuryUpdated.
  • SlashingManager: Slashed, SlashReported.
  • AccessManager: standard OZ RoleGranted, RoleRevoked, TargetAdminDelayUpdated.
Indexers such as The Graph subgraphs in contracts/subgraph consume these directly.

Local development

The Hardhat configuration includes mainnet forking for integration tests and deterministic deployment ordering via hardhat-deploy.