Security Model
Anvil256 — Security Model
1. Assets
| Asset | Location | Formal Protection |
|---|---|---|
| Unminted ANVL supply | Intrinsic to Anvil256.sol | Minted on valid only; totalSupply ≤ MAX_SUPPLY (I1) |
| Minted ANVL | ERC-20 balances | Standard ERC-20 transfer semantics |
| Protocol fee ETH | feeRecipient (immutable) | address immutable feeRecipient; no setter (I2) |
| POL reserve ETH | lpReserveEthWei | 50% of each protocol fee until deployed/dripped to official LP |
| POL reserve ANVL | lpReserveTokenWei / official LP NFT | 10% of each miner reward, minted inside MAX_SUPPLY |
| Stuck-fee ETH | stuckFeesWei | Sweepable by anyone, permissionless |
| Operator private keys | Operator’s machine only | Never transmitted; not in scope |
| Difficulty state | currentDifficulty, integralErrorWad | (I5); $ |
| Miner temporal identity | minerEpochCount[m] = | Monotonic, non-transferable (I13) |
| NCT window state | minerWindow, uniqueCount, windowFreq | (I11); updated before external calls (§4.4) |
| Epoch entropy | epochEntropy, lastMineBlock | Set after difficulty adjustment; commits to post-adjustment |
2. Adversary Classes
| Class | Formal Capability |
|---|---|
| External miner | Run any client; submit any (nonce, address) pair as mine() input |
| Precompute attacker | Compute candidate values before is known |
| Wallet rotation attacker | Generate fresh addresses; attempt to reduce below |
| NCT Sybil attacker | Operate addresses to suppress while controlling hashrate |
| MEV searcher | Observe mempool; reorder or front-run mine() transactions |
| Malicious RPC | Censor or misrepresent eth_call / eth_getTransactionReceipt responses |
| Compromised Chainlink oracle | Return malformed latestRoundData() |
| Fee recipient compromise | Drain future fee accumulations |
| Post-deployment deployer | No privileges — contract is fully immutable post-constructor |
3. Protocol Invariants
Definition 3.1 (Protocol Invariant). A predicate over the contract state is a protocol invariant iff it holds in all reachable states — i.e., for all sequences of valid calldata starting from the deployment state.
| ID | Invariant | Formal Statement |
|---|---|---|
| I1 | Supply cap | totalSupply(S) <= MAX_SUPPLY = 21,000,000e18 for all reachable states |
| I2 | Fee recipient immutability | feeRecipient is immutable; no setter exists |
| I3 | Deployer separation | Constructor enforces feeRecipient != msg.sender and feeRecipient != address(0) |
| I4 | Oracle non-null | Constructor enforces _ethUsdFeed != address(0) |
| I5 | Difficulty floor | for all |
| I6 | Epoch monotonicity | currentEpoch[n+1] = currentEpoch[n] + 1 after each valid mine() |
| I7 | Fee correctness | After mine(): feeRecipient delta + stuckFeesWei delta + lpReserveEthWei delta = currentFeeWei() exactly |
| I8 | Refund correctness | msg.sender refunded |
| I9 | Halving terminus | for ; mine() reverts MiningEnded() unless MAX_SUPPLY is reached earlier |
| I10 | Anti-windup | integralErrorWad remains inside [-I_MAX * WAD, +I_MAX * WAD] |
| I11 | Window integrity | after first mine; exactly |
| I12 | Cascade correctness | mine(ν) verifies before any state mutation |
| I13 | -monotonicity | minerEpochCount[m] is strictly non-decreasing; never decremented or transferred |
4. Threat Analysis and Mitigations
4.1 Cryptographic Assumptions
Model. is modelled as a random oracle with uniform output distribution.
| Threat | Security Bound |
|---|---|
| Preimage attack on | (preimage resistance) |
| Collision attack on | Birthday bound: queries needed for collision with probability |
| Length-extension attack | Not applicable: Keccak uses sponge construction, not Merkle–Damgård |
4.2 Cascade Precomputation — Formal Theorem
Theorem 4.1. Under the random oracle model, for any PPT adversary and any epoch , the probability that produces a valid nonce strictly before is produced by the sequencer is:
i.e., no better than an online random guess.
Proof. where is derived from
, , and
(PATCH-1: if the 256-block window has expired, and are used alone,
emitting EntropyFallback). In all paths,
is produced at an unknown future time. In the random oracle model, is
uniformly distributed over , independent of all values computable
before is known.
For any function computable by before time :
since with uniform produces a uniform output independent of its first argument. No precomputed set reduces this probability.
Corollary 4.2. ASIC precomputation of rainbow tables over all possible pairs provides no advantage, because the outer pass requires — a mandatory per-epoch network fetch.
4.3 Wallet Rotation Attack — Complete Analysis
| Attack | Formal Mitigation |
|---|---|
| Fresh address fresh cheap challenge | . Distinct from all with , but difficulty is identical. No cost reduction. |
| fresh addresses suppress NCT | Each address must mine at \0.10\sigma(k) = k \times $0.10$ (Theorem 1.9, MATH.md). Equals genuine mining cost. |
| Accumulate on one address then rotate | is non-transferable (I13). Accumulated history stays with original address. |
| Replay high- address’s from another address | includes directly. (collision resistance of ). |
Theorem 4.3 (Rotation Equivalence). For all and window cycles:
The Sybil cost per apparent independent miner equals the legitimate mining cost. No adversary benefits from wallet rotation.
4.4 NCT Attacks
| Attack | Mitigation |
|---|---|
| Sybil: fake distribution with wallets | \sigma(k) = k \times \0.10$ (Corollary 1.10). No advantage. |
| Window stuffing: saturate buffer to reset | Same \0.10/\text{slot}$ cost floor; no free writes. |
| Reverse Sybil: concentrate to harm competitors | NCT penalty raises difficulty for everyone, including the concentrator. |
| Manipulate via reentrancy | nonReentrant modifier; and windowFreq updated atomically before any external calls. |
Concentration equilibrium. The NCT update function:
achieves its minimum over strategies at (since is minimised, i.e., zero). This is the unique Nash equilibrium.
4.5 Replay and Cross-Miner Attacks
| Attack | Formal Exclusion |
|---|---|
| Resubmit nonce in next epoch | with probability (random oracle independence) |
| Steal nonce solved by miner and submit as | for valid nonce for is invalid for |
| Replay across deployments | differs across deployments; is genesis-bound |
| Replay across chain forks | Contract address differs; is address-included |
Proposition 4.4. For , (collision resistance of , applied at the -layer).
4.6 Oracle Attack Surface
The fee formula depends on the Chainlink ETH/USD feed. Attack surface and mitigations:
| Scenario | On-Chain Response | Off-Chain Response |
|---|---|---|
| Stale price ($ | t - \texttt{updatedAt} | > 24;\text{hours}$) |
answeredInRound < roundId | Revert StaleOracle (O5) | — |
Revert InvalidOracle | — | |
Revert OracleClockSkew | — | |
| Inflated (oracle compromise) | : mine cheapens, not blocks | Client-side MAX_FEE_USD aborts if \texttt{fee\_wei}/p_\ > \text{cap}$ |
| Deflated (oracle compromise) | inflates: mine becomes expensive | Client-side MAX_FEE_USD aborts submission |
| Round ID sequence gap (phase boundary) | Not checked — gap check produces false positives | — |
Risk. Oracle compromise can cause temporary fee spikes or drops. It cannot cause loss of minted ANVL, cannot modify , and cannot violate I1–I13.
4.7 Difficulty Controller — Stability Under Adversarial Input
The controller operates on . Its stability properties under adversarial hashrate perturbations:
| Perturbation | Bound | Mechanism |
|---|---|---|
| Hashrate flash spike | can at most per period | Outer envelope |
| Sustained hashrate increase | PI integrator accumulates error; converges | Lyapunov stable (MATH.md §3.3) |
| Integrator windup | $ | I |
| NCT overflow | ; | (I11) bounds above |
| Difficulty collapse to zero | always | Floor enforced in PIController.step (I5) |
4.8 Fee Mechanics — Accounting Invariant
Invariant I7 (Fee Accounting). After every successful mine():
where devFee is 50% of the protocol fee and is forwarded to feeRecipient
(or parked in stuckFeesWei on failure), and lpFee is 50% and accumulates
in lpReserveEthWei.
Proof sketch. The mine() function:
- Reads
- Asserts ; refunds excess to
msg.sender - Splits: ;
- Accumulates into
lpReserveEthWei(always succeeds, no external call) - Attempts
feeRecipient.call{value: f_dev}(""):- On success:
feeRecipient.balance += f_dev. . - On failure:
stuckFeesWei += f_dev. .
- On success:
In all branches:
and , so their sum equals .
stuckFeesWei is sweepable permissionlessly to protect against DoS on feeRecipient.
Note. The stuckFeesWei mechanism applies only to devFee. The LP share
goes directly to lpReserveEthWei via in-contract accounting and is never
subject to a reverting external call.
4.9 MEV and Sequencer Reordering
Each mine() is statistically independent. The valid nonce for miner
is invalid for (Proposition 4.4). Therefore:
- Front-running is unprofitable: a front-runner cannot use miner ‘s nonce; they must solve the puzzle for their own address.
- Reordering only transfers the slot: if two valid
mine()calls from and compete, reordering awards the epoch to one of them — no additional value is extractable. - No arbitrage exists: unlike DEX swaps,
mine()contains no price-sensitive state to exploit.
Formal: MEV strategy with positive expected value beyond the mining reward itself, which requires solving the Cascade PoW.
4.10 Supply Chain — Build Integrity
| Layer | Guarantee | Mechanism |
|---|---|---|
| Source code | Public, reviewed | GitHub; audit report published |
| Binary | Reproducible build | Docker image pins compiler versions; sha256sums.txt matches across builds |
| Release signing | Cosign + Sigstore Rekor | cosign verify-blob with GitHub OIDC identity |
| Contract | Bytecode verified | Basescan source verification; bytecode hash matches signed release |
5. Out of Scope
- Sequencer-level censorship on Base validators.
- Chainlink’s internal oracle security model and aggregator architecture.
- Operator wallet hygiene and private key storage.
- Power or infrastructure failures on the operator’s machine.
- Consensus-layer forks of Base
6. Invariants That Are Never In Scope for Modification
The following properties are on-chain invariants of the immutable contract. No future action can modify them:
7. Responsible Disclosure
Vulnerability reports: security@anvil256.xyz (PGP key published on website).
Coordinated disclosure window: 90 days from acknowledgement.