ASA·COMPASS
Index Shuffle

Read me

What this is

An archive first

ASA Compass is a record of the NFTs minted on Algorand in 2021, back when the chain was young and most of these pieces were made by people who have since moved on. Marketplaces of that era closed and took their listings with them. What remains is on the chain, and this site reads it back.

It is built for collectors who care where a piece came from, not for traders. You will find no charts, no floor prices and no rankings designed to make you act quickly.

What the archive holds

Counted at build time

2,515collections in the index Each one groups 25 pieces or more that belong together, reconstructed from the chain. Collections gathered on one card count once.
5,810series in the index Smaller groups of 2 to 24 pieces, with their own index tab. Each keeps its own page.
1,183,789pieces inside them Every piece keeps its asset ID, its creator and the round it was minted in.
7,828collections and series with images A collection without a single resolvable image is held back rather than shown empty.
721,108trades on-chain 720,945 recovered from the 2021 to 2022 archive, the rest from active marketplaces and ASA Compass. Spread across 5,400 collections and series.
187dormant collections and series Nothing has moved in them for years. They are dimmed, never hidden.

How it is built

Read, group, verify

Every asset minted in the period is read from the chain, with its name, its creator, its metadata and the round it appeared in. Pieces are then grouped into collections, collections are scored, and only those that look like real work by a real author are published.

A group of 25 pieces or more is listed as a collection; a smaller one, from 2 to 24 pieces, is listed as a series. Both have the same kind of page.

Nothing here is entered by hand, which is the point: an archive that depended on someone typing it would stop the day that person stopped. It also means the machine makes mistakes, and the next section is about those.

Why a collection may look wrong

And what we do about it

Grouping is guesswork. Names are the strongest signal, so a series called Zombie Punk, Nerd Punk and CowboyPunk is recognised by the word they share, wherever it sits in the name. That same method will occasionally put together two things that merely sound alike, or leave a piece out because its name went its own way.

Some creators used several wallets, and some wallets hold several unrelated series. Both cases are handled, neither perfectly. If a collection is grouped wrong, saying so is the fastest way to fix it.

Where the images come from

Served from here

Most 2021 pieces point at IPFS. Public gateways answer one request happily and fail roughly one in ten when asked for hundreds at once, which made pages full of empty frames. Every image is therefore fetched once and served from this domain instead.

A piece whose image no longer resolves anywhere keeps its entry, with its identifier in place of the picture. It existed, and that is worth recording even when the artwork is gone.

What the numbers mean

And what they do not

Every price shown is a trade that already happened on the chain. Nothing is an estimate, an appraisal or a suggestion. A collection with no price either never traded, or has not been checked yet. Those are not the same thing, and the archive says which: a collection is only called quiet once every one of its pieces has been looked at. Until then it is marked not checked yet, because announcing an absence we have not verified would be a claim, not a fact.

Live token prices in the top bar come from Vestige and are shown in US dollars. A unit price keeps as many decimals as it needs, since a token worth billionths of a dollar rounds to zero and would read as worthless. A balance is shown in dollars and cents.

The marketplace

Open since October 1, 2026

Buying and selling are open. These rules are set in the settlement contract:

2.5%commission at most Taken in the currency of the sale. Sales paid in XDB pay none at all. This is both the standard rate and the ceiling written into the contract: nobody can ever be charged more, whoever runs the platform later. Locking up XDB lowers it from there.
0.01minimum price A guard against selling a piece for nothing by mistake. An auction starts higher, at 0.13, because below that no penalty taken from a bid could cover the seller's loss. Each accepted currency carries its own floor.
6pieces per bundle Sold together in one move at a fixed price when paid in ALGO; a bundle paid in another currency holds 6. An auction carries more per piece, so it holds fewer still: 2 when priced in ALGO, 1 when priced in another currency. The limit comes from what a single transaction group can carry.
10 minauction extension A bid in the last minutes pushes the end back, so nobody wins by arriving one second before the close.

The commission is capped at 2.5% forever, and the cap is in the contract rather than in this sentence. Nobody can raise it, whoever runs the platform later. 2.5% is what you pay with nothing locked up, and locking XDB lowers it from there, a quarter of a point at a time, down to nothing. Holding the token does not count, only locking it does: a balance that appears and disappears inside one transaction is exactly what that rule exists to stop. Paying in XDB costs no commission at all, whatever your locked amount already earns you.

Your rate is read from the chain at the moment you sign, not from this page. If it changed while you were reading, the contract charges the rate you actually qualify for and hands back the difference in the same transaction.

