lANTS
Back to market

Introduction

The lANTS marketplace is a contract for listing and selling lANTS positions on Base (chainId 8453). Positions are ERC-721 tokens issued by the AntseedSellerPools collection. Payment is settled in USDC.

This site documents the deployed contracts as they are, including their current limits. It does not describe planned features as if they existed.

Contracts

ComponentAddress
Marketplace (VexyMarketplace)0xC5BFc309a68dBf4e7eEca9BD91749d611c75C660
Position collection (AntseedSellerPools)0x8Bf4d39AA13F3CB03F87D9500767fBc4D0940652
USDC (6 decimals)0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
ANTS token0xa87EE81b2C0Bc659307ca2D9ffdC38514DD85263
Emissions (emissionsGate)0xE60a31E6CD2F8455503cA0B3f6545Dd3DDF543BD
Operator / fee recipient0x3d4CCcfAA3B25997F4ab33f838558521259Eef1B

ENS name: lants.eth.

What you can do today

  • List an lANTS position you own for a USDC price.
  • Buy a listed position; the token transfers directly from seller to buyer.
  • Cancel your own listings at any time, for free.
  • Manage a position: stake a finished epoch's buyer reward, split, move to another pool, or enable max-lock.
  • See your positions and your listings in My Portfolio.
  • Claim a position's staker reward to your wallet, or restake it as a new position, with one click.
  • On the Incentives tab: a network row above the board, and a ▾ details view per seller (revenue, buyers,

models from antscan).

  • A "Buyer ANTS per $1" column: how many ANTS the network returns to a buyer for each $1 spent with that seller

in the current epoch. 0 means the seller has no pool. A "Selling, but no pool" list shows those sellers and the steps to create a pool.

  • Two offer types. Stake: a seller pays USDC to stakers for weight in their pool. Rebate: the seller or a sponsor

returns a % of buyers' spend in USDC, calculated from chain data. Rebate campaigns are funded before the epoch in the shared RebateClaims contract and buyers claim their share themselves (14-day window). A "spend $Y → get $Z back" calculator shows what a buyer gets back. Details: docs/incentives.md.

A 1% fee is taken from each sale and sent to the fee recipient.

What does not exist yet

  • Bids on positions. The market contract stores listings only; you cannot bid on a position yet.
  • Escrow for stake offers. Stake offers are still paid directly by the payer named on the offer after the

epoch. Rebate offers use the shared claims contract: nothing is sent by hand, buyers claim with a merkle proof and the unclaimed part returns to the seller.

How this site reads the chain

The positions table works from a snapshot taken at a fixed block, refreshed three times a day; the line under the table shows its block, epoch and time. Listings, sales, My Portfolio and the MC / FDV figures are read live from Base in your browser.

Origin

The marketplace contract is adapted from Vexy by @0xValde. The source is marked UNLICENSED. The credit is stated here and in Privacy & Terms, openly and without hiding it.

Who runs this

The project is built by one person with help from AntSeed network models. There is no company and no team page.

How it works

The marketplace lets an NFT owner list a token for sale in USDC without transferring the token into escrow. The NFT stays in the seller's wallet until a purchase completes.

Roles and custody

The seller keeps ownership of the NFT for the entire life of a listing. To make a sale possible, the seller must approve the marketplace to move the token:

setApprovalForAll(market, true)   // selector 0xa22cb465

Without this approval a buyer's transaction reaches the payment stage and then reverts on the ERC-721 transfer. No funds change hands in a reverted transaction.

Currency and price format

All listings are priced in USDC. USDC uses 6 decimals, so a price is an integer count of micro-dollars:

PriceValue passed to the contract
$0.10100000
$1.001000000
$100.00100000000

The contract rejects any currency other than USDC.

Fee

A fixed 1% fee applies to every sale:

FEE = 0.01 ether
fee = price * FEE / 1e18   // exactly 1% of price

On purchase the buyer pays price. The seller receives price - fee, and the fee recipient receives fee. Both transfers happen in the same transaction.

Lifetime

Every listing has an end time set at creation:

