Qwen3.5

Tool: Qwen3.5 (Alibaba Cloud) Type: 3-round AI audit (Systematic → Economic → Triage) Contracts reviewed: evently.sol v5.4 · EventlyProfiles.sol v1.3 · EventlyMarketsV3.sol (LMSR, b=200) Chain: MegaETH (Chain ID 4326) — Solidity ^0.8.20 Date: March 2026 Status: Complete — v3.2 post-audit fixes verified


Summary

Severity
Count

Critical

0

High

0

Medium

0

Low

1

Info

3

Total

4

Overall Assessment: The contract demonstrates strong security hygiene with proper CEI patterns, SafeERC20 usage, and correct LMSR implementation. Known fixes (F-02, A-03) are properly applied. No production blockers identified.


Round 1 — Systematic Vulnerability Scan

Reentrancy Protection

CEI Pattern: All external-facing functions with state changes follow Checks-Effects-Interactions. State updates precede safeTransfer/_safeTransferFrom calls.

nonReentrant Modifier: Applied to all functions with external calls: buyShares, sellToAMM, createSellOrder, cancelSellOrder, disputeMarket, settleDispute, claimCreatorFees, redeemWinnings, claimCancelRefund.

LOW-001 [RESOLVED — L-01]: nonReentrant has been added to resolveMarket, cancelMarket, and slashMarket. While CEI is followed (state changes before external calls), adding the modifier provides defense-in-depth against future refactoring risks.

Recommended Fix: Add nonReentrant to resolveMarket, finalizeMarket, cancelMarket, and slashMarket.

Access Control

✅ Clear separation between onlyAdmin, onlyWhitelisted, and creator-only functions. No privilege escalation vectors.

✅ Creator collateral logic correctly uses creatorCollateralReturned flag to prevent double-claims.

✅ Invite code system properly prevents reuse via inviteCodeUsed mapping.

Integer Arithmetic & Fee Precision

✅ Solidity ^0.8.20 provides automatic overflow revert.

✅ Fee rounding dust absorbed by resolverCut:

setFees validates totalBps <= MAX_TOTAL_FEE_BPS (500).

Token Handling

✅ All USDm transfers use safeTransfer/safeTransferFrom.

✅ Proper use of _mint, _burn, _safeTransferFrom with correct token ID encoding (marketId * MAX_OPTIONS + optionIndex).

✅ P2P sell orders properly escrow shares to contract before listing.

LMSR Mathematical Correctness

_lmsrCost correctly implements C(q) = b * ln(Σ exp(qᵢ/b)) with proper fixed-point conversion via PRBMath.

quoteBuy uses tolerance 1e15 (0.001 shares) with proper bracketing and capacity validation.

getPrice maintains Σ Pᵢ = 1e18 (100%) via normalized exponentials.

⚠️ INFO-001: Upper bound maxQ = 26,000e18 yields q/b ≈ 130, approaching the PRBMath exp() overflow threshold (~133). Currently safe, but future library changes or parameter adjustments could trigger overflow.

Recommended Mitigation: Add explicit check: require(q[i] * 1e18 / b_ < 133e18, "LMSR overflow risk").


Round 2 — Economic Attack Analysis

LMSR Solvency Guarantee

Invariant Verified: poolBalance + subsidyDeposited ≥ total winning shares × 1e18

The LMSR mechanism ensures solvency because:

  1. Initial subsidy = b * ln(n) covers worst-case uniform→concentrated transition

  2. Trader payments (net of fees) increase poolBalance proportionally to shares minted

  3. Fees are deducted before LMSR cost calculation, so shares minted correspond to net collateral

  4. Redemption logic draws from poolBalance first, then subsidyDeposited, with explicit exhaustion check

Fee Accounting Integrity

✅ Default 2.5% split (1% creator, 1% treasury, 0.5% resolver) is correctly enforced.

✅ Creator fees accrue in creatorAccruedFees[_marketId] and are only claimable post-finalization with creatorFeePaid guard.

✅ Admin market creator fees correctly redirected to treasury when isAdminMarket || creator == address(0).

