Skip to content
ProjectX
Capture the flag

Break the old one. Learn the new one.

Seven challenges, built from ProjectX’s own audit findings and running against a retired mainnet deployment.

These are not invented puzzles. Each one is a vulnerability that existed in v1.0, was found in review, and was fixed in v1.0.1 — you are reproducing real findings on the real chain.

7 challenges2,700 pointsNo depositor funds exposed

Read the scope first

The range is a retired v1.0 deployment, taken out of service when v1.0.1 shipped. Its balances were migrated at that point, so no depositor funds are exposed here. The live pool is not a target and never will be.

In scope
  • The retired v1.0 package and pool listed above, and the objects they own.
  • The v1.0 Move logic: deposits, withdrawals, the draw, settlement, the oracle breaker.
  • Anything you can make true on chain by calling those contracts from your own wallet.
Out of scope
  • The live v1.0.1 pool and its treasury. Findings there are real — disclose, do not exploit.
  • Any wallet or address that is not yours, on any network.
  • Any deployment other than the retired v1.0 range named on this page.
  • The daemon, the read API, this website, and any RPC provider — infrastructure, not protocol.
  • Social engineering, phishing, and denial-of-service against shared services.
Never a target

The live v1.0.1 pool holds real deposits. If you find something there, it is a real vulnerability — report it privately through the disclosure route. It is worth more to everyone as a report than as a flag.

live pool · off limits0x0742576b…4766c9
The range

ProjectX v1.0 · retired in-situ deployment

A real deployment on Sui mainnet: real gas, real shared objects and real failure modes — everything a local sandbox quietly gets wrong. Drained and migrated when v1.0.1 shipped, then left standing so the code that made these mistakes can still be run against.

package0xe338cb78…e71952pool0x88cb9ac8…b0fcd2
House rules
  1. Use your own wallet and your own gas. Nothing here is sponsored.
  2. A flag is a transaction digest: the state you made true, and the call that made it.
  3. Do not grief other players. The range is shared.
  4. Found something outside scope? Stop and disclose. That is worth more than the points.
The board

Seven findings, hardest last

Each challenge names the audit finding it reproduces, so you can read the fix after you land it — or before, if you would rather learn than score.

Warm-up

2 challenges · 200 points
  • 100 ptsF-02Access control

    The late ticket

    v1.0 gated draw eligibility on a wall-clock timestamp. A deposit made in the closing seconds of an epoch was eligible for that epoch’s draw — a prize it contributed nothing to funding.

    Capture

    Win an epoch with principal that entered after that epoch’s yield was already earned.

    Spoiler — what v1.0.1 did

    v1.0.1 indexes eligibility by epoch number, not by clock: a deposit in epoch N cannot win until N+2. Time-based gates are manipulable; the epoch counter is not.

  • 100 ptsF-04Access control

    The missing gate

    Every governance entry point checked an object version before acting — except one. The treasury sweep path shipped without the guard the others all had.

    Capture

    Reach the sweep path on a treasury whose version the other entry points would have rejected.

    Spoiler — what v1.0.1 did

    v1.0.1 gives the treasury a version and asserts it first in the sweep, closing the single entry point that lacked one. A guard that is on every function but one is on no function that matters.

Standard

2 challenges · 500 points
  • 250 ptsF-16Economic

    One MIST

    Prize funding is permissionless and unbounded below. The rollover safety valve only triggers when the prize is exactly zero — so a single MIST of funding commits the pool to a full settlement cycle it may be unable to complete.

    Capture

    Drive the pool into its settlement phase for a prize too small to clear the circuit breaker’s floor.

    Spoiler — what v1.0.1 did

    The fix replaces the zero-check with a minimum drawable prize: dust accumulates harmlessly until it is worth drawing. A safety valve keyed on exact zero is a safety valve one MIST defeats.

  • 250 ptsF-06Resource

    The long loop

    The harvest iterates every stake object the pool holds. v1.0 placed no ceiling on how many there could be, so the loop’s gas cost was attacker-influenced and unbounded.

    Capture

    Make the pool hold enough stake objects that a harvest cannot complete within a block’s gas.

    Spoiler — what v1.0.1 did

    v1.0.1 caps the object count and has the harvest restake *skip* at the cap rather than abort — bounding the loop without ever bricking the very path the bound protects.

Hard

2 challenges · 1000 points
  • 500 ptsF-03Oracle & MEV

    The settler’s spread

    Settlement was permissionless. Whoever ran it could swap the prize at market, hand the contract only the oracle floor, and keep the difference — up to the full slippage bound, taken from the winner, every epoch.

    Capture

    Settle an epoch you did not win and end the transaction holding value that should have gone to the winner.

    Spoiler — what v1.0.1 did

    v1.0.1 gates settlement behind an operator capability, with a permissionless fallback that opens only after a grace window. Liveness stays open; routine extraction is closed.

  • 500 ptsF-09Oracle & MEV

    Zero means zero

    The circuit breaker checked variance as a ratio to the mean. With a mean of zero, both volatility checks divided into zero and passed trivially — a reading that should have been rejected sailed through.

    Capture

    Settle against an oracle attestation that the breaker was supposed to refuse.

    Spoiler — what v1.0.1 did

    v1.0.1 asserts a positive mean before any ratio is computed. A validity check that is itself undefined at the boundary is not a check at the boundary.

CapstoneNo known solution1,000pts

The invariant

The claim under attack

liquid+staked==total principal

Enforced by the Move type system, not by a runtime check.

No function taking an admin capability can reach principal at all. This challenge is not a known bug, and there is no intended solution. It is the wall.

Capture

Make the invariant false by any path. Withdraw more than you put in, or leave the books unable to return everyone’s principal.

If you solve this, do not submit it as a flag

Stop and disclose it privately — on any deployment, including the retired one. It would be the most important finding in the protocol’s history, and it is worth far more to everyone as a report than as points.

Invariant
For agents

Machine-readable, on purpose

Coding agents are going to audit protocols whether or not we make it convenient. This range is built so they can — same rules, same scope, same chain.

The manifest is stable JSON: challenge ids, categories, points, objectives, the target identifiers and the scope boundary, so a harness can enumerate the board without scraping this page.

The manifest

GET /ctf/manifest.json

Includes the scope boundary as data, not prose — an agent that reads outOfScope has no excuse for touching the live pool.

If you are running an agent

  • Dry-run everything first. Sui simulates for free and it catches most of what a blind send would cost you.
  • Bisect with A/B transactions that differ in exactly one way. A wrong theory on chain costs a redeploy; a dry-run costs nothing.
  • You are responsible for what your agent sends. Scope violations are yours, not its.
Why this exists

Most CTFs teach you to find bugs nobody ever shipped.

These were shipped. By us. Into a system holding real money — then found, written up, and fixed.

Every finding, its severity and the reasoning behind each fix is published. You can read what a professional review actually said about this code, then go and exploit it yourself.

  1. 01

    For developers

    Six of these are patterns, not one-offs: a time gate that should have been a counter, a guard on every function but one, a check undefined at its own boundary. You will meet them again in other people’s code.

  2. 02

    For the protocol

    Every solver is a reviewer we did not have to hire, working on a system that looks exactly like the live one — because it used to be it.

  3. 03

    For the community

    A protocol that publishes its own mistakes as a teaching range is making a claim about how it will handle the next one.

Landed one?

Send the transaction digest and a paragraph on the mechanism you used. Every solver is a reviewer the protocol did not have to hire.