endTime = block.timestamp + fixedDuration + slopeDuration

The combined duration cannot exceed 60 days. After endTime the listing can no longer be bought; a purchase attempt reverts.

Cancellation

A seller cancels by calling:

cancelNftListings(nftCollection, nftId)

This increments the seller's nonce for that NFT. Every prior listing on that token no longer matches the current nonce and becomes invalid. Cancellation costs only gas.

It does not delete anything. The listing record stays in the listings array, and the transaction history remains on-chain permanently. "Invalid" means unbuyable, not removed.

Listings

A listing records who is selling which NFT, at what price, in USDC, and until when.

Creating a listing

Listings are created with:

createListing(
  address nftCollection,
  uint256 nftId,
  address currency,       // must be USDC
  uint256 price,
  uint96  slopeMax,
  uint32  slopeDuration,
  uint32  fixedDuration
)

Requirements enforced by the contract:

CheckMeaning
ownerOf(nftId) == msg.senderYou must own the NFT to list it.
slopeDuration + fixedDuration <= 60 daysTotal lifetime is capped at 60 days.
currency == USDCOnly USDC is accepted.
listingPrice(listingId) > 0A zero-price listing cannot be created.

The NFT is not moved on listing. Remember to approve the marketplace (setApprovalForAll), or sales will revert.

Fixed price vs. Dutch auction

The contract supports two pricing modes through the same function.

Fixed price. With slopeMax = 0 and slopeDuration = 0, listingPrice always returns the base price. The listing form on this site creates fixed-price listings only.

Dutch auction. With a non-zero slopeMax and slopeDuration, the price starts above the base price and falls to it along a cubic curve:

r = (endTime - fixedDuration - now) * 1e12 / slopeDuration
price = basePrice + (basePrice * r^3 / 1e36) * slopeMax / 1e18

Once the slope period has passed, listingPrice returns the base price. Dutch-auction listings are not offered by the form and must be created by calling the contract directly.

Buying a listing

buyListing(uint256 listingId)

Conditions that must all hold:

CheckIf it fails
soldTime == 0Already sold.
endTime >= block.timestampListing has expired.
sellerNftNonce == current nonceListing was cancelled.

When all conditions hold, the buyer pays price in USDC. The seller receives price - fee, the fee recipient receives fee, and the NFT is transferred from seller to buyer in the same transaction.

MC / FDV on each lot

The table shows what a lot's price implies for ANTS as a whole:

price per ANTS = price / ANTS in the position
MC  = price per ANTS * totalSupply()   // ANTS minted so far, read live from the token
FDV = price per ANTS * MAX_SUPPLY()    // 1,040,000,000 ANTS

Example: 10 ANTS for 0.10 USDC is $0.01 per ANTS, an MC of about $1.19M and an FDV of about $10.4M. Trades between our own wallets are labelled *internal* and are not counted in volume or in the Implied FDV tile.

Positions & Rewards

A staking position is an ERC-721 token minted when you stake ANTS into a seller's pool. One stake produces one token. The collection is 0x8Bf4d39AA13F3CB03F87D9500767fBc4D0940652.

positions(uint256) returns: owner, agentId, amount, weightAmount, stakeStartEpoch, stakeEndEpoch, closedAtEpoch, withdrawn.

Example — position #27, read on-chain:

FieldValue
owner0x3d4CCcfAA3B25997F4ab33f838558521259Eef1B
agentId52894
amount10,075.913604428940056768 ANTS
stakeStartEpoch24
stakeEndEpoch128 (104-epoch lock)
closedAtEpoch0
withdrawnfalse

Epochs. An epoch lasts one week. Epoch 23 began 2026-09-17 09:54 UTC; epoch 24 begins 2026-09-24 09:54 UTC. currentEpoch() at snapshot time was 23.

Activation. stakeActivationDelay() = 1, so a position is not active in the epoch it is created; it earns from the next epoch.

Max-lock. enableMaxLock keeps a position's weight at amount × 104. After it, splitStake and moveStake revert with PositionClosed() even though closedAtEpoch is 0 (measured on 2026-09-26 on #27 and #111; the same calls pass on positions without max-lock). Split or move first, then enable max-lock.

