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. Trading opens only once the contract that would hold your pieces and your money has been reviewed by someone other than its author, and once every safeguard written into it has been made to refuse something. 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 refuse | 80 of 82 written into the program |
| Chapters of testing | 14, run by 22 replayable benches |
| Refusal attempts written | 113, plus 24 positive controls |
| Instances used | 3: 770868027 (59 guards), 770867198 (19), 770913547 (2) |
| Program | 6,429 bytes, fingerprint fa74919269d4e64f |
| Network | TestNet |
| Last verified | 2 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.
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.
| Chapter | Guards proven |
|---|---|
| Currencies, settings and the operator role | 18 |
| Shape checks and upper bounds | 12 |
| Offers and claims | 11 |
| Auctions | 10 |
| Buying, and the life of a listing | 5 |
| Offers paid in a token, and the exempt token | 5 |
| Listing a piece | 3 |
| Auctions run to their end | 3 |
| Debts | 3 |
| A newly accepted currency | 3 |
| Guards that require an action first | 2 |
| Time-limit guards | 2 |
| Debt owed as a piece | 2 |
| Opting out of an asset | 1 |
How many attempts, and what is not counted
113 refusal attempts are written across the 22 benches, alongside 24
positive controls. The 80 proven guards counted here all belong to
application 770868027 and its twins, fingerprint fa74919269d4e64f.
Other versions of this contract carry different counts, and their figures
are not mixed in: the stock mechanism written in September has 87 guards on
a different program, and its five proven so far are recorded separately. Those are transactions built on purpose to break a
specific rule, submitted to the contract, and expected to come back refused.
And here is what that number does not tell you. The register records guards proven, not attempts made: 80 distinct guards for 113 written attempts, because several guards are approached from more than one angle and some attempts belong to benches for other versions of the contract. 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 named guards, 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.
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 promises | Where 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.
- 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.
- 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.
- 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.
- 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 named without ambiguity: application 770868027, program fingerprint fa74919269d4e64f, 6,429 bytes, on the test network. The fingerprint is read from the chain every time the bench runs, never from a file kept here, a green check on a different object establishes nothing about this one.
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.