Skip to content

Repository files navigation

TICK — a countdown to 2100, one token per second

TICK is a fixed-supply SPL token on Solana. Its total supply is the number of seconds between launch and 2100-01-01T00:00:00Z — minted once, in a single transaction, with the mint authority revoked in that same transaction.

Those tokens are then given away for free, at 1 TICK per second, released in completed one-minute batches. Anyone may claim. There is no sale, no allowlist, no fee, no cooldown, and no per-claimant state.

Status: LIVE on Mainnet since 2026-08-12. The program is deployed and immutable — its upgrade authority is none and cannot be restored.

program 5b8oDRPP6iGMP4hLeip9nr5Wtsfejuwy6aqkk3Msh9hP
mint SuHS5YeFjHDX2a56HEktzikGZ1ACuUAfLgw3FKm2TxH
supply 2,315,907,000 TICK — mint and freeze authority both null
genesis 1786537800 (2026-08-12T12:30:00Z); first claim at genesis + 60

--final landed at block time 1786537214, 586 seconds before genesis, so no claim was possible while the program could still be rewritten. A stranger can check that from chain state alone: compare that transaction's block time against distributor.genesis_ts.


How it works

One on-chain program, tick_distributor, with three instructions:

Instruction Who When
initialize INIT_AUTHORITY, once per mint at launch
fund_reserve anyone (once) at launch
claim anyone for ever after

At launch a single transaction creates the mint, mints the entire supply, revokes the mint authority, and initializes the distributor. Then fund_reserve moves the whole supply into a vault owned by a program-derived address. From that moment the only way a token leaves the vault is claim, and the amount is pure clock arithmetic:

released = whole minutes elapsed since genesis × 60 TICK
payable  = released − already claimed

A claim takes the entire outstanding backlog. If two claims race, one takes the backlog and the other gets NothingToClaim — never a double payout.

The program is deployed to Mainnet and its upgrade authority has been revoked. Whatever it does is what it does for the next 74 years.

What nobody can do — including the author

The launch transaction has landed, so every line below is now a fact about Mainnet rather than an intention:

  • Mint more. The mint authority was revoked in that same transaction. Supply is fixed for ever.
  • Change the rules. The program is finalized; there is no upgrade path.
  • Take the tokens. No withdraw path exists. Nothing leaves the vault except through claim.
  • Get special treatment. Over the TICK distributor, INIT_AUTHORITY has exactly the power any other address has: none. It cannot mint, pause, withdraw, upgrade, or re-initialize it — initialize uses Anchor init on a PDA keyed by the mint, so it can never run twice for the same mint.
  • Stop it. No pause, no admin, no crank. Accrual is the chain's clock.

What the author will still be able to do

One thing, and it is worth stating plainly. Distributors are keyed per mint (seeds = [b"distributor", tick_mint]), so INIT_AUTHORITY — and only INIT_AUTHORITY — can call initialize again for a different mint, creating another distributor under the same immutable program id, at any time, for ever.

Such a distributor could never reach TICK's vault or supply: its state, vault authority and vault are all derived from its own mint, and funds cannot cross between distributors. But it would run identical code at an identical program id, and could be presented as though it were TICK.

So the program id is not what identifies TICK. The mint address is. Verify the mint first; the distributor, vault authority, vault and metadata accounts are all derived from it.

The launch mint is SuHS5YeFjHDX2a56HEktzikGZ1ACuUAfLgw3FKm2TxH. Any token whose mint is not that address is not TICK, whatever it is called and whatever program it runs. Two earlier launch attempts were aborted before funding and left inert mints on Mainnet (ACqXdjJm…, jiT2CseU…); they can never emit a token — their distributors were never funded, and claim is impossible until fund_reserve latches — but an explorer will show them, so they are named here rather than left to be discovered.

Parameters

Decimals 9
Batch 60 seconds
End 2100-01-01T00:00:00Z (Unix 4102444800)
Supply END_TIMESTAMP − genesis whole TICK, fixed at launch
Emission 1 TICK/second, released per completed minute

Documentation

Start at docs/README.md.

If prose anywhere disagrees with programs/tick_distributor/src, the source wins.

Build and verify

