SORTIEDOCUMENTATION
CONTENTSThe crate drop

The crate drop

Airframes are minted as ERC-721 tokens from a sealed-crate drop. You buy a crate during the sale; after the sale closes the seed is published and every crate reveals into one of five aircraft.

Supply2222
Price0.0006 ETH
Limit5 NFT per wallet

One price, one door

There is a single price, and a single way to buy. Every crate costs the same, and there is no second entrance, no list, and nobody who pays less than you.

The price is written into the contract when the drop is deployed and cannot be moved afterward, by us or by anybody. There is no function that changes it. The figure is not written down here either: the drop page reads what it charges off the contract itself, so the number on the button and the number you pay cannot drift apart.

The roster

ModelCountChance
AF-03 Strike74133.35%
AF-06 Recon74133.35%
AF-02 Superiority36816.56%
AF-05 Heavy36716.52%
AF-04 Ghost50.23%

AF-01 is not in the drop. It is the starter every pilot already owns.

6 traits, and all 6 counts are exact

The airframe is the headline, but it is not the only thing a crate decides.

TraitOptions
AirframeStrike 741, Recon 741, Superiority 368, Heavy 367, Ghost 5
BayHangar 667, Revetment 600, Deck 467, Sky 333, Void 155
LiveryAsh 667, Char 600, Bone 467, Rust 333, Chrome 155
WingStandard 1000, Swept 666, Straight 467, Forward 89
ConditionClean 1000, Scuffed 666, Weathered 467, Scorched 89
StoresNone 1000, Two 733, Four 489

Every one of those counts is exact, in the same sense the roster's are: 89 Scorched airframes means a 90th cannot exist. Each trait is mapped one to one across the whole drop, rather than rolled per crate against a table of odds.

That is not the usual way, and the difference matters. Rolling each trait independently would make every number above a close guess instead of a fact, and a drop that says "exact" about one trait while meaning "roughly" about the other five is not being honest about either.

The wing is real geometry, not a sticker: each shape is a separate render of that airframe with its wing actually reshaped, from the same locked camera, so a swept wing is a different airplane rather than a different picture of the same one. Ordnance is real too, hung on pylons under the wing and occluded by it exactly as the renderer works it out.

AF-04 Ghost takes no part in the wing shapes. Five of them exist; it is marked by how it is lit instead, and you will know one when you see it.

The traits are drawn independently of each other, so a Ghost is no likelier to be Chrome than a Strike is. Scarcity stacks rather than clumping, which is what makes a particular combination rarer than any single part of it. A Scorched Chrome Ghost is possible and almost certainly does not exist: the arithmetic puts it at well under one crate in the whole drop.

Superiority carries one more than Heavy for a boring reason worth stating plainly: with a five-unit Ghost, 2222 cannot be split into two equal pairs, because 2222 minus 5 is odd. Something has to absorb the odd unit, and trimming a published cap to force prettier symmetry would change what buyers were told.

The odds are exact, not expected

Every crate number is mapped to its own place in the roster, one to one. Nothing is re-rolled against a probability table.

So "5 Ghost" is a fact in both directions: a sixth cannot exist, and if every crate sells, a fifth cannot fail to appear. One honest caveat: the second half depends on the sale selling out. The mapping covers all 2,222 crate numbers, so if the sale closes early the crates that sold hold a random subset of the roster: the ceiling still holds absolutely, but a Ghost slot may sit on a crate number that was never bought. Each crate's odds are exactly 5 in 2,222 either way. Free odds would make both directions merely likely, and a drop that advertises a count while rolling probabilities is advertising the wrong thing.

Nobody can see a crate before it is opened

Reveal is delayed until the sale closes. During the sale the seed exists only as a hash, so nothing about a crate is computable.

That is what kills the classic gacha attack: wrap mint and reveal in one transaction, inspect the result, revert if it is bad, and pay only gas until you win. With the outcome unknowable at mint time there is nothing to inspect.

And opening it changes nothing either

What a crate holds does not depend on when it is opened, on who opens it, or on how many were opened first. It is fixed by the published seed and the crate number, and nothing else.

This is worth spelling out because the obvious way to build a drop does not have that property. If each opening drew from a shrinking pool, then the order of openings would decide the outcomes, and since anyone may open anyone's crate, a buyer could open other people's crates in a chosen order inside a single transaction and cancel the whole thing unless their own came out rare. It would cost less than the crate did. An earlier version of this contract worked exactly that way; the version that ships does not.

The house cannot re-roll the draw

Closing the sale fixes the block whose hash goes into the seed, and it can only be done once. That matters more than it sounds: once the sale is closed nothing else that feeds the seed can change, so a second close would have been a fresh roll of the entire drop, available to whoever holds the key, for the price of gas.

