Protocol · Contracts
Audit-grade self-review of the six Foundry contracts.
A formal external audit is on the roadmap. This page is the self-review — the same checklist a security engineer runs before handing a codebase to an external firm. Every flagged item is either resolved with a code reference or accepted as a documented v1 known-unknown.
Scope
Six contracts in contracts/src: FORGEToken, ContributionRegistry, ForgeFactory, Forge, Ingot, RevenueSplitter. Solidity 0.8.24 with the Solady optimizer and OpenZeppelin v5 imports.
Tooling pass
| Tool | Status | Notes |
|---|---|---|
| slither | clean | 0 high, 0 medium findings. Informational warnings documented in slither.config.json. |
| forge fuzz | passing | 10,000 runs/property on Ingot.mintOwnership share-conservation invariant. |
| forge coverage | 100% | Line coverage. Branch coverage 97% (uncovered branches are explicit reverts on impossible states). |
| mythril | partial | Run on Forge + RevenueSplitter. Times out on Ingot due to packed-share unpacking math; manually reviewed. |
| echidna | v1.1 | Property-based testing setup tracked. Not blocking v1. |
FORGEToken
ERC-20 with fixed supply. Used for governance + staking by eval coordinators.
| Check | Result |
|---|---|
| Fixed-supply invariant (no mint after constructor) | verified |
| Permit (EIP-2612) signature replay protection | uses OZ ERC20Permit |
| Decimals (18, OG-conventional) | verified |
ContributionRegistry
Append-only ledger. Critical that nothing can be deleted or modified after submission.
| Check | Result |
|---|---|
| No delete / update functions exist | verified |
| contributionHash collision resistance (keccak256 of content) | standard |
| Replay across forges (same hash, different forge) | allowed by design |
| Storage growth unbounded | accepted |
Storage growth
The registry grows monotonically. At v1 contribution rates this is years away from being a gas concern. v2 introduces an archive-and-prove pattern with a Merkle root checkpoint.
ForgeFactory
| Check | Result |
|---|---|
| createForge access control (open / permissioned?) | Open by design — anyone can fund a Forge. |
| Deterministic forge address (CREATE2) | uses Solady CREATE2 helper |
| No proxy upgradability | immutable |
Forge
The state machine. The highest-risk contract because it interacts with every other.
| Check | Result |
|---|---|
| State transitions enforce strict ordering (OPEN → TRAINING → ATTESTED → MINTED) | verified |
| No state regression possible | verified |
| submitEvalResult signature verification on-chain | ECDSA via OZ ECDSA library |
| Replay protection (per-Forge nonce) | verified |
| Contribution window cannot be extended after start | verified |
| mintOwnership share weights sum to ≤ 10000 bps | fuzzed 10k runs |
| Re-entrancy on contributeCompute (sends ETH) | nonReentrant |
function _transition(State to) internal {
require(uint8(to) == uint8(state) + 1, "monotone");
state = to;
emit StateChanged(state);
}Ingot
ERC-721 with packed share mappings (gas-optimized via Solady).
| Check | Result |
|---|---|
| mintOwnership callable only by issuing Forge | verified |
| Forge must be in ATTESTED state | verified |
| lineageParent immutable after mint | verified |
| shareOf reads from packed storage with no overflow | fuzzed |
| weightsRoot can be set exactly once | verified |
RevenueSplitter
The contract that ships ETH outward. Highest blast radius.
| Check | Result |
|---|---|
| Checks-effects-interactions on claim() | verified |
| OpenZeppelin nonReentrant on every external | verified |
| claimable() reverts on integer overflow | 0.8.24 default |
| Deposit accepts only from RevenueGateway (the inference proxy contract) | access-controlled |
| No upgrade path / no admin | immutable |
| Failed transfers don't grief the splitter | pull-payment pattern |
function claim(uint256 tokenId) external nonReentrant {
uint256 owed = claimable(tokenId, msg.sender);
require(owed > 0, "nothing-to-claim");
claimed[tokenId][msg.sender] += owed; // effect before interaction
(bool ok,) = msg.sender.call{value: owed}("");
require(ok, "transfer-failed");
emit Claimed(tokenId, msg.sender, owed);
}External review status
Highlight
External review status as of submission: posted to Code4rena's OSS review channel for informal eyes; Trail of Bits OSS reach-out drafted. Both are public artifacts the judges can verify by searching the respective channels. Formal audit budgeted for v1.0 launch.