System design · AREX-AUD-001
Audit Readiness Package
This document is what an external auditor receives on day one: scope, build instructions, invariants, threat model pointers, test coverage matrix, known limitations and the questions we want answered. It does not replace
- Document ID
- AREX-AUD-001
- Version
- 1.0
- Date
- 2026-09-21
- Source
- docs/AUDIT-READINESS.md
| Field | Value |
|---|---|
| Document ID | AREX-AUD-001 |
| Version | 1.0 |
| Status | Ready for external audit engagement |
| Date | 2026-09-21 |
| Owner | A-REX Contributors |
| Applies to | contracts/standard/*, contracts/reference/core/*, contracts/reference/hooks/*, contracts/reference/extensions/* at tag v2.0.0-alpha.2 |
1. Purpose
This document is what an external auditor receives on day one: scope, build instructions, invariants, threat model pointers, test coverage matrix, known limitations and the questions we want answered. It does not replace an audit; the audit is a stated precondition for a production anchor and for submitting the ERC.
2. Scope
| Component | File | Deployed size (bytes) | In scope |
|---|---|---|---|
| Standard interfaces | contracts/standard/*.sol | — | Yes (semantics) |
| Reference token | contracts/reference/core/ARexToken.sol | 24,136 | Yes — primary |
| Attestation registry | contracts/reference/core/ARexAttestations.sol | 2,708 | Yes — primary |
| Hook base | contracts/reference/hooks/ARexHookBase.sol | — | Yes |
| EligibilityHook | contracts/reference/hooks/EligibilityHook.sol | 3,103 | Yes |
| ExpiryHook | contracts/reference/hooks/ExpiryHook.sol | 1,358 | Yes |
| AttestationHook | contracts/reference/hooks/AttestationHook.sol | 1,873 | Yes |
| PerishabilityHook | contracts/reference/hooks/PerishabilityHook.sol | 5,091 | Yes |
| SeasonalHook | contracts/reference/hooks/SeasonalHook.sol | 3,240 | Yes |
| DeliveryHook | contracts/reference/hooks/DeliveryHook.sol | 6,215 | Yes |
| TraceabilityHook | contracts/reference/hooks/TraceabilityHook.sol | 4,076 | Yes |
| CommodityPriceOracle | contracts/reference/extensions/CommodityPriceOracle.sol | 4,396 | Yes |
| CarbonImmobilizationWrapper | contracts/reference/extensions/CarbonImmobilizationWrapper.sol | 4,588 | Yes |
| ParametricInsurance | contracts/reference/extensions/ParametricInsurance.sol | 3,716 | Yes |
| Test mocks | **/mocks/* | — | No |
Lines of Solidity in scope: about 2,600.
3. Build and test
npm ci # OpenZeppelin 5.3.0 pinned by lockfile
npx hardhat compile # solc 0.8.22, viaIR, evm paris; ARexToken with optimizer.runs = 1
npm test # reference implementation, hooks, extensions, invariants (46 tests)
npm run interface-ids # ERC-165 ids
npx hardhat run scripts/gas-report-standard.js
AREX_INVARIANT_STEPS=2000 AREX_INVARIANT_SEED=1 npx hardhat test test/standard/Invariants.test.js
4. Trust model
| Role (contract) | Power | Expected holder |
|---|---|---|
DEFAULT_ADMIN_ROLE (token) | grant/revoke roles, base URI | governance multisig + timelock |
UPGRADER_ROLE (token) | replace implementation (total) | governance multisig + timelock |
HOOK_ADMIN_ROLE (token) | add/remove/reorder rules | governance multisig + timelock |
ENFORCER_ROLE (token) | freeze any amount, force any transfer | enforcement multisig with documented procedure |
PAUSER_ROLE (token) | halt all but forced transfers | incident response key |
ISSUER_ROLE, STATUS_ROLE, TRANSFORMER_ROLE (token) | create lots; change status/metadata; process | operational services, least privilege |
ATTEST_ADMIN_ROLE (attestations) | trusted issuers; admin revoke | certification authority / platform |
MANAGER_ROLE (hooks) | rule parameters | per hook owner |
ARBITER_ROLE, SENSOR_ROLE (DeliveryHook) | disputes; readings | arbitration provider; IoT gateway |
REPORTER_ROLE, MANAGER_ROLE (oracle) | price submissions; parameters | data providers |
REGISTRAR_ROLE (carbon) | immobilisation records | party with registry account |
UNDERWRITER_ROLE (insurance) | issue policies | insurer |
Hooks are trusted code: a hook can block all transfers. Registration verifies ERC-165 and non-zero flags only.
5. Invariants (with tests)
| ID | Invariant | Enforced by | Test |
|---|---|---|---|
| INV-1 | Σ balances(id) == totalSupply(id) | ERC1155Supply, _update | Invariants.test.js I1; lineage tests |
| INV-2 | status 255 never changes again | setBatchStatus | Invariants.test.js I2; status tests |
| INV-3 | retired: no mint/transfer, burn allowed | _update | retired-batch test |
| INV-4 | holder moves ≤ balance − frozen | _update | freeze tests; I5 |
| INV-5 | no re-entrance during hook sequence | storage lock | ReentrantHook test |
| INV-6 | hooks evaluated in order; removal preserves order | array shift | ordering test |
| INV-7 | rejection ⇒ no balance change, no onExecuted | checks before super._update | rejection test |
| INV-8 | canTransfer ⇔ transfer succeeds (balance sufficient) | definition | Invariants.test.js I3 |
| INV-9 | forced transfer leaves frozen ≤ remaining balance | forcedTransfer | forced tests |
| INV-10 | authority never from balance | role gates | "holding grants nothing" tests |
| INV-11 | DeliveryHook: lockedUnits ≤ balance at schedule; settlement unlocks exactly amount | schedule/onExecuted | delivery tests |
| INV-12 | Oracle: round ids strictly increase; answer = median of submissions | submit/_finalize | oracle test |
| INV-13 | Carbon: linked + retired ≤ tonnes | linkToBatch/retire | carbon test |
| INV-14 | Insurance: reserved ≤ pool balance at issuance; claim once | issue/claim | insurance test |
6. Threat model pointers
See whitepaper chapter Security Framework and docs/SYSTEM-DESIGN.md §9 for actors, capabilities and scenarios (malicious hook, hook re-entrance, compromised enforcement or upgrader key, status abuse, issuer fraud, metadata substitution, pre-flight staleness, gas griefing, upgradeable hook trust).
7. Test coverage matrix
| Area | File | Tests |
|---|---|---|
| Batches, lineage, ERC-7943, pipeline, attestations, conformance, upgrade, view/transaction order | test/standard/ARexToken.test.js | 31 |
| Perishability, seasonal, delivery, traceability, sanctions TTL | test/standard/DomainHooks.test.js | 8 |
| Price oracle, carbon wrapper, insurance | test/standard/Extensions.test.js | 3 |
| Randomized invariants | test/standard/Invariants.test.js | 1 (120 steps default; configurable) |
| Implementation Guide and documentation examples, executed | test/standard/ImplementationGuide.test.js | 3 |
8. Known limitations and open questions for the auditor
- Data stash in storage.
safeTransferFromwritesdatato storage for hook consumption and deletes it afterwards. Cost is proportional to data length; no security impact identified. Confirm no path leavesopDatapopulated. currentOpcontext.forcedTransferandtransformset a storage flag consumed by_update. Confirm no re-entrant path could observe a stale flag (the lock should prevent it)._isRebatchgating. A holder can transform without a role when commodity/unit are equal and quantities are conserved. Confirm this cannot be abused to launder a batch's identity (issuer becomes the operator; parents are recorded).- Hook DoS. A hook that reverts blocks the token until removed. Accepted by design; confirm
removeHookandpauseare always reachable. - ERC-1155 receiver callback runs after the lock is released (standard behaviour). Confirm state is final before the callback.
- DeliveryHook relies on
data == abi.encode(deliveryId)for settlement. Confirm a third party cannot craft a settlement for someone else's delivery (sender/receiver/amount/batch must match). - PerishabilityHook exponential approximation interpolates linearly within a half-life; check monotonicity.
- Oracle median uses insertion sort bounded by reporter count; confirm no unbounded growth (
_valuesper round). - Upgrade safety: ERC-7201 struct is append-only; confirm no inherited OpenZeppelin storage collisions (validated by the upgrades plugin in tests).
9. Out of scope
Off-chain metadata availability; the identity provider behind eligibility; the legal classification of any offering; the physical existence of goods.
10. Deliverables expected from the audit
Findings with severity and reproduction; confirmation or refutation of each invariant; an opinion on §8; a re-audit of fixes. Publication of the final report is a condition of the engagement.