There is one narrow exception, and it exists to protect buyers rather than the operator. A chain only keeps its last 256 block hashes, so an operator who misses that window would otherwise leave every paid crate permanently unopenable. The seed can therefore be re-pinned, but only after the hash has actually expired, at most twice, and every re-pin is counted on chain where the drop page shows it. An ordinary run shows zero.

The seed itself cannot be ground

A committed seed alone would let the deployer try seeds offline until one favored them. So the seed that drives the draw mixes in facts the deployer neither controls nor could know when the commitment was made:

finalSeed = keccak(committedSeed, blockhash(entropyBlock), minted, lastMinter)

Mixing several is deliberate. This chain documents blockhash as cryptographically insecure pseudo-randomness, so resting a whole drop on it would be resting it on a value the sequencer has a say in. The split that actually holds is this: the deployer knows the seed but cannot choose the public inputs, and the public can see the inputs but not the seed. Neither side can grind the result alone.

Once the seed is public, every draw in the drop can be recomputed by anyone. No oracle, no signature, no trust.

Where the picture lives

Two images, and the second one is the reason the first is safe to have.

The artwork is a render: the bay, the aircraft with its wing shape, its livery and its wear, assembled from the traits above. That is a real image file, and real image files have to be hosted somewhere. It is pinned to IPFS, which addresses a file by a hash of its contents rather than by a domain that has to be renewed, and the address of that pin is written into the contract and then frozen, after which nobody can point the collection at different pictures, including us.

A sealed crate carries no traits at all, only its picture and its number. That is not an omission: it has not been dealt anything yet, and listing a "sealed" trait would put it on a marketplace's rarity board next to Ghost, as though a third of the drop had been dealt something in common.

The second image is not in that file at all. The contract keeps its own copy of every token's description, and the picture in that copy is a plate drawn inside the contract itself, naming the airframe, its count and its traits. It costs nothing to keep and it is what anyone asking the chain directly gets back, whatever happens to the pin. What that does and does not cover is set out below rather than glossed.

This is the one place where the obvious design turned out to be the wrong one, and it was measured rather than argued.

The natural thing to do, and what this contract did first, is to build the whole description inside the contract and hand it out directly, so a token needs no server at all. A rehearsal drop was deployed that way, opened, and looked at on the marketplace where it would actually be sold. The listing showed Sealed Crate #1 for a crate that the chain said had already been opened into an AF-06 Recon. Refreshing it changed nothing, and it never could have: an indexer reads a token once, keeps whatever it read, and remembers the address it read it from so it can go back later. A description handed over directly has no address, so there is nothing to go back to. Every on-chain announcement that the token had changed was correctly emitted and correctly ignored.

For a drop whose entire product is the moment a crate opens, a reveal that the main venue can never display is not a small defect. So the token now carries a link, and the document at the other end is a copy of the one the contract builds: generated from it, checked against it file by file before it is pinned, and pinned by content hash so the link cannot be quietly repointed once it is frozen.

The cost is stated rather than buried, because it is real: while the description was built in the contract, a lapsed pin cost the picture and nothing else. Now it would cost the name and the traits too. What pays for that is that the pin is content-addressed rather than a domain, that the contract still builds the full document for anyone who asks it directly, and that the address is frozen only after every one of the files behind it has been fetched and compared.

There are two pins, not one, and the first one happens before the sale opens. An indexer records a token the first time it sees it, which is while every crate is still sealed, so the sealed documents have to already exist at that moment or the same defect returns unchanged. The second pin, after the seed is published, carries the first one forward and adds the opened documents and the renders beside it.

Five per wallet is friction, not a wall

It slows casual hoarding and spreads the drop. Anyone willing to fund a second address defeats it in a minute, and without an identity system there is no fix on chain, so it is presented as what it is rather than sold as a guarantee.

What the cap does buy is that hoarding has to be deliberate and repeated rather than a single click. At five crates an address, cornering the drop means funding 445 wallets rather than doing it from one.

The honest description does not change with the number, and neither does the cost, which falls on both sides: a buyer who wants more than five has to fund another wallet and pay gas again, and a tighter cap would make the drop slower and harder to sell out. Five is where that trade was settled, breadth of distribution against speed of sale.

It has one consequence worth reading next to the odds above, since the floor of the guarantee there holds only if the sale clears: a cap that slows the sale makes an undersold drop likelier, and in an undersold drop a Ghost may sit on a crate number nobody bought.

An L2 trap that bit us

block.number inside the contract is the L1 block number, nowhere near the L2 head the node reports. Measured on this chain: 11,448,430 against 98,550,242.

Anything waiting for the entropy block must read the contract's own clock, and it advances on L1's twelve-second cadence. Polling the node's head waits forever against a number already millions ahead.