Order Book Security

MAX_ORDERS_PER_BOOK = 200 (A-03 fix) prevents order book flooding.

✅ P2P orders filled before AMM; P2P trades don't affect LMSR quantities, preventing price oracle manipulation.

✅ Cheapest-first sorting with proper slippage protection via _minShares/_minUsdm.

⚠️ INFO-002: Binary search tolerance 1e15 in quoteBuy may cause rounding at the MIN_TRADE boundary. A trade of exactly MIN_TRADE could yield 0 or 2e15 shares due to tolerance bounds.

Impact: Negligible for practical trade sizes; protected by require(ammShares >= MIN_TRADE).

Resolution MEV Analysis

resolveMarket requires block.timestamp >= bettingDeadline, preventing pre-deadline resolution. Status changes to Resolved before order cancellation, blocking further trades.

✅ 24-hour DISPUTE_WINDOW with collateral requirement prevents spam disputes.

Subsidy Exhaustion Attack

redeemWinnings checks fromSubsidy <= m.subsidyDeposited before drawing from subsidy. LMSR solvency guarantee ensures this holds under normal operation.

claimCancelRefund Sequential Call Safety

✅ F-02 fix snapshots optionSupply before burning, ensuring fair pro-rata distribution across sequential claimants.


Round 3 — Adversarial Triage

Fund Theft Vectors

No theft vectors found. Funds only exit via: redeemWinnings (requires burning winning shares), claimCancelRefund (requires burning shares in cancelled market), sellToAMM (requires burning shares with AMM pricing), or authorized fee withdrawals.

Permanent Bricking Vectors

No permanent bricking path found. Admin key compromise allows fee changes and treasury withdrawals, but cannot freeze user redemptions. claimCancelRefund remains callable regardless of admin status.

Centralization Risk: Admin key compromise enables fee increases to 5% cap, resolver pool redirection, market slashing, and treasury withdrawal. Recommended mitigation: deploy admin behind multisig or timelock.

Edge Cases

✅ Zero-volume market: subsidy covers theoretical payouts; no actual shares to redeem.

✅ Single bettor monopoly: LMSR cost escalation and maxQ cap prevent infinite share acquisition.

✅ All bets on losing side: unclaimed poolBalance remains in contract (design choice, not vulnerability). No sweep mechanism.

⚠️ INFO-003: closeBetting function lacks event emission, reducing off-chain observability of market state transitions.

Recommended Fix: Add emit BettingClosed(_marketId);.


Findings Summary Table

ID
Severity
Contract
Title
Status

LOW-001

Low

EventlyMarketsV3.sol

Missing nonReentrant on resolution functions

Acknowledged

INFO-001

Info

EventlyMarketsV3.sol

LMSR upper bound near exp() overflow threshold

Monitor

INFO-002

Info

EventlyMarketsV3.sol

Binary search tolerance edge case near MIN_TRADE

Acknowledged

INFO-003

Info

EventlyMarketsV3.sol

Missing event in closeBetting function

Resolved — v3.2: BettingClosed event added (QWEN-I03)


Production Blockers

No Critical/High findings blocking deployment. The contract is suitable for production with the following recommendations:

  1. Add nonReentrant to resolution functions (LOW-001) as defense-in-depth

  2. Deploy admin behind multisig/timelock to mitigate centralization risk

  3. Monitor LMSR parameter adjustments to maintain q/b < 133 safety margin


Severity Scale

Severity
Impact
Description

Critical

Fund loss, permanent bricking, protocol halt

Exploitable vulnerability causing irreversible damage

High

Significant fund risk, major logic bypass

Exploitable under realistic conditions with notable impact

Medium

Limited fund risk, partial logic bypass

Exploitable but with constraints or limited impact

Low

No fund risk, best practice violation

Code quality, gas optimization, or defense-in-depth issues

Info

Observability, documentation, minor edge cases

Suggestions for improvement without security impact

Audit conducted via static analysis, formal reasoning of LMSR invariants, and adversarial simulation. Dynamic testing recommended pre-deployment.

Last updated

Was this helpful?