AUDIT.md — sun audit: Aderyn with Controlled TVM Degradation¶
Living reference for internal/audit and the sun audit command. Tier-1
authority is docs/ARCHITECTURE.md §5.8.
1. The pinned binary¶
sun audit runs Cyfrin Aderyn, managed
exactly like solc (ARCHITECTURE §1.5): version pinned in sail.toml,
downloaded on demand into <SAIL_HOME>/bin/aderyn-<version>, and never
executed without a SHA-256 match. The release ships .tar.xz archives;
the digest pinned per platform is that of the extracted binary, verified
before the file ever becomes executable and re-verified on every run
(compiler.EnsureManaged, the generalized solc manager).
[aderyn]
version = "0.6.8"
[aderyn.checksums]
"darwin/arm64" = "8cb4f272…"
"darwin/amd64" = "a3f47a3d…"
"linux/arm64" = "77303383…"
"linux/amd64" = "a268d616…"
Windows: upstream publishes no Windows asset — sun audit on Windows
reports exactly that (no pinned aderyn binary for windows/amd64: upstream
(Cyfrin/aderyn) publishes no Windows asset) instead of failing obscurely.
SAIL_ADERYN_URL overrides the download URL (mirrors/air-gapped setups);
the checksum requirement is unaffected.
2. Per-file execution and degradation¶
Aderyn is executed once per src/**/*.sol file (aderyn . -i <file> -o
<tmp>.json). A file it cannot parse — TVM syntax such as trcToken,
msg.tokenvalue or the Stake 2.0 APIs — makes that invocation print a
Compilation Error and write no report (observed v0.6.8 behavior, which
exits 0 either way); sun audit degrades that file to a
SKIPPED (TVM syntax) row and the rest of the project is analyzed normally.
Any other per-file failure is reported as that file's error — the set is
never aborted.
3. The TVM post-filter — visible, never silent¶
Findings from detectors whose premises are EVM-specific are suppressed with a recorded reason, kept in the report, and rendered collapsed:
| Detector | Reason |
|---|---|
push-zero-opcode |
The TVM ships Shanghai's PUSH0 (schedule-enabled); the missing-opcode warning targets other chains. |
selfdestruct |
Aderyn models EIP-6780 Ethereum semantics; the TVM implements TIP-6780 with TRON-specific eligibility rules. |
--show-suppressed lists them inline with their reasons. Suppressed findings
never count toward --fail-on.
Every output ends with the fixed limitations section:
static analysis with EVM semantics; TVM divergences (energy model, TVM-specific opcodes, TIP-6780 selfdestruct, 0x41 CREATE2) are not modeled
4. Output formats¶
- Terminal:
SEVERITY · FILE:LINE · RULE · DESCRIPTION, grouped high → low, followed by SKIPPED/ERROR rows, the counts line, and the limitations. --json(global flag): stable structured dump (files, findings with suppression flags, counts, limitations) for CI.--report <path.md>: passthrough of Aderyn's native markdown report — one extra whole-project run with the skipped files excluded (-x).--fail-on <low|medium|high>: exit ≠ 0 when any unsuppressed finding reaches the threshold. Aderyn v0.6 reports only high/low, somediumbehaves likehigh. Default: report and exit 0 — the failure policy belongs to CI, not the tool (§5.8).
5. Testing¶
Hermetic (make check and make e2e): a fake aderyn shell script reproduces
the observed v0.6.8 contract — per-file JSON, markdown passthrough, and the
Compilation-Error-without-report degradation signal — via the
SAIL_ADERYN_BIN override, so no download ever happens in the gates. The
managed-download path (tar.xz extraction, checksum refusal, atomic install)
is covered by internal/compiler/binmgr_test.go against an in-process HTTP
server. The real-binary flow was validated manually on Nile's scaffold
project (v0.6.8: 5 low findings on Counter.sol, 1 suppressed).