Lock bounds. minStakeEpochs() = 1, MAX_STAKE_EPOCHS() = 104.

Early exit. Exiting before the end epoch is slashed by earlyExitSlashBps. For #27 this is 50%. The floor you recover on early exit is amount * (1 - slash) = 5,037.96 ANTS.

Rewards. A staker's reward for an epoch is driven by pool *sales*, not by stake size:

poolReward     = stakerBudget * (poolSales * poolWeight) / sum(poolSales * poolWeight over all pools)
positionReward = poolReward * positionWeight / poolWeight

stakerBudget = 100,000 ANTS per epoch, read via raw selector 0x56ab55c5 on the emissionsGate contract 0xE60a31E6CD2F8455503cA0B3f6545Dd3DDF543BD at block 51613321. This selector has no name in any signature database and the contract ABI is not verified. The value is constant across epochs 21, 22 and 23 and equals 2% of the weekly emission of 5,000,000 ANTS derived from currentEmissionRate().

Position #27 metrics at snapshot block 51613321 (epoch 23), for the next epoch:

MetricValueDefinition
reward38,486 ANTSnext-epoch position reward
yield3.820reward / amount
payback0.131floor / reward (epochs for the reward to cover the floor)

Transferability. ANTS is non-transferable between wallets: transfersEnabled() = false, and a direct transfer reverts with TransfersNotEnabled(). The token checks the *sender*: only whitelisted contracts (the stake and reward contracts) can send ANTS. So ANTS in your wallet can be neither sent nor staked; rewards become new positions only through Restake. ANTS you Claim stay in your wallet until transfers are enabled. Because of this, the position NFT is the only way to move locked ANTS.

---

Snapshot & Data

The positions table computes from a snapshot, not from a live read of the whole network. A GitHub Actions job refreshes it three times a day (06, 14 and 22 UTC); the line under the table reads Snapshot: block ..., epoch ..., taken ....

Pool weights are read with poolWeightAtEpoch(agentId, epoch) for every pool with non-zero sales.

Known defect, fixed. Before 2026-09-21, weights were collected only for the 32 pools that hold our own positions, so the reward denominator was understated. The ratio of the full denominator to the partial one was 1.1179. As a result the site showed #27 at 43,022 instead of 38,486 — 11.8% too high. The defect was found and corrected, and the snapshot was rebuilt.

Sources. Pool sales come from the public API antscan.co/api/sellers, a third-party community site, not an on-chain source. Everything else is read directly from Base.

Cross-check. Every snapshot number is read on two independent RPCs (base-rpc.publicnode.com and base-mainnet.public.blastapi.io) at the same block and compared. If they disagree, the snapshot is not published.

Live reads. Listings, sales, My Portfolio and the MC / FDV figures do not come from the snapshot: your browser reads them directly from Base through public RPC endpoints.

Privacy. The page has no backend and does not collect user data. Transactions go through your wallet; reads go through public RPC endpoints.

---

FAQ

What is a lANTS position, and why does this market exist?

A position is an ERC-721 from the AntseedSellerPools collection (0x8Bf4d39AA13F3CB03F87D9500767fBc4D0940652 on Base, chainId 8453). It represents ANTS locked by staking into a seller pool. ANTS themselves are non-transferable between wallets: transfersEnabled() is false and a transfer reverts with TransfersNotEnabled(). The stake contract sits in the transfer whitelist, so the position NFT is the only way to hand locked ANTS to another wallet. This market exists so that NFT can change hands.

How do I get a position?

The main path is to stake: call stake(agentId, amount, stakeEpochs) on the pool, which mints the position NFT to you. stakeEpochs runs from minStakeEpochs = 1 to MAX_STAKE_EPOCHS = 104, where one epoch is one week. The position activates from the next epoch: stakeActivationDelay = 1. The other path is to buy an existing position from a listing here.

How do I list a position for sale?