Pieces held for sale sit in the contract itself, not in anyone's wallet. Taking a fixed-price listing back returns them at any time, and the deposit that covers the network's storage comes back with them. That stays true even if we pause new listings: the contract has no way to stop a seller from withdrawing, and it was tested against a paused marketplace rather than taken on trust. An auction is a different promise: once its reserve is met, the sale is owed.

If you made the pieces, part of each sale can come back to you. Artists who stake enough XDB earn a royalty on every sale of their pieces here, and choose where it is paid.

Your royalty, for artists → Read the security review record → Read the white paper →

How this contract was checked

The full record, in the open

Audit performed by Claude, an AI agent Every claim below can be replayed against the chain by anyone, which is the only reason to trust it.

What the contract refused to do

An audit report for the settlement contract behind this marketplace, written from the test bench that produced it.

What this document is

ASA Compass is a catalogue today. This page is the record of that second half: not a summary of intentions, but a list of things the contract was asked to do and would not.

The object under audit is a single program on the Algorand chain, named without ambiguity below by its application number and by the fingerprint of its bytecode. That precision is not formality. An earlier register of 56 guards belonged to a different version of the program, and a green check on one object establishes nothing about another. Every figure on this page is tied to the fingerprint it describes, and the fingerprint is read from the chain each time the bench runs, never from a file kept here.

How to read it. The table below is what a suspicious reader checks first, and all of it can be verified in a single request to a public node. The sections that follow explain what a tested guard means here, what the contract refused when we tried to break it, and, at the end, what is still open. Nothing on this page asks you to trust its author; the last section tells you how to reproduce the whole thing.

Guards made to refuse80 of 131 positions written into the program
Chapters of testing14, run by 22 replayable benches
Refusal attempts written120, plus 24 positive controls
Program auditedfingerprint fa74919269d4e64f, 6,429 bytes
Checkable onany instance running that exact bytecode
NetworkTestNet
Last verified2 September 2026

Every one of these is checkable. The fingerprint is the SHA-256 of the approval program as the chain serves it; the instance numbers are public; the register that backs the guard count is published with this project.

2 of the 82 shown to be unreachable, by refusals rather than by argument
7 security reviews, across six versions of the contract
0 known defects that can cost anyone a piece or their money

Why we make the code refuse things instead of reading it

In September 2026 a new mechanism was added to the contract, letting one listing offer several copies of the same piece rather than a single one. The code was written, reviewed, and looked correct.

Then the bench withdrew a listing of a thousand copies, three of which had sold, and compared the seller's balance before and after. One copy came back. The other 997 stayed in the vault, permanently, with no error and no message. The deposit was returned, the listing's record disappeared, and the pieces were simply gone. The cause was one line written back when a listing could only ever hold a single piece: what the contract held on to was right, what it gave back had not kept up.

Reading the code had not found it. Measuring what came out did. And on a contract whose code cannot be changed after deployment, that defect would have been permanent: every seller of a multi-copy listing would have lost everything they did not sell, forever, and nothing could have been done about it afterwards. It was found before the contract was engraved, not after, which is the entire reason this project tests rather than reviews.

That is what the numbers at the top of this page are really about. Not that the code contains safeguards, but that each one was made to stop something.

What "a guard was tested" means here

It does not mean the code contains an assertion. It means a transaction was built specifically to break that rule, sent to the contract, refused, and that the refusal message was read back and compared, word for word, against the one the contract attaches to that rule. Fifty-nine of them were made to refuse on the live instance itself; twenty-one on a twin running the same bytecode.

Two of the eighty-two were never made to refuse, and they are counted separately rather than quietly folded into the total. Both are unreachable, and their unreachability was established by refusals obtained on the guards upstream of them, not by reasoning about the code. They are belts underneath braces that have themselves been tested.

What was actually tried, chapter by chapter

The testing is organised into fourteen chapters, each a separate replayable bench. The distribution is worth a look on its own, because it is not the one you would guess: the currencies, the settings and the operator role needed more testing than buying and selling did. That is where a marketplace hides its levers, and where a careless contract lets its operator take what is not theirs.

ChapterGuards proven
Currencies, settings and the operator role18
Shape checks and upper bounds12
Offers and claims11
Auctions10
Buying, and the life of a listing5
Offers paid in a token, and the exempt token5
Listing a piece3
Auctions run to their end3
Debts3
A newly accepted currency3
Guards that require an action first2
Time-limit guards2
Debt owed as a piece2
Opting out of an asset1

How many attempts, and what is not counted

