Appearance
Errors
Every custom error either contract can revert with, its 4-byte selector, what actually causes it, and a message worth showing a user.
Selectors are the first four bytes of keccak256 over the error signature — they are what you see in a raw revert before decoding.
LootMarket
Listed in the order fulfillOrder checks them. That ordering is useful when debugging: the error you get is the first failing condition, so anything below it is untested.
| Selector | Error | Cause | Show the user |
|---|---|---|---|
0xa113a3fc | SelfPurchase() | Buyer is the maker | "You can't buy your own listing." |
0x2136832c | CollectionNotAllowed(address) | Collection removed from the allow-list | "This collection isn't tradable." |
0x8a6ce247 | CurrencyNotAllowed(address) | Currency not allow-listed | "This payment method is unavailable." |
0xc56873ba | OrderExpired() | block.timestamp > order.expiry | "This listing has expired." |
0x89b514f5 | NonceUsedOrCancelled() | Already filled, or cancelled | "This listing was already sold or cancelled." |
0xdb29391f | NonceBelowMinimum() | Seller bulk-cancelled via setMinimumNonce | "The seller cancelled their listings." |
0x8baa579f | InvalidSignature() | Doesn't recover to order.maker — tampered order, wrong chain id, or a smart-contract wallet | "This listing is invalid." |
0x5e885439 | MakerNotOwner() | Seller transferred, sold or burned the token | "The seller no longer owns this item." |
0xdf7badef | MarketNotApproved() | Neither operator nor per-token approval | "The seller revoked approval; the listing is stale." |
0x0d35e921 | IncorrectPayment(uint256 expected, uint256 provided) | Native value below price | "Payment amount is incorrect." |
0x1a9fe9f6 | NativeNotAccepted() | Sent ETH on an ERC-20 order | Caller bug — fix it |
0x94ca97e4 | FeeExceedsPrice() | Royalty + platform fee exceed the price | "This listing can't be filled." |
0xcd4e6167 | FeeTooHigh() | Owner tried to set a fee above 10% | Admin only |
0xf0c49d44 | RefundFailed() | Excess refund to the buyer failed | "Payment failed — nothing was charged." |
0xf499da20 | PaymentFailed() | A payout transfer failed | "Payment failed — nothing was charged." |
Plus OpenZeppelin's EnforcedPause() when trading is paused, and ReentrancyGuardReentrantCall().
SelfPurchase is live as of the 2026-08-11 upgrade
Filling your own order reverts. Before that upgrade it succeeded, so if you are reading historical transactions you may find fills where maker and taker match.
LootSkins
| Selector | Error | Cause | Show the user |
|---|---|---|---|
0x4d65ccb8 | NotOwner(uint256 tokenId) | Burning a token you don't directly own | "You don't own this token." |
0xa458261b | InsufficientFee(uint256 required, uint256 provided) | Sent less than withdrawFee × count | "Withdrawal fee is incorrect." |
0xa67b9f9e | BatchTooLarge(uint256 length) | More than 50 ids in one call | "Withdraw at most 50 at a time." |
0xc2e5347d | EmptyBatch() | Empty id array | Caller bug |
0xc364c29e | InvalidCategory(uint256 category) | Category byte ≥ 8 | Minting only |
0xf8d2906c | NotMinter() | Caller is not on the minter allow-list | Minting only |
0x4033e4e3 | FeeTransferFailed() | Fee sweep failed | Admin only |
0xd92e233d | ZeroAddress() | An address argument was zero | Caller bug |
Plus the standard ERC-721 errors (ERC721NonexistentToken, ERC721InsufficientApproval, …).
NotOwner on a burn is usually an approval misunderstanding
deTokenize requires direct ownership. Being an approved operator is not enough — that restriction is deliberate, so the Detokenized event's owner is always the true owner and the physical item is returned to the right person.
Decoding a raw revert
A revert arrives as 4 selector bytes plus ABI-encoded arguments.
bash
cast 4byte 0x5e885439
# → MakerNotOwner()ts
import { decodeErrorResult } from "viem";
const decoded = decodeErrorResult({ abi: marketAbi, data: err.data });
// { errorName: "MakerNotOwner", args: [] }viem surfaces this automatically on simulateContract, which is the main reason to simulate before writing — see Fill an order.
Integration mistakes that produce these
| Mistake | Error |
|---|---|
Forgot setApprovalForAll before listing | MarketNotApproved |
Checked only isApprovedForAll, ignoring per-token approval | none — you wrongly reject a valid order |
| Reused a nonce | NonceUsedOrCancelled |
Picked a nonce below minimumNonce | NonceBelowMinimum |
| Signed with a Safe / AA wallet | InvalidSignature |
| Signed against the wrong chain id | InvalidSignature |
Reordered the Order struct fields | InvalidSignature |
Sent msg.value on an ERC-20 order | NativeNotAccepted |
Sent more than withdrawFee × count | none — the excess is kept, not refunded |