First call setApprovalForAll for the marketplace, VexyMarketplace (0xC5BFc309a68dBf4e7eEca9BD91749d611c75C660); the NFT stays in your wallet. Then call createListing(nftCollection, nftId, currency, price, slopeMax, slopeDuration, fixedDuration). Settlement is in USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, 6 decimals). The seller pays a 1 % fee on sale. slopeDuration + fixedDuration must be <= 60 days.

What is the difference between a fixed price and a Dutch auction?

Fixed price: slopeMax = 0 and slopeDuration = 0. The price is constant. Dutch auction: slopeMax and slopeDuration are non-zero. price is the base price, which is also the final and minimum price; the auction starts above it and declines toward it.

How does the Dutch auction price actually move?

r is the remaining slope time: r = (endTime - fixedDuration - now) * 1e12 / slopeDuration. The price is price + (price * r^3 / 1e36) * slopeMax / 1e18. Early in the slope r is near 1, so the price is at its maximum and falls fast; toward the end it flattens out at the base price. The r^3 term means most of the drop happens near the start.

How do I buy a listing?

Buyers fill a listing directly at its current price, paid in USDC. There is no bidding and no offer system: no offer contract exists.

How do I cancel a listing?

Call cancelNftListings(nftCollection, nftId). It cancels ALL of your listings on that NFT at once by incrementing the nonce; you cannot cancel a single lot by id. The records are not deleted, they just become unbuyable. The only cost is gas.

How much will my position sell for?

We don't predict prices. The data so far: one internal test trade on 2026-09-25 (50 ANTS for 1.00 USDC, between our own wallets, not counted in volume) and five public lots of 10 ANTS at 0.10 USDC each, listed on 2026-09-26. Every lot shows the MC and FDV its price implies. Anyone citing an expected price is guessing.

Are there any listings right now?

Open the Listings tab: listings are read live from the chain, and sold or cancelled ones are labelled. There is no offer system: buyers fill listings directly, they do not bid.

What do MC and FDV mean on a lot?

They translate a lot's price into a valuation of ANTS: price per ANTS times ANTS minted so far (MC) and times the 1.04B max supply (FDV). A bare USDC price for a position is hard to compare; these two numbers make lots of any size comparable.

Why are Split and Move disabled for my position?

The position is on max-lock. The contract reverts split and move on a max-locked position, so the site disables those buttons. Split or move before enabling max-lock.

How does the interface read data?

This site is static. All reads come from your connected wallet or a public RPC endpoint. There is no backend, no database, no server-side indexer of ours.

Who makes this, and what do you collect about me?

One person, with help from AntSeed network models. There is no company and no team. We collect nothing: no accounts, no analytics, no cookies, no logs. See Privacy & Terms.

Contact

Reach out on X. The ENS name lants.eth is a wallet address for on-chain interaction, not an inbox. We make no promise to respond.

ChannelWhereUse it for
X@TheTieTieTiesQuestions and notes
ENSlants.ethIdentifying the operator wallet on-chain

Privacy & Terms

Privacy

This interface is static and non-custodial. It never touches your keys or funds — every action is a transaction you sign in your own wallet.

  • The wallet modal is Privy (privy.io), a React SDK bundled into this page; it talks to Privy servers (auth.privy.io) when the modal opens and a wallet connects. Login is wallet-only — no email, no social accounts, no embedded wallets — and connecting a phone by QR uses the public WalletConnect relay through the WalletConnect project ID configured by Privy.
  • We use no analytics, no logging, no cookies. We do not collect or store personal data ourselves.
  • Anything you send to the blockchain — addresses, listings, trades — is

public and permanent. We can't delete or alter it, and neither can anyone else.

Terms

  • The marketplace contract is adapted from Vexy and provided as-is, without

warranties of any kind.

  • You are responsible for verifying contract addresses before you interact and

for reviewing every transaction you sign.

  • Eligibility: don't use this interface if doing so is prohibited where you live.

We have no way to verify who you are and make no representation that use is lawful in your jurisdiction — that check is yours.

We are not a registered entity and hold none of your data or assets. This is software, used at your own risk.