Toolchain is pinned deliberately: Anchor 1.1.2, Agave/Solana 3.1.10, platform-tools v1.52, host Rust 1.97.1. The last of those only builds the IDL generator — platform-tools is what compiles the bytecode, which is why Anchor.toml pins solana_version as well.

pnpm install
anchor build
cargo test --workspace --all-targets
pnpm test

Two of the published hashes are the same bytes — the third is not

The frozen artifact is target/deploy/tick_distributor.so, 214,088 bytes, built from commit f8eaea5 for program id 5b8oDRPP6iGMP4hLeip9nr5Wtsfejuwy6aqkk3Msh9hP.

Measured by Value
shasum -a 256 / sha256sum on the file 568f06ed057a1c29b020cf4f7fcf9aa50b90a1a64edf8f5b9fdeb80e969fdc6d
solana-verify (get-executable-hash, get-program-hash) f16e47501ce77a61d217792918a19b15c77b7188a8f5f70fdf20629924ffce4c
solana-verify build in the pinned container — a rebuild, and it does not reproduce this artifact 5d470ad370c3a08dde93ad61dab3832e424772ebea82bd276bdc2bf3d920f920
shasum -a 256 on the IDL target/idl/tick_distributor.json 4b616622d184ca0ad86be8286ff2787c06046b2d0c8da4babcd6b9c07303af5a

Those first two figures are one artifact measured two ways, not two artifacts. solana-verify strips trailing zero bytes before hashing; this file ends in 15 of them, so it hashes the leading 214,073 bytes and reports f16e4750…. A plain sha256sum hashes all 214,088 and reports 568f06ed…. Neither is wrong, and a difference between them is not a failed reproduction. The third figure, unlike the first two, is a different binary: get-executable-hash and get-program-hash only hash bytes that already exist, while build re-compiles the source, and the container's compiler does not emit the deployed bytes — see "Reproducing it" below. Compare like with like:

shasum -a 256 target/deploy/tick_distributor.so                      # 568f06ed…
solana-verify get-executable-hash target/deploy/tick_distributor.so  # f16e4750…

# and the equivalence itself, if you want to see it:
python3 -c "import hashlib,sys; d=open(sys.argv[1],'rb').read(); \
print(hashlib.sha256(d).hexdigest()); print(hashlib.sha256(d.rstrip(b'\0')).hexdigest())" \
  target/deploy/tick_distributor.so

Reproducing it

Native rebuild against the pinned local toolchain:

scripts/verify-build.sh                  # rebuild, compare .so and IDL hashes
scripts/verify-build.sh --rpc <endpoint> # ...and compare against deployed bytes

The --rpc step identifies the cluster by asking it for its genesis hash rather than reading its hostname, and prints what it found; add --expect-cluster mainnet-beta to turn that into an assertion. It reads bytes and signs nothing, so it is safe to point at Mainnet.

Container rebuild, which needs nothing from this machine except Docker — and which does not reproduce the deployed artifact:

solana-verify build --library-name tick_distributor \
  --base-image solanafoundation/solana-verifiable-build:3.1.10

Expect 5d470ad370c3a08dde93ad61dab3832e424772ebea82bd276bdc2bf3d920f920 — a different binary. An earlier version of this README said to expect f16e4750… here; that was wrong. The cargo build-sbf this container runs and the anchor build that produced the deployed artifact do not emit the same bytes, so the container is not a route to reproducing this program. The route that does reproduce it is scripts/verify-build.sh above — the native rebuild against the pinned toolchain, which yields 568f06ed… — subject to the caveat in the next section: that rebuild has so far been demonstrated only on the author's machine.

The --base-image pin is required — do not drop it. Left to itself, solana-verify infers a base image from the dependency tree and picks 3.0.1, whose Cargo 1.84 cannot parse the edition2024 manifest of block-buffer 0.12.1. It then hard-fails with "failed to cargo build". That is a stale inference, not a broken project.

Run it from a clean clone: solana-verify searches the working tree for a program to build, and a target/ directory left over from local testing can contain source trees with different declare_id! values. The image is linux/amd64; on an Apple-silicon host it needs an emulating Docker runtime (this was measured under Colima started with --vm-type vz --vz-rosetta).

How far that reproduction goes, exactly

