> For the complete documentation index, see [llms.txt](https://novacont.gitbook.io/nova-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://novacont.gitbook.io/nova-docs/security-and-developers/contract-architecture.md).

# Contract Architecture

NovaCont's protocol is split across two separate smart contracts. This separation of concerns is intentional. It isolates fund management from dispute resolution, ensuring that a failure or upgrade in one layer does not compromise the other.

<figure><img src="/files/xSnSpj4aaZpDJ9UCPI6L" alt=""><figcaption></figcaption></figure>

### NovaCont - The Escrow Layer

NovaCont is the primary contract. It is responsible for:

* Accepting and locking client funds at contract creation
* Enforcing the agreement lifecycle through strict state transitions
* Managing fund distribution upon completion, cancellation, or dispute resolution
* Interfacing with NovaJury when a dispute is escalated to the decentralized jury system

NovaCont inherits from three OpenZeppelin base contracts:

**ReentrancyGuard**: Prevents reentrancy attacks on all functions that move funds. Every external call that touches ETH or ERC-20 balances is wrapped with the `nonReentrant` modifier.

**Ownable2Step**: Implements a two-step ownership transfer mechanism. The new owner must explicitly accept ownership before the transfer is finalized, preventing accidental or malicious ownership transfers to invalid addresses.

**Pausable**: Allows the contract owner to pause all state-modifying operations in the event of a critical vulnerability or emergency. Pausing does not affect fund withdrawals — users can always reclaim their funds even when the contract is paused.

### NovaJury - The Arbitration Layer

NovaJury is the dispute resolution contract. It operates independently from NovaCont and is responsible for:

* Managing the juror pool, including staking, warnings, slashing, and ejection
* Receiving dispute cases forwarded by NovaCont
* Collecting and distributing dispute fees between parties and jurors
* Assigning jurors randomly to cases and managing the voting lifecycle
* Returning final verdicts to NovaCont for on-chain execution

NovaJury inherits the same three OpenZeppelin base contracts (ReentrancyGuard, Ownable2Step, and Pausable) for the same security reasons.

### How the Two Contracts Communicate

NovaCont and NovaJury communicate through a set of tightly controlled interfaces. Neither contract can call arbitrary functions on the other. Only specific, explicitly defined entry points are exposed.

**NovaCont → NovaJury:** When a dispute is opened in jury mode, NovaCont calls `INovaJury.createCase()` on the NovaJury contract, passing all relevant case data including the contract ID, party addresses, agreed price, evidence URI, and dispute reason URI. NovaCont also calls `INovaJury.computeDisputeFeePerParty()` to determine the correct fee before initiating the transfer.

**NovaJury → NovaCont:** When a verdict is finalized, NovaJury calls `settleDisputeByJury()` on NovaCont, passing the contract ID, case ID, and the provider's basis point allocation. NovaJury also calls `onCounterFeePaid()` to notify NovaCont when the counter party has paid their share of the dispute fee.

**Access control:** All calls from NovaJury to NovaCont are protected by the `onlyJuryContract` modifier — only the registered NovaJury address can invoke these functions. Symmetrically, all calls from NovaCont to NovaJury are the only way cases can be created — external actors cannot inject cases directly into NovaJury.
