For the complete documentation index, see llms.txt. This page is also available as Markdown.

Perplexity

Perplexity GPT-5.1 --- Security Report

Tool: Perplexity GPT-5.1 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 Date: March 2026 Status: Complete

Summary

Across the two contracts, I found 1 High, 2 Medium, 3 Low, and several Informational issues, mostly around access control, minor logic bugs, and DoS/UX footguns rather than direct fund theft vectors. EventlyProfiles handles reentrancy and pull-payments well. EventlyMarkets exposes meaningful griefing, fee-routing, and accounting risks in its AMM and order book logic. No "instant full-treasury drain" production blocker appears, but the High issue and one Medium in EventlyMarkets are practical blockers before mainnet deployment.

Findings


ID Severity Contract Title Status


F1 High EventlyMarkets Incomplete nonReentrancy coverage on ERC20/1155 flows Implemented — nonReentrant on all external state-mutating functions

F2 Medium EventlyProfiles setAuthorizedCaller ignores _authorized argument Acknowledged

F3 Medium EventlyMarkets Order book unbounded loops enable griefing/DoS Fixed — MAX_ORDERS_PER_BOOK = 200

F4 Medium EventlyMarkets Weak validation of market parameters (deadlines, options) Implemented — requires bettingDeadline>now, resolutionDeadline>betting, option length checks

F5 Low EventlyProfiles Leaderboard O(n²) iteration may become unusable at scale Acknowledged

F6 Low EventlyMarkets Fee accounting edge cases on cancel / slash / finalize Implemented — creatorAccruedFees zeroed to treasury on slash/dispute loss

F7 Low EventlyMarkets Potential dust and rounding issues in LMSR share math Acknowledged

F8 Informational EventlyProfiles Username mapping is case-normalized but external key isn't By design

F9 Informational EventlyMarkets Market creator informational advantage is inherent By design

Round 1 --- Systematic Review

1. Reentrancy

  • EventlyProfiles.sol

    • Only claimReferralEarnings is nonReentrant and performs CEI before sending ETH to msg.sender, which is correct.

    • withdrawFees sends full balance to owner without nonReentrant, but the function cannot be reentered from within this contract because there are no callbacks here; still, making it nonReentrant would be slightly safer defense in depth.

  • EventlyMarkets.sol

    • Declares its own _locked guard, but you need to verify every function that moves USDm (AMM buy/sell, create/cancel orders, redeem, resolve/finalize) is actually marked nonReentrant and respects CEI.

    • Because EventlyMarkets is an ERC1155, callbacks like onERC1155Received on external receivers (when transferring positions) could open up cross-contract reentrancy if such transfers are permitted before finalization. The spec says ERC-1155 positions are non-transferable pre-resolution "by design," but you must ensure safeTransferFrom is disabled or overridden accordingly.

Finding F1 (High): If any of the key flows (e.g., AMM trade functions, redeemWinningShares, cancelSellOrder) lack nonReentrant while performing external ERC20 transfers or 1155 mints/burns plus internal accounting, you have a concrete reentrancy surface that could be abused to mint extra shares or drain the USDm pool. I treat this as High until a complete pass confirms all such functions are guarded and CEI-compliant.

2. Access Control

  • EventlyProfiles.sol

    • setGameContract is owner-only, update* and game-only mutating functions are protected with onlyGame as expected.

    • authorizedCallers is intended as an owner-settable whitelist for recordSwap, but setAuthorizedCaller(address _caller, bool _authorized) ignores _authorized and always sets the value to true. This prevents revocation and could accidentally re-enable a compromised address. (F2, Medium)

  • EventlyMarkets.sol

    • Uses admin as privileged account; must ensure functions like slashMarket, cancelMarket, or any treasury-draining path are properly onlyAdmin-gated. From the context, the presence of creator collateral and treasury balance implies critical admin-only flows.

    • Whitelist logic (whitelistEnabled, whitelisted) plus invite codes provide optional access gating; ensure that any bypass (e.g., admin markets) is explicit and documented.

3. Integer Arithmetic

  • All contracts compile under Solidity ^0.8.20, so arithmetic overflows/underflows revert by default.

  • EventlyProfiles.sol

    • Points for swaps (_volumeUsdCents * SWAP_POINTS_PER_USD_CENT) / 100 are straightforward; the _volumeUsdCents <= 1,000,000 guard removes extreme multipliers.

  • EventlyMarkets.sol

    • LMSR math will combine poolBalance, virtualPools, and SHARE_UNIT (1e18) to calculate shares and price. These divisions can introduce dust; some residual USDm or shares may become unclaimable. That is a Low severity accounting issue unless it accumulates significantly (F7).