120 refusal attempts are written across the 22 benches, alongside 24 positive controls. The 80 proven guards counted here belong to the program whose fingerprint is fa74919269d4e64f, and to that program alone. Those are transactions built on purpose to break a specific rule, submitted to the contract, and expected to come back refused.

The count is of positions in the program, not of names. A named guard can be written at more than one place: on the program audited here, 82 named guards are spread across 131 positions, and 25 of those names appear more than once. One of them, the check that only the operator may change a setting, is written fifteen times. Proving a guard at one of its positions says nothing about the other fourteen, so each position is counted on its own. This makes the figure on this page lower than it used to be, and it is the one we can defend.

The program that will settle trades is a different one, and its record is kept apart. Its fingerprint is 12784f33e1ab11d7, 7,305 bytes, and it carries two things the audited program does not: listings that hold several copies of the same asset, and a commission rate that falls as the buyer locks up XDB. 35 of its 148 positions have been made to refuse. Counts are never carried from one program to the other. A green check on a different object establishes nothing about this one, and that rule applies to our own earlier figures first.

Buying and fixed-price selling, which is what a visitor can actually do, is where that work has gone: 33 of the 34 positions those paths cross have been made to refuse. The one that remains is not untried. It cannot be reached at all, and the two guards upstream that make it unreachable have themselves been made to refuse. Everything else in the 148 belongs to auctions, offers, claims and operator settings, and we say it is untried rather than rounding the number up.

And here is what these numbers do not tell you. The register records positions proven, not attempts made: 80 positions for 120 written attempts, because several are approached from more than one angle. We do not count how many times a bench has been run, and we will not invent the figure. What is counted is this: 80 positions, each of which refused at least one real transaction and whose refusal message was read back and compared word for word against the one the contract attaches to it.

None of this was checked by anyone other than the author of the contract. The adversarial reviews recorded on this page read the audited program, and each finding is listed with the fingerprint it was read against. What this page claims about the program that will settle trades is what its own benches measured, and nothing more.

Each proven guard is recorded with the exact position in the program where it stopped the transaction, which is what makes the record checkable rather than merely stated. A few, taken verbatim from the register: prix nul (pc 5746), a price of zero refused at program counter 5746; une unite a la fois (pc 761), more than one unit refused; expiration deja passee (pc 1964), an already-expired deadline; depot insuffisant (pc 2023), a deposit that did not cover what it must; lot trop grand (pc 3394), an oversized batch. All 80 carry such a position.

The control that makes the refusals mean something

A test bench that only ever collects refusals cannot tell "the contract refuses this" from "I do not know how to build a call that works." So an ordinary listing was built in the same run, against the same instance, and it went through. The refusals are therefore refusals, and not a bench that was broken all along.

The clearest thing the contract got right, and it is not technical

A seller withdraws a listing, and the piece cannot be returned to their wallet, because that wallet has since opted out of the asset, which on Algorand is an ordinary thing to have done.

The contract could have refused the withdrawal on the grounds that it cannot hand the piece back. That refusal would have sounded prudent, and it would have locked both the piece and the listing with no way out for anyone. Instead it records a debt in the seller's name, lets the listing close, and the piece waits to be claimed. The balances were checked before and after: the money comes back to the exact figure, the seller receiving the full price, because the one per cent fee is paid on top by the buyer and never taken out of what the seller is owed.

And this is worth knowing about who that guard protects. Algorand does not let the creator of an asset close their position in it. A minter can therefore never end up in this situation with their own pieces. The debt mechanism protects resellers, which is to say most of the people on a secondary market, and the ones with the least recourse if a contract decides to hold on to what is theirs.

What the contract cannot do, in the exact words

The code of this contract cannot be changed after deployment, not even by its creator. It can be closed, through a method built for that purpose, and only once it no longer holds anything.

Both halves matter, and the short version would be false. No branch of the program accepts an update, and four attempts were built and run, all of them signed by the creator, the one person with the best chance of getting through, because a refusal aimed at a stranger proves nothing. A bare update was refused. A bare delete was refused. Closing the market through its own dedicated method was refused, with fifteen listings and three auctions actually sitting in the vault, on the grounds that the vault still holds something. And an update disguised with the closing method's selector was refused as well.

Saying "this contract cannot be deleted" would be false, and a suspicious reader would establish that in a few minutes: the closing method is in the contract's public interface and nobody hid it. What is true is narrower and better: the market cannot be closed while it is holding anyone's property.

