> 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/audit-and-security/novacont-security-review.md).

# NovaCont Security Review

### Scope

* NovaCont.sol
* NovaJury.sol

### Methodology

* Static analysis: Slither v0.11.5, 101 detectors, run across two separate compilation passes.
* Every Medium+ finding was manually verified against the source code; cases where static analysis missed relevant context are documented and justified in a separate section below.

| Severity          | Count | Note                                                                                                                                                   |
| ----------------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Critical / High   | 0     | -                                                                                                                                                      |
| Medium (verified) | 0     | All 4 candidates were reviewed and closed as "Reviewed & Not Exploitable" below, with justification                                                    |
| Low               | 8     | Immutable optimization (2), missing event emission (2), missing-zero-check (OZ library code), solc version pinning, costly-loop, cyclomatic-complexity |
| Informational     | 110   | Naming convention (\~90), assembly/low-level-calls (OZ library code), timestamp usage, unused-state                                                    |

### Findings — Reviewed and Determined Not Exploitable

Four findings flagged by Slither and closed after manual review:

#### Oracle Round Validation (unused-return)

Slither flagged that part of the return values from "feed.latestRoundData()" were unused. Code review confirmed that "getLatestTokenUSDPrice" already implements both the "updatedAt" staleness check and the "answeredInRound >= roundId" stale-round check. The finding stems from Slither producing a false positive on a partial tuple-discard pattern (the "startedAt" field, left as "None").

#### Cross-Function Reentrancy (reentrancy-eth, reentrancy-no-eth)

"createContract", "disputeWork", "joinJury", and "payCounterFee" all carry the "nonReentrant" modifier. Because OpenZeppelin's "ReentrancyGuard" uses a single, contract-wide lock, entry into any other "nonReentrant" function is blocked while one is executing. The write to "dd.linkedCaseId" after the external "createCase" call in "disputeWork" is a pattern Slither flags as a checks-effects-interactions violation, but the active lock makes re-entry in this scenario effectively impossible.

#### Uninitialized Locals (\_assignJurors.selected, \_processJurorOutcomes.voters)

"\_assignJurors" is guarded at the end of its loop by "require(pickedCount == JURORS\_PER\_CASE, "Not enough eligible jurors")" if the pool doesn't contain enough eligible jurors, the function reverts entirely; a partially filled array can never be returned. "\_processJurorOutcomes" never accesses the unfilled portion of the "voters" array, since the loop bound is strictly defined by "voterCount"; "address(0)" slots are never processed.

#### Divide-Before-Multiply (cancelContract, computeDisputeFeePerParty)

In both locations, division happens before multiplication. The magnitude of the affected amount is roughly 1 wei (\~$0.000000000003)on the Ethereum side, and roughly 1 unit in the 8-decimal price format used by the oracle calculation ($0.000000005). In practice, this would need to occur millions of times before any user or the protocol experienced a measurable loss. It has no effect on fund safety or fund lockup.

### Low Severity

<table><thead><tr><th>Finding</th><th>Recommendatiton</th><th data-hidden></th></tr></thead><tbody><tr><td>usdtToken/usdt could be immutable</td><td>If set once in the constructor, mark as immutable a gas saving with no downside</td><td></td></tr><tr><td>setJuryContract, setNovaContAddress don't emit events</td><td>An event should be added for transparency</td><td></td></tr><tr><td>USDT_DECIMALS is unused</td><td>Dead code, should be removed</td><td></td></tr><tr><td>replaceInactiveJuror has high cyclomatic complexity</td><td>Not a functional bug, but splitting it into sub-functions is recommended for maintainability and auditability</td><td></td></tr><tr><td>solc ^0.8.20 includes known compiler bugs</td><td>No assembly/verbatim usage in the project itself</td><td></td></tr></tbody></table>

### Conclusion

Static analysis surfaced **no Critical or High severity findings** in the codebase. All 4 Medium candidates were closed as "Not Exploitable" after manual review, with justifications documented above. The remaining findings are gas optimizations, code style, or already-known and accepted design decisions. This result does not replace an independent third-party audit, but it is a positive signal about the current maturity of the codebase.
