Tax
Every transaction on merca.earth — registration, buyout, expansion, slice acquisition — reserves 8% of the payment for the spatial hierarchy. That 8% flows upward as cash flow for parent parcel owners.
This page explains how that flow works, what you need to do to claim it, and what happens if you don't.
See also: Fees → Payment-Bearing Operations, Cash Flows → Tax Collection, Collect Tax → Claiming Tax Revenue.
Where the 8% goes
The split depends on whether there's a seller. Registrations and expansions into unclaimed land have no seller, so the treasury takes the non-hierarchy share. Buyouts and slice acquisitions pay a seller.
| Operation | Treasury | Seller | Hierarchy pool |
|---|---|---|---|
register, expand_unclaimed | 92% | — | 8% |
buy_full, acquire_slice | 7% | 85% | 8% |
The hierarchy pool doesn't go to a central authority. It flows into a tax bucket on the transacted parcel and waits there for the direct parent parcel owner to collect it.
If no parent exists at that level — for example, a top-level parcel with nothing above it — the hierarchy pool routes directly to treasury instead.
What a tax bucket is
A tax bucket is an on-chain escrow record tied to a specific parcel. Think of it as a labeled envelope: it holds a MIST amount and records exactly where the money came from and when.
Each bucket is keyed by the composite identity (polygon_id, version, bucket_id, origin_level_rank, ancestor_distance, accrual_epoch).
This means the parcel, its geometry version, the bucket itself, the hierarchy path, and the accrual epoch all have to match. Buckets from different hierarchy paths — different origin_level_rank or ancestor_distance — stay separate, and buckets opened in different origination epochs stay separate too.
When a parcel's geometry changes — through expansion, rebalance, merge, or slice acquisition — the old version closes and new buckets open on the new version. Old buckets from the previous version remain collectible until they expire.
The four operations that create tax buckets are: register, buy_full, expand_unclaimed, and acquire_slice. For acquire_slice, the bucket opens on the donor parcel (the one selling area), not the receiver.
How cascade collection works
Tax doesn't jump straight to the top of the hierarchy. It moves one level at a time.
When a parcel is sold, a bucket opens on that parcel. The direct parent collects it by calling collect_tax. The parent keeps 50% and forwards 50% upward as a new cascade bucket on itself. The grandparent then collects that cascade bucket, takes an equal share of what remains, and forwards the rest. This continues until the top level is reached or the forwarded amount falls below the minimum threshold.
The direct parent always receives exactly half the upstream amount. Each subsequent ancestor receives an equal share of the remainder, split evenly among however many ancestors remain above them.
After collecting, the parent's share transfers directly to the parcel owner in the same collect_tax call.
Full cascade formula (technical reference)
Given levels (block → district → city → region → country → continent):
When , the collector is the top ancestor — it takes the full upstream amount. When and , the direct parent takes exactly 50% and forwards the rest. For deeper ancestors, the amount splits evenly among the current collector and the ancestors above it.
If the forward amount is below MIN_BUCKET_AMOUNT (1000 MIST), it is added to the current collector's share rather than opening a cascade bucket.
The anti-retro rule
A parent parcel can only collect tax from buckets that originated before or during the same epoch the parent was created.
If you register a new parent parcel today, it cannot reach back and claim tax buckets that opened before it existed. Same-epoch registration is eligible — only later-created parents are blocked.
This prevents retroactive extraction: you can't create a parent parcel specifically to harvest old tax that accumulated before you arrived.
Bucket expiry — the critical warning
Every tax bucket has a hard expiry:
Once the current epoch passes expires_at, the bucket is expired. Anyone — not just the parent owner — can call sweep_expired to move the uncollected funds permanently to the protocol treasury.
The bucket window and expiry window are per-level admin settings (TaxLevelCfg), not fixed protocol constants. Admins can configure different values for each hierarchy level. The current mainnet deployment uses a uniform config: 7-epoch bucket window and 30-epoch expiry across all levels. These are deployment choices, not protocol invariants.
Expired buckets cannot be recovered. If you own a parent parcel and miss the expiry window, that tax flow is gone. There is no grace period and no appeal.
The expiry obligation falls on the parent parcel owner, not the child. The child parcel owner loses nothing when a bucket expires — they already paid into the pool at transaction time.
Watch your expiry windows. The parcel detail panel shows collectable bucket counts and flags expired buckets you've missed.
What owners need to do
Collecting tax from child parcels
If you own a parent-level parcel that geographically contains child parcels, you can collect tax flow whenever those children transact.
To collect:
- Select your parent parcel on the map.
- Open the Taxes section in the Selected Parcel Panel.
- Click Collect. This calls
collect_tax, processing up to 20 child buckets per transaction.
collect_tax is permissionless — any sender can trigger it, but the tax always transfers to the parcel owner. The protocol enforces three correctness checks before accepting a collection:
- Rank equality — the parent's level rank must equal the child's origin level rank plus the ancestor distance.
- Containment — the parent parcel must geometrically contain the child parcel.
- Anti-retro — the parent parcel must have been created before or during the bucket's accrual epoch (no retroactive harvesting).
It processes all matching buckets for each child you specify and deletes them after collection — there's no risk of double-claiming.
When you sell a parcel
collect_tax transfers your share directly to your wallet in the same transaction. There's no separate withdrawal step.
Sweep expired buckets
sweep_expired is permissionless. Anyone can call it on an expired bucket to return the funds to treasury. You don't need to own the parcel.
This keeps the on-chain state clean and ensures uncollected tax doesn't sit in limbo indefinitely. If you spot an expired bucket on a parcel you don't own, you can sweep it — though there's no direct reward for doing so.
Summary
| Action | Who calls it | What it does |
|---|---|---|
collect_tax | Anyone (permissionless) | Collects child buckets, keeps cascade share for owner, forwards remainder up |
sweep_expired | Anyone | Sweeps expired uncollected bucket to treasury |
The tax system routes part of each lower-level payment upward. Large parent parcels can collect from activity inside their boundaries. More activity inside that territory means more tax flow to collect, provided you collect before expiry.
See Cash Flows → Why Hierarchy Position Matters for a broader view of how revenue flows on merca.earth, and Hierarchy → Why Hierarchy Matters Economically for the technical details of how tax cascades through the quadtree.