That is not a weakness dressed up as a feature. Total immutability would mean a dead contract could hold property forever, which is precisely the problem this project measured elsewhere, in the 14,546 pieces still stuck in the escrow of a marketplace that shut down. This contract is built so that cannot happen to it.

The guards behind each public promise

A suspicious reader will check these first. Each one was made to refuse on the program in service.

What the market promisesWhere the guard refused
The market cannot disappear taking your property with it With fifteen listings and three auctions really in the vault
The operator cannot help themselves to your proceeds At a twenty per cent ceiling, refused to the unit
A seller cannot back out once your price has been met On an auction actually run to its reserve
What could not be paid to you comes back to you Balances checked before and after: the money returns to the exact figure, the one-of-one piece returns to its owner
The operator cannot sweep up what is owed to you On a debt one moment old, against a two-year limit
The market cannot be bricked for a dollar In both directions: closing refuses while the vault holds anything else, and the currency closes once it is empty

Seven reviews, and what they found out about each other

Seven security reviews were carried out, on six different versions of the contract, and the versions they examined are archived so that each review can be replayed against the exact object it looked at. That is what separates a verifiable audit trail from a list of assurances. Thirty-two versions are archived in total, four of them recovered from the creation transactions of instances that have since been closed: the program of a closed application survives in the transaction that created it.

The last two reviews worked blind, without knowing of each other, and they have not a single finding in common. Zero out of five. That is the most important result in this file, and it does not mean the reviews were poor. It means the coverage of any single review is far narrower than it looks, and this project measured that instead of assuming it.

What is still open

Publishing these makes the rest of the page stronger, not weaker.

  1. One correction is read, not measured. A deposit that one seller could capture from another has been fixed, and the fix was reviewed by reading the code. Proving it would take two sellers of the same multi-edition asset and a withdrawal by the first before the second. That has not been done, and it is recorded here as read rather than observed.
  2. Two guards out of eighty-two were never made to refuse, because they are out of reach. They remain in the contract as defence in depth.
  3. A listing holds at most three editions, and there are eighteen units of budget left at three. That is a limit rather than a defect, but it leaves no room: any guard added to that path would bring it down to two.
  4. All of this was measured on the test network. The program engraved on MainNet has to be measured in its turn, and its fingerprint compared. Until that is done and published here, this page describes the test network and says so.

How to check any of this yourself

The audited object is a program, not an instance. Its fingerprint is fa74919269d4e64f, 6,429 bytes, and that is what the benches replay against: any instance running that exact bytecode will answer the same way. The fingerprint is read from the chain every time a bench runs, never from a file kept here, and a green check on a different object establishes nothing about this one.

If you want a place to start, application 770868027 on the test network was running that program when this page was last verified. We name it as a convenience and not as evidence. Test instances get deleted, and one that this page used to cite is already gone; the fingerprint is the part that does not expire.

Two test-network instances are deliberately kept alive and unclosable, each one the standing demonstration of a finding, and anyone can inspect them on the chain. The disassembly of the bytes read from the live instance, and the bench that produced the refusals, which submits nothing and costs nothing - are both published with this project.

Who did this work

The contract, the guards and the bench that made them refuse were written and run by Claude, an AI agent, under the direction of this project's author. That is stated plainly rather than shown as a badge, because a badge would suggest a company examined and endorsed this marketplace, and none did.

Which is exactly why this page is built the way it is. There is no authority here for you to defer to, so nothing on it asks you to. The instance is named, its fingerprint is published, the bench can be replayed by anyone and submits nothing, and every guard is described by what it actually refused rather than by what it is meant to prevent. Check the parts you care about; none of it depends on trusting who wrote it.

Last verified against the program in service on 2 September 2026. This page carries its own verification date because an audit page without one is a claim about the past presented as a fact about the present.

Your wallet

Read-only, until you sign

Connecting a wallet reads public data that anyone could read without you. Nothing is stored on a server, and no transaction can ever be signed without your explicit approval inside your own wallet application.

This site will never ask for a seed phrase, a private key or a password. Nobody legitimate ever will, here or anywhere.

What is not done yet

Said plainly

The archive covers mints up to March 31, 2023 so far, and 52 collections are marked as adult content and hidden by default. Shuffles are not open yet: they come next. Some collections are grouped wrong. Some images will never come back.

These are stated here rather than discovered by you, because an archive that oversells itself is not worth trusting on the parts that are right.

How you can help

Corrections welcome

If you recognise a collection that is missing, grouped wrong, or credited to the wrong creator, saying so is worth more than any amount of automated tuning. The same goes for a piece of history: who made it, what it was for, whether the project is still alive.

Tell us something →