Skip to main content

Documentation Index

Fetch the complete documentation index at: https://filterfun.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Mainnet activation is gated on the Epic 2.3 audit. Contracts are live on Base Sepolia for testnet UX validation. Do not yet rely on bag-lock semantics on mainnet — until the audit clears, bag-lock is testnet-only.
Bag-lock is filter.fun’s structural answer to “trust me, I won’t dump my own bag.” A creator opts in to time-locking the tokens held by their own wallet. The lock is enforced by the token contract itself — it cannot be circumvented by the protocol, by the creator, or by anyone else.A creator with a 60-day lock has burned the option to rug for 60 days. That’s a different category of trust signal than “trust me bro.”

Why this is the killer feature

Every other launchpad — Clanker, Bankr, Pump.fun — lets creators dump their own holdings whenever they want. The trust gradient is asymmetric: creators promise restraint, holders cannot verify it. Bag-lock collapses that gradient. A locked creator’s commitment is a public, on-chain fact, readable by any block explorer, with no escape hatch and no unlock function.The product implication is simple: bag-locked tokens get a badge on the Arena leaderboard. Holders trade tokens with badges; creators who refuse to lock signal exactly that. The badge becomes table stakes for serious launches over time.See spec §38.5 and §38.8 for the strategic framing.

How to use it

The contracts shipped to Base Sepolia in PR #43; the creator console UI wrap is on its way as the Epic 1.13-web follow-up. Until then, lock from the contract directly on Sepolia:
# unlockUntil is a unix timestamp; the block must be strictly later
# than block.timestamp AND strictly later than any existing lock.
cast send $CREATOR_COMMITMENTS \
  'commit(address,uint256)' $TOKEN $UNLOCK_UNTIL \
  --rpc-url $BASE_SEPOLIA_RPC_URL \
  --private-key $CREATOR_KEY
You must call commit from the creator-of-record wallet — the address that originally launched the token. Auth is checked against CreatorRegistry.creatorOf(token), not adminOf. If you’ve handed admin to a multisig, the multisig cannot call commit; the lock is a personal commitment by the original launcher.To extend an existing lock, call commit again with a later timestamp. The contract refuses any value <= the existing unlock.To lock forever, pass type(uint256).max. The contract explicitly allows this; the gate will revert on every transfer from your address indefinitely.

How holders verify a lock

CreatorCommitments exposes two view functions any holder can read without permission:
function isLocked(address creator, address token) view returns (bool);
function unlockOf(address creator, address token) view returns (uint256);
isLocked returns true if and only if block.timestamp < unlockTimestamps[creator][token]. unlockOf returns the raw unix timestamp (zero if no lock has ever been recorded).The contract address lives in the deployment manifest under addresses.creatorCommitments.

Five things bag-lock does NOT do

These are the false-trust risks. The web UI must surface every one of them loudly — a holder who misunderstands the lock as broader than it is will feel betrayed when they encounter the gap.

1. Pre-commit transfers escape

If the creator transferred half their bag to a second wallet before calling commit, that second wallet is not subject to the lock. The gate is keyed off (creator-address, token). Anything that left the creator’s wallet before the commit lives outside the gate.The implication: a “creator locked X% of supply” badge must compute against the creator’s current balance at commit time, not the launch-time balance. Otherwise a creator who pre-distributed gets credit for a lock they didn’t actually take.

2. Buying more is fine; selling is not

Incoming transfers to the locked address still work. Fee revenue, tips, swaps from a different wallet into the locked address — all permitted. Only outgoing transfers from the locked address revert.This is intentional: a lock that prevented incoming credits would block creator-fee claims and trap the creator’s revenue. The lock is about not selling, not no activity.

3. The lock does not cover other wallets the creator controls

Only the address that called commit is gated. If the creator quietly transferred to a sibling wallet they also control before committing, they can dump from the sibling without restriction. Detecting “common controller” addresses is an off-chain heuristic problem (Arkham-style), not something the contract can do.The implication: surface the creator’s other on-chain activity (clusters, large transfers near commit time) so holders can form their own judgment. Don’t claim the lock covers more than the literal mapping says.

4. Lost keys = permanent lock

If the creator loses access to the wallet that called commit, the bag is permanently locked. The protocol cannot rescue it. This is by design — an escape hatch would be the exact same hatch a creator could use to renege on the commitment.The implication: creators must be told this before they commit. The “Lock my bag” flow surfaces an acknowledgement: “If you lose this wallet, your tokens stay locked forever. You cannot recover them.”

5. Pre-1.13 tokens (Sepolia legacy)

Tokens deployed before the Epic 1.13 FilterFactory redeploy do not consult the commitments contract. The gating code isn’t in their bytecode. A creator of a pre-1.13 Sepolia token who calls commit will see it succeed (the contract doesn’t know about the token’s bytecode), but the lock will not enforce — transfers from their address will still go through.The operational implication: until the Sepolia FilterFactory is redeployed and old tokens are wound down or migrated, bag-lock is not advertised for pre-1.13 tokens. The Sepolia README and the in-app badge logic explicitly exclude them.

Locks extend, never shorten

The contract enforces strict-> monotonicity:
  • Calling commit with a timestamp <= block.timestamp reverts with LockMustBeFuture.
  • Calling commit with a timestamp <= the existing unlock reverts with LockCannotShorten.
  • There is no unlock function. There is no cancel. There is no admin override. There is no pause.
This is the property that makes the lock credible. A function that could shorten the lock would be the same function a creator could use to renege. So the function does not exist.If a security issue is found post-deploy, the only remediation is to deploy a new contract instance. Locks recorded on the existing instance remain enforced for as long as the FilterToken contracts that reference it exist.

Audit constraints

Mainnet activation is gated on Epic 2.3. The audit specifically validates:
  • No way to shorten or cancel a lock. commit enforces strict-> monotonicity; no other state-mutating function exists on CreatorCommitments.
  • No admin override. The contract has no owner, no pause, no upgradeability, no escape hatch.
  • The transfer gate is consulted on every balance change (not just direct transfer). OZ v5’s _update hook is the single funnel — the override calls it on transferFrom, swap-routing, and burn paths too.
  • Auth uses creatorOf, not adminOf. Admin transfers do not carry the bag-lock right.
  • Reentrancy guard on commit. Defensive — no current external calls inside, but the guard is load-bearing if a future change adds one.
A loud failure mode caught in audit (lock-shortening, admin override, gate bypass) would be worse than not shipping the feature. That is why mainnet activation is gated.

Next

Creator console

Where the bag-lock UI will live once the Epic 1.13-web follow-up ships.

Launch a token

The launch flow that establishes the creator-of-record bag-lock keys off.

Risks

What can happen, what isn’t promised — including the limitations above.

The filter

The competitive cut bag-lock is designed to live alongside.