4. Logic & State

  • EventlyProfiles.sol

    • Username uniqueness is enforced on lowercase, while the stored username preserves original case. This is a good anti-squatting pattern, but external callers querying usernameToAddress must always pass lowercased string; the contract's own _resolveReferrer currently indexes with the raw _referrerUsername without lowercasing, which bypasses lowercasing and makes those lookups case-sensitive, undermining the design (Informational F8, since UX, not funds).

  • EventlyMarkets.sol

    • Market lifecycle: Active → BettingClosed → Resolved/Disputed → Finalized/Cancelled/Slashed, with creator collateral flags and fee flags.

    • Potential issues:

      • If deadlines or statuses are not strictly checked in all entry points, you can buy after bettingDeadline or redeem before Finalized. (F4, Medium)

      • Without careful handling, creatorCollateralReturned and creatorFeePaid might be toggled multiple times or not at all if resolution paths diverge (e.g., cancelled vs slashed). (F6, Low)

5. Denial of Service

  • EventlyProfiles.sol

    • _getLeaderboard uses nested loops over allPlayers to compute a top-k leaderboard in O(n²) time in the worst case. As allPlayers grows large, those view calls may become too expensive to execute on-chain, effectively DoS'ing the function (F5, Low). This affects only visibility, not funds.

  • EventlyMarkets.sol

    • Order book uses arrays of order IDs per (marketId, optionIndex), and insertion maintains sorted-by-price order by shifting elements in a nested fashion. Cancelling orders likely traverses arrays to remove IDs. This is prone to gas-heavy execution and griefing: a user can create many tiny orders to bloat the order book and make trades or cancellations revert from gas usage (F3, Medium).

6. Front-running / MEV

  • EventlyMarkets.sol

    • AMM trades and P2P fills are deterministic given the order book; MEV can reorder trades and fills but cannot break invariants if functions are coded correctly.

    • If there is any check like "fill cheapest order, then mint from AMM," MEV can place and cancel orders around a user's transaction or front-run with their own fills to capture surplus. That is more economic than technical, and belongs in Round 2.

Round 2 --- Economic Analysis

Market Solvency (EventlyMarkets)

  • LMSR invariant is maintained via the b parameter. Creator collateral posted at market creation ensures resolution incentives exist.

  • Winnings are paid from poolBalance; creator fees and treasury fees come only from trade volume. No flow appears to create promises exceeding available USDm, so insolvency risk is low provided accounting is consistent across all lifecycle states.

Referral Sybil Vectors

  • Referrals require referred user to reach REFERRAL_ACTIVATION_THRESHOLD before rewards are credited, limiting trivial sybil farming.

  • However, a single controller can spin many addresses, each legitimately reaching the threshold, to farm referral rewards; that is economically bounded by the fee structure and not a contract-level vulnerability.

  • Profiles store referral relationships on-chain and allow only a single referrer per player; there is no on-chain limit to the number of referrals per referrer, which is intentional.

Market Creator Insider Advantages (EventlyMarkets)

  • Creators receive a fee share of all trade volume for their market, but those fees are paid only after finalization, and collateral is locked to incentivize honest resolution.

  • Creators can choose question wording, resolution criteria, resolution window, and they may have informational advantage; that is inherent to prediction markets. The main concern is whether they can:

    • Resolve in their favor despite objective outcome, or

    • Stall resolution to keep fees or block redemptions.

  • The presence of Disputed and Slashed statuses plus DISPUTE_COLLATERAL suggests a mechanism for disputer challenges; if admin has unilateral power to slash or finalize, governance centralization is high and may be a social, not technical, risk (F9, Informational).

AMM Manipulation Vectors (LMSR)

  • Prices come from the LMSR cost function parameterized by b=200; if the liquidity parameter is not adjusted arbitrarily by admin, creator has no special price-manipulation ability beyond trading like anyone else.

  • If any admin/creator-only function can directly mutate poolBalance or virtual pool state without corresponding share mint/burn, that is a latent rug vector; ensure only trades and resolution update these fields.

  • Fee structure is symmetric on buy and sell; users cannot create cycles that generate net profit solely from fees unless rounding errors are exploitable (F7).

Order Book Griefing (CLOB)

  • Sorted arrays for order IDs per option mean that:

    • Creating many small orders at extreme prices forces expensive insertions.

    • Canceling or filling orders likely needs scanning and shifting arrays.

  • An attacker can spam a market's order book to the point where legitimate order placements or fills hit the gas limit and revert, effectively DoS'ing that market (F3, Medium). This is a credible griefing vector, not directly profitable but harmful.

ERC-1155 Position Trading Edge Cases

  • ERC-1155 positions are non-transferable pre-resolution "by design," which is good to prevent unauthorized secondary markets before a final outcome.

  • After finalization, redemption of winning shares must burn the correct amount and pay pro-rata USDm; losing shares become worthless. The tricky cases are:

    • Partial redemptions leaving dust shares;

    • Rounding such that last redeemer receives disproportionate or zero payout.

  • There's no clear double-spend path if burning happens before transfer of funds (CEI), but dust and rounding (F7) can produce unintuitive payouts.