The artifact reproduces natively on the author's host: nine builds across eight varied environment dimensions (paths, cleared CARGO_HOME, target and temp directories, locale, timezone, umask) all produced the same hash. It does not reproduce in the pinned public container. An earlier version of this section claimed that it did; that claim was wrong. solana-verify build compiles with the container's cargo build-sbf, the deployed artifact came from anchor build, and the two do not emit the same bytes: the container yields 5d470ad3… (measured 2026-08-11 on a clean clone), and OtterSec's remote verifier — infrastructure this project does not control — produced the same 5d470ad3…. The container build is reproducible across environments; what it reproduces is a different binary.

What the native reproduction is not: independent. Every build that has matched the deployed program ran on the author's machine, and no third party has reproduced the hash. The one third-party build on record — the remote verifier's — used the container path and got 5d470ad3…. Until someone else assembles the pinned toolchain, runs scripts/verify-build.sh and reports 568f06ed…, the claim rests on one operator's word — and checking it now costs a stranger the full toolchain setup rather than one Docker pull, which is a real regression in how cheaply this program can be checked.

An on-chain Verified Build badge (solana-verify verify-from-repo) rides on that same container build, so it is closed to this program: the registry's remote verifier rebuilds in the container, gets 5d470ad3…, and reports a mismatch. Do not expect a verified-build badge for this program. Its absence is this section, not evidence about the deployed bytes — read a build you can rerun yourself.

On a fresh clone anchor build prints a "Program ID mismatch" warning and suggests anchor keys sync. Do not run it — it rewrites declare_id! to a randomly generated local key and invalidates the published hash. The build is already correct. See docs/operations/DEVELOPMENT.md.

Local end-to-end demo on a throwaway validator:

pnpm distributor:demo:local

Verifying a live deployment

Start from the mint address. Every other address is derivable from it, so you never have to trust a record in this repository — and the mint is the only thing that tells TICK apart from another distributor running the same code at the same program id. See docs/operations/DEVNET.md.

A rehearsal faucet is live on Devnet: mint FbzcDjaHYhGqVi9vHWpzHQfQUxiedcFYJKR7zyWZQGZ3, program 6bBr6ggWg8CY9HAFWwyvehaUpMnBsoJ6WLcwBHfVaSte. These check it against the chain and derive every address independently:

pnpm distributor:status:devnet:test
pnpm verify:supply:devnet:test

verify:supply re-derives the distributor PDA, vault authority and vault from the mint, and asserts the supply is exactly the whole seconds from the recorded genesis to 2100-01-01T00:00:00Z. It warns while the rehearsal program remains upgradeable; pass --require-immutable to treat that as a failure, which is what you would use against the Mainnet launch.

The un-suffixed pnpm distributor:status:devnet / pnpm verify:supply:devnet are pinned to the frozen launch id 5b8oDRPP…, which is deployed on Mainnet and nowhere else — its Devnet rehearsal copy was closed on 2026-07-27. Run against Devnet they still fail closed, by design; point them at Mainnet to check the live launch.

If you check that address on Devnet yourself, expect to find an account. solana program close leaves the program stub behind — it still reports executable: true and is still owned by the BPF upgradeable loader — while deleting the programdata account that holds the bytecode. Verified 2026-07-30: programdata G9uKL9kaQGYeb3xFf1v4ssxZtUymGWRVCGQk2F7k6ud8 is absent, so the program cannot be invoked. An executable flag is not evidence that a program exists; resolve the programdata account, which is what verify-build.sh reads.

Repository layout

programs/tick_distributor/   the on-chain program — the only thing that is trustless
scripts/                     launch ceremony, verification, and localnet harnesses
tests/                       offline TypeScript tests
docs/                        specifications, operations, audit record
docs/archive/                superseded designs — never implementation guidance

A note on what this is

TICK does nothing except count. It has no yield, no governance, no utility, no treasury, and no roadmap of features. Its supply is a countdown and its distribution is a clock. That is the whole idea.

Please read docs/public/RISK_DISCLOSURES.md before forming any expectation about it.

Licence

Apache-2.0.

About

Immutable Solana token distributed freely at one TICK per second through a permissionless, fixed-supply batch faucet.

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages