> For the complete documentation index, see [llms.txt](https://docs.evently.market/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.evently.market/audit-reports-ai/claude.md).

# Claude Opus 4.6

**Tool:** Claude Opus 4.6 (Anthropic) **Type:** 3-round AI audit (Systematic → Economic → Triage) **Contracts reviewed:** EventlyProfiles.sol · EventlyMarkets.sol (LMSR b=200 + CLOB bids/asks) **Chain:** MegaETH (Chain ID 4326) — Solidity ^0.8.20 **Dependencies:** OpenZeppelin ERC-1155 / SafeERC20, PRBMath SD59x18 **Date:** March 2026 **Status:** Complete

***

## Summary

Full audit of EventlyMarkets covering the LMSR AMM, CLOB order book (bids & asks), ERC-1155 position system, dispute mechanism, and collateral/fee flows. All previously identified vulnerabilities (F-02, A-03, F-DS-M02, R2-2, L-01) confirmed patched. Four additional findings (GROK-M01, GPT-R3-3, GROK-L02, QWEN-I03) identified and resolved. **No production blockers remain.**

| Severity      | Count |
| ------------- | ----- |
| Critical      | 0     |
| High          | 0     |
| Medium        | 1     |
| Low           | 4     |
| Informational | 1     |
| **Total**     | **6** |

***

## Round 1 — Systematic Vulnerability Scan

### Reentrancy

All external state-mutating functions use `nonReentrant` mutex (`_locked`). CEI (Checks-Effects-Interactions) pattern is correctly followed throughout:

* `placeOrder`: USDm/shares transferred in at top; all state updates before external calls (seller transfers, share transfers, AMM mint)
* `sellToAMM`: quantities and balance decremented, shares burned, \_collectFees called — all before `usdm.safeTransfer`
* `redeemWinnings`: shares burned, balances decremented before transfer
* `claimCancelRefund`: pre-burn snapshot, then burn, then transfer — F-02 fix correctly implemented
* `cancelOrder`: order deactivated, amounts zeroed before `safeTransfer` / `_safeTransferFrom`
* `disputeMarket`: state set before transfer
* `settleDispute`: state fully updated before `usdm.safeTransfer` to disputer
* `resolveMarket`, `cancelMarket`, `slashMarket`: now protected by `nonReentrant` (L-01 fix) ✅

**No reentrancy vulnerabilities found.**

### Access Control

* `onlyAdmin`: correctly restricts `withdrawTreasury`, `transferAdmin`, `settleDispute`, `slashMarket`, `setResolverPoolAddress`, `setFees`, `burnLosingShares`
* `onlyWhitelisted`: correctly gates `placeOrder`, `sellToAMM`, `disputeMarket`, `createMarket` when `whitelistEnabled = true`
* `transferAdmin`: zero-address check present ✅
* `resolveMarket`: checks `msg.sender == m.creator` and timing bounds ✅
* `claimCreatorFees`: requires `Finalized` status — implicitly blocks `Disputed` (R2-2 fix) ✅

**L-02 (Low):** Single admin key is a centralization risk. Admin can call `slashMarket`, drain treasury, override dispute outcomes, and trigger `burnLosingShares`. Mitigated by planned Gnosis Safe multisig post-raise. Acknowledged design tradeoff.

### Integer Arithmetic

* Solidity ^0.8.20 built-in overflow protection ✅
* LMSR math uses PRBMath SD59x18 — audited fixed-point library ✅
* Fee calculations: `(amount * BPS) / 10000` — correct order, no precision loss beyond 1 wei per operation ✅
* `redeemWinnings` payout: `payout = shares` (1 share = 1e18 = 1 USDm) — no rounding, exact ✅
* `claimCancelRefund` pro-rata: `(poolBalance * userTotal) / allTotal` — standard floor division, last redeemer may receive 1 wei less. Acceptable.

**L-03 (Low):** In `quoteBuy`, the binary search upper bound is `maxQ = 26000e18` (\~26,600 USDm worth of shares per tx). Derived from the SD59x18 `exp` overflow limit at `q/b ≈ 133`. Documented in NatSpec.

### Token Handling

* `SafeERC20` used for all USDm transfers ✅
* ERC-1155 shares: minted on AMM buy, burned on sell/redeem, `optionSupply` tracking mirrors ERC-1155 supply correctly
* CLOB fills: shares transferred from contract escrow (ASK) or minted (AMM BUY) to buyer

**L-04 (Low):** `optionSupply[marketId][opt]` is manually maintained alongside `_mint`/`_burn`. Peer ERC-1155 transfers via `safeTransferFrom` do not update `optionSupply` — it tracks total minted supply, not per-wallet balances. The math in `redeemWinnings` (uses `balanceOf`) and `claimCancelRefund` (uses `optionSupply`) remains correct by design. Acknowledged.

### CLOB Order Book

The CLOB replaces the previous P2P sell-only book with full bids and asks:

* **Price-time priority**: orders sorted by price first (ascending for asks, descending for bids), FIFO within same price using `placedAt` timestamp
* **Immediate matching**: `placeOrder` matches against the opposite book before creating a resting order
* **Dead entry cleanup (F-DS-M02 fix)**: `_cleanBook` called immediately on `cancelOrder`, preventing permanent DoS of a book
* **Book cap**: `MAX_ORDERS_PER_BOOK = 200` per (market, option, side) pair — griefing cap maintained ✅
* **AMM fallback**: unmatched BUY budget routed to LMSR AMM — ensures liquidity always available

**No CLOB-specific vulnerabilities found.**

### LMSR Math Verification

The cost function `C(q) = b × ln(Σ exp(q[i]/b))` is correctly implemented in `_lmsrCost`. Verified properties:

* **Initial price symmetry:** At `quantities = [0,0,...,0]`, all options have price 1/n ✅
* **Price sum invariant:** `Σ P(i) = 1` always ✅
* **Monotonicity:** Buying option i increases P(i), decreases P(j≠i) ✅
* **Solvency:** `poolBalance + subsidyDeposited ≥ total winning shares` — proven by LMSR cost function bound ✅

***

## Round 2 — Economic Attack Analysis

### LMSR Solvency

**Proof:** `poolBalance + subsidyDeposited = C(q_final) ≥ quantities[winning_opt]` = total winning shares minted. `redeemWinnings` draws from `poolBalance` first, then `subsidyDeposited`. **SOLVENT by mathematical guarantee.** ✅

### F-02 Fix Verification

`claimCancelRefund` snapshots `allTotal` before burning. Multiple sequential claimers cannot extract more than `poolBalance`. ✅

### F-DS-M02 Fix Verification

`cancelOrder` now calls `_cleanBook` immediately after marking the order inactive. Dead entries are removed on the same transaction. An attacker who fills a book with 200 orders and cancels them all will see the book length drop to 0 — no permanent DoS possible. ✅

### R2-2 Fix Verification

`claimCreatorFees` requires `m.status == MarketStatus.Finalized`. While a market is `Disputed`, its status is `Disputed` — not `Finalized` — so the require reverts. No front-run path exists: the creator cannot claim fees during the dispute window. ✅

### Fee Accounting

`_collectFees` correctly splits into creator, treasury, and resolver cuts. Admin markets redirect creator cut to treasury. Creator fees locked until finalization. On slash or lost dispute: `creatorAccruedFees` zeroed to treasury. ✅

**M-01 (Medium) — Multi-ledger accounting:** In `sellToAMM`, `poolBalance -= grossUsdm` before `_collectFees` returns `netUsdm`. Fees (grossUsdm - netUsdm) are credited to treasury/resolver/creator balances but not deducted separately from poolBalance — this is correct since `poolBalance` is reduced by gross. The implicit invariant `poolBalance + treasuryBalance + resolverPoolBalance + Σ creatorAccruedFees = total USDm held` should be validated by formal invariant tests. No discrepancy found.

### Auto-Burn Economic Model

`burnLosingShares` is callable by admin only, 24h after finalization. The BURN\_DELAY matches DISPUTE\_WINDOW, so winning and losing determination is always final before the burn. The keeper-driven model is appropriate for MegaETH's environment. ✅

***

## Round 3 — Adversarial Triage

### Can funds be stolen?

* `withdrawTreasury`: `onlyAdmin`, draws from `treasuryBalance` only ✅
* `redeemWinnings`: burns shares before transfer, subsidy drawn only for shortfall ✅
* `claimCancelRefund`: pre-burn snapshot prevents over-extraction ✅
* `claimCreatorFees`: `onlyCreator`, requires `Finalized`, one-time flag ✅
* `cancelOrder`: returns only escrowed funds to `msg.sender == o.maker` ✅
* `settleDispute`: slash mechanism intended; only activates on dishonest resolution ✅
* `burnLosingShares`: `onlyAdmin`, burns worthless losing shares only — no USDm movement ✅

**Verdict: No direct fund theft path found.**

### Can the contract be bricked?

* `transferAdmin(address(0))`: blocked ✅
* `_cancelAllOrders` in `resolveMarket`/`cancelMarket`/`slashMarket`: max 200 asks + 200 bids × 4 options = 1,600 iterations. Safe on MegaETH. **L-05 (Low):** On L1-like environments this could hit gas limits; noted for any future multi-chain deployment.
* LMSR `exp` overflow: `quoteBuy` cap at 26,000e18. ✅
* CLOB dead entries: cleaned immediately on cancel — no permanent DoS possible (F-DS-M02 fix). ✅

**Verdict: No bricking path found.**

### ERC-1155 Transfer Hook

No `_beforeTokenTransfer` override. Shares are freely transferable. `redeemWinnings` uses `balanceOf` (actual balance) so peer transfers don't break redemption. `optionSupply` tracks total minted, not per-wallet — by design. ✅

**I-01 (Info):** Empty ERC-1155 URI — no metadata for position tokens. URI to be added pre-deployment.

***

## Findings Table

| ID   | Severity | Contract       | Title                                                              | Status                                   |
| ---- | -------- | -------------- | ------------------------------------------------------------------ | ---------------------------------------- |
| M-01 | Medium   | EventlyMarkets | Implicit multi-ledger accounting — recommend formal invariant test | Acknowledged — recommend test coverage   |
| L-02 | Low      | EventlyMarkets | Single admin key — centralization risk                             | Acknowledged — Gnosis Safe post-raise    |
| L-03 | Low      | EventlyMarkets | `quoteBuy` max capacity \~26,600 USDm/tx                           | Acknowledged — documented in NatSpec     |
| L-04 | Low      | EventlyMarkets | `optionSupply` not updated on peer ERC-1155 transfers              | Acknowledged — by design, math correct   |
| L-05 | Low      | EventlyMarkets | `_cancelAllOrders` gas bound on L1-like chains                     | Acknowledged — safe on MegaETH           |
| I-01 | Info     | EventlyMarkets | Empty ERC-1155 URI                                                 | In resolution — URI added pre-deployment |

***

## Confirmed Fixed

| ID       | Title                                                                | Verification                                                                                 |
| -------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| F-02     | `claimCancelRefund` insolvency — double-counted burned shares        | **Resolved.** Pre-burn snapshot in `claimCancelRefund`. ✅                                    |
| A-03     | Order book griefing — no MAX\_ORDERS cap                             | **Resolved.** `MAX_ORDERS_PER_BOOK = 200` per side per (market, option). ✅                   |
| F-DS-M02 | Dead CLOB entries permanently block new orders                       | **Resolved.** `_cleanBook` called in `cancelOrder` — dead entries removed immediately. ✅     |
| R2-2     | Creator front-runs `settleDispute` to claim fees before slash        | **Resolved.** `claimCreatorFees` requires `Finalized` status — `Disputed` markets blocked. ✅ |
| L-01     | `resolveMarket`, `cancelMarket`, `slashMarket` lacked `nonReentrant` | **Resolved.** `nonReentrant` modifier added to all three functions. ✅                        |
| G-I01    | Outdated NatSpec — CPMM reference, P2P sell-only description         | **Resolved.** NatSpec updated to LMSR + CLOB (bids & asks). ✅                                |

***

## Production Blockers

**None.** All previously identified vulnerabilities are confirmed patched. LMSR mechanism is mathematically sound. CLOB implementation correctly handles bids and asks with price-time priority. Contract is ready for professional audit engagement.

***

## LMSR-Specific Security Properties

| Property                                  | Verified | Notes                                  |
| ----------------------------------------- | -------- | -------------------------------------- |
| Initial prices = 1/n                      | ✅        | All quantities = 0 → softmax uniform   |
| Σ prices = 1 always                       | ✅        | Softmax invariant                      |
| Solvency: pool + subsidy ≥ winning shares | ✅        | Proven by LMSR cost function bound     |
| 1 share = 1 USDm payout (exact)           | ✅        | `payout = shares` in `redeemWinnings`  |
| Subsidy exhaustion impossible             | ✅        | By solvency proof                      |
| quoteBuy binary search converges          | ✅        | Monotone cost function, bounded domain |

***

## CLOB-Specific Security Properties

| Property                       | Verified | Notes                                                 |
| ------------------------------ | -------- | ----------------------------------------------------- |
| Price-time priority maintained | ✅        | `_insertSorted` + `placedAt` timestamp                |
| Dead entries cannot block book | ✅        | `_cleanBook` in `cancelOrder` (F-DS-M02)              |
| BUY escrow always sufficient   | ✅        | `usdmEscrowed = qty * price / SHARE_UNIT`             |
| SELL escrow returned on cancel | ✅        | Shares transferred back in `cancelOrder`              |
| No double-spend via order+AMM  | ✅        | AMM phase uses only remaining budget after CLOB fills |
| Book cap enforced              | ✅        | `MAX_ORDERS_PER_BOOK = 200` per side                  |

***

## Severity Scale

| Severity      | Definition                                         |
| ------------- | -------------------------------------------------- |
| Critical      | Direct fund loss, immediate production blocker     |
| High          | Fund loss possible under specific conditions       |
| Medium        | DoS, griefing, or logic error with economic impact |
| Low           | Edge case, minor logic issue, or gas concern       |
| Informational | Code quality, missing feature, or best practice    |

Status options: Fixed · Resolved · In resolution · Acknowledged · By design


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.evently.market/audit-reports-ai/claude.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
