666 pixel Agent avatars, with the image and the metadata 100% written into the contract on BNB Chain.
Minting has no gate — any wallet on BNB Chain can call mint(). The first 200 are free, one per wallet, and they are soulbound: they can never be transferred or sold. The remaining 466 are paid, transferable, starting at 0.002 BNB and stepping up by 0.0005 BNB every 50 tokens. Passing a referrer address to mint() pays that address 20% of the price.
This project has exactly one source of revenue: the mint fee. No token, no staking, no dividends, no roadmap promises, no referral programme. Buying one is buying a very cheap on-chain pixel image that can never go offline, plus a receipt that you were an early Agent user.
Total supply is fixed at 666 and cannot be inflated. There is no team reserve — the constructor mints nothing,
so totalSupply() starts at 0 and every single token must be paid for.
The price is a pure function of tokenId:
priceAt(id) = 0 for id ≤ 200
priceAt(id) = PRICE_START + tier × PRICE_STEP where tier = (id − 201) / 50
PRICE_START = 0.002 BNB, PRICE_STEP = 0.0005 BNB, TIER_SIZE = 50,
FREE_QUOTA = 200.
Two hundred free Founder tokens plus ten paid tiers of 50 plus a 16-token tail make exactly 666
(666 = 200 + 50 × 9 + 16).
| Tier | tokenId | Unit price | Quantity | Subtotal | Frame |
|---|---|---|---|---|---|
| Founder | 1 – 200 | FREE | 200 | 0 BNB | soulbound |
| Tier 1 | 201 – 250 | 0.002000 BNB | 50 | 0.1000 BNB | none |
| Tier 2 | 251 – 300 | 0.002500 BNB | 50 | 0.1250 BNB | none |
| Tier 3 | 301 – 350 | 0.003000 BNB | 50 | 0.1500 BNB | none |
| Tier 4 | 351 – 400 | 0.003500 BNB | 50 | 0.1750 BNB | none |
| Tier 5 | 401 – 450 | 0.004000 BNB | 50 | 0.2000 BNB | none |
| Tier 6 | 451 – 500 | 0.004500 BNB | 50 | 0.2250 BNB | none |
| Tier 7 | 501 – 550 | 0.005000 BNB | 50 | 0.2500 BNB | none |
| Tier 8 | 551 – 600 | 0.005500 BNB | 50 | 0.2750 BNB | none |
| Tier 9 | 601 – 650 | 0.006000 BNB | 50 | 0.3000 BNB | none |
| Tier 10 | 651 – 666 | 0.006500 BNB | 16 | 0.1040 BNB | final |
A full sell-out corresponds to 3.5964 BNB in total mint volume. There is no price-changing function anywhere in the contract — not "we won't change it", there is simply no such entry point in the code.
Prices are denominated in BNB, so the dollar figure drifts with the BNB price. 0.002 BNB was about 1.4 USD when the contract was written; it is about 2 USD at BNB ≈ $742. No oracle is involved on purpose — fewer moving parts.
There is none. mint() checks the supply counter and nothing else — any address on BNB Chain can call it.
Version 3 required holding a .ai Agent ID; that gate was removed in version 4 and cannot be re-added.
hasAgentId() still exists in the ABI for compatibility and always returns true.
One restriction does apply, to Founder tokens. Token ids 1–200 can never be transferred: transferFrom,
safeTransferFrom and list() all revert with SOULBOUND. Paid tokens (201–666) move freely.
MAX_PER_TX)MAX_PER_WALLET)mint() rejects any free claim with qty ≠ 1
mint(qty) sums priceAt() over the ids it is about to issue. Sending less reverts with
UNDERPAID; sending more is accepted and the excess is refunded in the same transaction. Any extra gas is yours;
the contract keeps none of it. A free claim needs msg.value = 0 — you pay gas only.
The owner can pause minting with setMintOpen(false), but cannot change the price, change the supply, change the free quota, un-soulbound a Founder token, or change the referral rate.
Traits are read from different bit ranges of keccak256(abi.encodePacked(PROVENANCE, tokenId)):
eight dimensions in total:
| Dimension | Values | Count | Bit offset |
|---|---|---|---|
| Head | Block / Rounded / Wide | 5 | seed >> 2 |
| Eyes | Single / Double / Void / Visor | 4 | seed >> 6 |
| Mouth | Line / Dot / Smile / Silent | 4 | seed >> 10 |
| Antenna | None / Stalk / Twin / Ears | 4 | seed >> 14 |
| Palette | 10 bright colors | 10 | seed >> 18 |
| Accent | 10 outline colors | 10 | seed >> 22 |
| Glow | 10 glow colors | 10 | seed >> 26 |
| Background | 4 dark colors | 4 | seed % 4 |
tokenURI() returns base64-encoded JSON, and the image field is a base64-encoded SVG.
Both are assembled by the contract on the spot and read no external resource. The attributes order in the JSON is fixed at
Tier / Head / Eyes / Mouth / Antenna / Palette / Edition.
This site reproduces the same rendering algorithm in the browser, for the gallery's batch display. The rendered result is
byte-for-byte identical to the un-framed part of the SVG in the on-chain tokenURI() output — that is guarded by a
contract test case, not by a verbal promise. The frame is added by the contract only (svgOf()), because it depends on the tier.
PROVENANCE is a bytes32 written into the constructor at deployment and cannot be modified afterwards. It guarantees that "the rules were nailed down in advance": anyone can recompute exactly the same image from the same PROVENANCE + tokenId, so the project cannot hold back rare pieces for itself once minting opens. It is not a random number, and there is no reveal stage.
This contract reuses the PROVENANCE of the first version, so a given tokenId draws the same face it always did — the only difference is the frame, which is new.
Market logic lives directly inside the NFT contract: no separate matching contract, and no approval to any third-party marketplace needed.
list(tokenId, price) — the holder lists; the price is set by the seller (> 0)cancel(tokenId) — only the lister can cancelbuy(tokenId) — fills at the listing price; no gate of any kind
On a fill MARKET_FEE_BPS = 300, i.e. 3% to the treasury, and the seller receives 97% immediately, with no second claim step.
If a listed token is moved away by a direct transferFrom, the listing automatically becomes invalid, so "already sold but still fillable" cannot happen.
The contract also declares a 5% royalty through ERC2981 (royaltyInfo). External marketplaces that honour the standard
will pay it to the fee recipient; those that ignore ERC2981 will not, and there is nothing the contract can do about that.
Direct transfers between wallets, or just giving one to a friend, cost nothing from the contract.
The first version of this project gave its first 2,000 tokens away free. It lasted one night.
On-chain, the aftermath is unambiguous: 896 tokens went to 87 addresses. Those addresses averaged 177 lifetime transactions each and a balance of 0.027 BNB; 37% of them minted exactly the 5-per-wallet cap and stopped. They were not users. They were airdrop farms running scripts. The tokens were transferable, so the farms could sell them — that was the whole business model.
The second version added a server-side signature so that a free mint required a real X post from the wallet. It worked exactly as designed — the scripts could not get past it. It also revealed the other half of the problem: over the following days, four addresses bothered to complete that flow. The third and fourth versions dropped the free tier entirely; version 4 sold zero in twenty-two hours.
A free tier with transferable tokens buys you scripts. A free tier with soulbound tokens buys you nothing at all — which is exactly the point. There is no arbitrage, so the only people who claim one are people who want the avatar. That is the whole design: give the free tier back, remove the reason to farm it, and let the paid tiers carry the revenue. Version 5 went live and had nine distinct wallets claim Founder tokens within three minutes, one each — no farm pattern.
Spelling out what the owner can and cannot do, so nobody has to guess:
| Action | Can owner do it | Notes |
|---|---|---|
| Pause / resume minting | Yes | setMintOpen |
| Change the fee recipient | Yes | setFeeRecipient |
| Withdraw accrued fees | Yes | withdraw, any address |
| Transfer contract ownership | Yes | transferOwnership |
| Change the price | No | constant, no entry point |
| Change supply / inflate | No | MAX_SUPPLY is a constant |
| Change the tier size | No | TIER_SIZE is a constant |
| Re-enable a mint gate | No | not in the contract |
| Change PROVENANCE | No | immutable |
| Touch someone else's token | No | there is no admin transfer |
| Change the market fee or royalty | No | constants, 300 and 500 bps |
| Get more than one free Founder token | No | 1 per wallet, enforced in the contract |
| Un-soulbound a Founder token | No | the check is on the token id, not on a flag |
Mint revenue accrues to the contract and is withdrawn by the owner, in one transaction, to any address. There is no per-transaction splitting and no referral accounting:
feeRecipient)None of it flows into a "holder dividend pool" — the reason is in the next section.
What is not promised:
Risks you should accept:
On "why there is no dividend": we did the math — assume all 1.904 BNB of paid tiers sells out and 100% is distributed to the 666 holders; that is 0.0054 BNB each, a few dollars at the exchange rate when this was written. Bringing reentrancy attack surface and gas cost into the contract for that amount would be trading safety for a gimmick. Not doing it.
| Item | Value |
|---|---|
| Network | BNB Smart Chain (chainId 56) |
| Contract address | 0xff5c3878d5577c4178654196e1db4c511d2dfd27 |
| Standard | ERC-721 + ERC2981 (hand-written, no OpenZeppelin dependency) |
| Solidity | 0.8.24 |
| Runtime bytecode | 22,068 B |
| PROVENANCE | 0xf33d1f95ef57b92d213d9bd3c34ac3507d884f9a1070b7b068fa03608ed3e926 |
| PROVENANCE source | keccak256(utf8("PIXELOX-AGENT-PASS-V1")) |
| Mint gate | none (v4) |
| Market fee | 300 bps (3%) |
| ERC2981 royalty | 500 bps (5%) |
| Deploy block | 130,445,602 · 2026-10-29 17:01:26 (+08) |
| Compiler | solc 0.8.24 · optimizer enabled · runs 200 · viaIR off |
| Constructor args | (0x60B9…022F, 0xf4b4…7381, 0xf33d1f95…3e926) |
| Deployment transaction | 0x7cb867fe9973b0b584c2fbe938a6d3070965831d2c2b36729eb0a571a78e2951 |
| creation length | 21,224 B |
| creation keccak256 | 0xb90860c27cf0dea3f1607d545f1c7d853a597c7ce0cbddd7bdcc7707f3ca73ef |
| Runtime keccak256 | 0xcddb844311df9a52ca94a28ba57e93da819bb80ba3b05a635d6e9da6e8496717 |
Compile PixeloxAgentPassV3.sol with the compiler settings above, append the three ABI-encoded constructor args, and keccak256 of the resulting byte string equals 0xb90860c…73ef — the same value the deployment transaction carries on-chain. As long as that number matches, the code running on-chain is this source, with no section of it swapped in afterwards.