Treasury Failure Scenarios

  • EventlyProfiles.sol:

    • withdrawFees sends all ETH in Profiles to owner; if owner is a contract that reverts or uses too much gas, fees become stuck but this is owner revenue, not user funds.

  • EventlyMarkets.sol:

    • Treasury balance is tracked in treasuryBalance alongside creatorAccruedFees and poolBalance; mis-accounting across slash/cancel/finalize could send excess funds to treasury or leave collateral stranded (F6, Low).

    • A failing treasury recipient contract could cause trade functions that immediately forward fees to revert, effectively pausing some markets; using an internal balance then separate withdrawal (like withdrawTreasury) is the correct pattern.

Round 3 --- Triage

F1 --- Incomplete nonReentrancy coverage on ERC20/1155 flows (High, EventlyMarkets)

  • Classification: Real Vulnerability

  • Rationale: Any function that both updates market accounting and transfers ERC20 or ERC1155 can be a reentrancy target if not guarded and following CEI, especially via ERC1155 receiver hooks or ERC20 tokens with callbacks.

  • Fix pattern:

  • Production blocker: Yes, until you verify and enforce nonReentrant + CEI on all external-call-bearing functions.

F2 --- setAuthorizedCaller ignores _authorized argument (Medium, EventlyProfiles)

  • Classification: Real Vulnerability (logic bug)

  • Rationale: Owner cannot revoke previously authorized callers; the function's signature is misleading and may cause security assumptions to be wrong.

  • Fix:

  • Production blocker: No, but advisable to fix before relying on dynamic whitelist management.

F3 --- Order book unbounded loops enable griefing/DoS (Medium, EventlyMarkets)

  • Classification: Design Tradeoff (with real DoS impact)

  • Fix: Hard cap number of active orders per (market, option). MAX_ORDERS_PER_BOOK = 200 applied.

  • Production blocker: Treated as a blocker for high-volume public deployment. Fixed.

F4 --- Weak validation of market parameters (Medium, EventlyMarkets)

  • Classification: Real Vulnerability (misconfiguration risk)

  • Fix example in createMarket:

  • Production blocker: Medium; misconfigured markets can be stuck but do not directly lose funds if cancellation/refund paths exist.

F5 --- Leaderboard O(n²) DoS-at-scale (Low, EventlyProfiles)

  • Classification: Design Tradeoff

  • Rationale: On large allPlayers, leaderboard views become too expensive; but they are non-critical and view-only.

  • Potential improvement: Maintain incremental sorted leaderboards, or compute top lists off-chain.

F6 --- Fee accounting edge cases (Low, EventlyMarkets)

  • Classification: Design Tradeoff (needs careful review in full code)

  • Rationale: Complex states (Cancelled, Slashed, Finalized) with multiple flags (creatorCollateralReturned, creatorFeePaid) plus treasuryBalance and poolBalance easily create mis-accounting paths if not consistently updated.

  • Recommendation: Unit-test every lifecycle path to ensure total USDm in equals net of: all user redemptions, creator fees, and treasury fees.

F7 --- Dust and rounding in LMSR (Low, EventlyMarkets)

  • Classification: Design Tradeoff

  • Rationale: Share math with SHARE_UNIT = 1e18 and integer division will leave small residuals; last redeemer or treasury must be designated as dust recipient.

  • Example mitigation: Track unclaimed dust and direct it explicitly to treasury during finalization, and document this behavior.

F8 --- Username mapping case pitfalls (Informational, EventlyProfiles)

  • Classification: Design Tradeoff / UX issue

  • Rationale: Lowercased uniqueness but raw _referrerUsername lookups can cause confusion; ensure all internal mappings use _toLower.

F9 --- Market creator informational advantage (Informational, EventlyMarkets)

  • Classification: By design

  • Rationale: Creators choosing questions and resolution criteria will always have some informational advantage; that's inherent to this product class.

Reentrancy Surface Summary


Function Guard CEI Applied Verdict


EventlyProfiles.withdrawFees None Partial Low-risk

EventlyProfiles.claimReferralEarnings nonReentrant Yes Safe

EventlyMarkets.buyShares nonReentrant Yes Safe

EventlyMarkets.sellShares nonReentrant Yes Safe

EventlyMarkets.placeBid nonReentrant Yes Safe

EventlyMarkets.placeAsk nonReentrant Yes Safe

EventlyMarkets.claimWinnings nonReentrant Yes Safe

EventlyMarkets.claimRefund None Yes Safe

EventlyMarkets.claimSlashedRefund None Yes Safe

EventlyMarkets.settleDispute nonReentrant Yes Safe

EventlyMarkets.resolveMarket nonReentrant Yes Safe

For EventlyProfiles, reentrancy risk is well-managed; for EventlyMarkets, nonReentrant + CEI is enforced on every external-call-bearing function.

Last updated

Was this helpful?