01Abstract#
A token's identity on an EVM chain lives in its contract: a name, a symbol, and, for tokens that have one, a metadata URI pointing at an image and description. Almost every ERC-20 freezes those values in the constructor. STS-1 does the opposite. It specifies tokens that are born shiftable, the four ways a shift can be requested, the single transaction that performs it, and the guarantees that hold across every rewrite.
The result is a token that can tell a story over time. It can be one thing at launch and another at graduation, change on a creator's command, be voted into its next form by its holders, or continuously become whatever the market is watching. Holders never move, never migrate, never claim. The token they hold simply becomes something new.
02Motivation#
Memecoins are narratives, and narratives move faster than a fixed ticker. Today a project that wants a new identity has two options: deploy a new token and ask everyone to move, or live with the old one. Both lose. Liquidity fragments, holders are left behind, and the history that made the token valuable is gone.
Nothing in the EVM prevents a contract from exposing name() and symbol() as mutable storage. What was missing is a standard: who may rewrite them, when, how it is authorized, what it may never touch, and how anyone watching can follow along. STS-1 is that standard, deployed on Robinhood Chain.
03Terminology#
The key words MUST, MUST NOT, SHOULD and MAY are to be read as described in RFC 2119.
04The shiftable token#
Supply and address#
A shiftable token is deployed by the launchpad with CREATE2, so its address is known before the launch transaction lands. The whole supply (1,000,000,000 tokens, 18 decimals) is minted once, to the launchpad, which sells 800,000,000 on the curve and keeps 200,000,000 for the graduation pool. There is no mint function. Supply, decimals, creator and address MUST NOT change.
Mutable identity#
name, symbol and tokenURI are storage variables, not constants. The contract exposes one mutator, shift(name, symbol, uri, by), callable only by the launchpad. Transfers, approvals and balances are standard ERC-20 and MUST behave identically before and after a shift.
contract ShiftToken {
string public name; // mutable
string public symbol; // mutable
string public tokenURI; // mutable
uint8 public constant decimals = 18;
uint256 public immutable totalSupply;
address public immutable launchpad; // update authority
address public immutable creator;
uint256 public generation;
event Shift(uint256 indexed generation, string name, string symbol, string uri, bytes32 by);
function shift(string calldata name_, string calldata symbol_, string calldata uri_, bytes32 by) external;
}Identity#
Wallets and explorers that read name() and symbol() see the new identity on the next refresh. Indexers that cache names SHOULD subscribe to the Shift event. The image and description are served from the URI, which the launchpad keeps pointing at a document that always reflects the current generation.
Off-chain document#
The tokenURI resolves to a JSON document. Its shape is stable across shifts; only the values change.
{
"name": "Shapeshifter",
"symbol": "SHIFT",
"image": "https://shift-spl.com/api/img/…",
"description": "What it is, and what it might become.",
"token": "0x…",
"createdOn": "https://shift-spl.com",
"twitter": "https://x.com/…",
"website": "https://…",
"attributes": [
{ "trait_type": "Standard", "value": "STS-1" },
{ "trait_type": "Shifts", "value": 3 },
{ "trait_type": "Mode", "value": "scheduled" }
]
}05Shifts#
The transaction#
Every shift is one call to ShiftLaunchpad.shift(token, name, symbol, uri, by) from the authority key. The launchpad forwards it to the token, which increments its generation and emits Shift; the launchpad emits Shifted with the same data so a single contract can be watched for every token. The by field is a 32-byte tag naming the source: creator, schedule, vote or keeper.
ShiftLaunchpad.shift(token, name, symbol, uri, by)
└─ ShiftToken.shift(name, symbol, uri, by) // msg.sender == launchpad
generation += 1
name, symbol, tokenURI ← new identity
emit Shift(generation, name, symbol, uri, by)
emit Shifted(token, generation, name, symbol, uri, by)Before the transaction is built, the new image (if any) and the new metadata document are stored, so the URI is live the moment the shift lands.
Invariants#
Generations#
The launch identity is generation 0. Each shift produces generation n+1. The token page and the engine log list every generation with the transaction that produced it, so the full history of a token is reconstructible from chain data alone: scan Shifted events on the launchpad.
06Shift modes#
The mode is chosen at launch and recorded on the pool. It decides who may ask for a shift.
Manual#
The creator asks, whenever they like, by signing a message with their wallet. No gas is spent by the creator: the launchpad verifies the signature and submits the shift. Message format: shift:<token>:<generation+1>:<name>:<symbol>:<timestamp>. The timestamp MUST be within five minutes and the generation MUST match the current one plus one, so a captured signature cannot be replayed.
Scheduled#
Up to four identities are planned at launch, each with a time. The keeper applies them in order as their time arrives, then stops. Planned identities are visible on the token page before they take effect.
Auto · trending#
Every keeper interval (30 minutes), the token takes the name, ticker and image of a coin that is trending right now. The trending source is a public market feed; the keeper picks the top entry that differs from the current identity. Nobody signs; the launchpad does the rewrite.
Holder vote#
Rounds last 60 minutes. During a round, holders propose identities and vote by signing messages (one proposal and one vote per wallet per round). When the round closes, the keeper weighs each vote by the voter's token balance at that moment and applies the winner. A round with no proposals changes nothing.
07Creator authorization#
Manual shifts, proposals and votes are authorized with EIP-191 signed messages, never with transactions, so the people asking pay no gas. The launchpad MUST verify that the recovered signer is the creator (manual) or holds a non-zero balance (vote), that the timestamp is fresh, and that the message binds the token, the round or generation, and the exact identity requested.
08The keeper#
The keeper runs every five minutes. On each run it applies due schedules, closes finished vote rounds, mirrors trending for auto tokens whose interval has elapsed, and migrates graduated curves. Runs are serialized with a time-boxed lock so two keepers never shift the same token twice. Every run is logged with what it did.
09Concurrency and safety#
Shifts are idempotent per generation: the signed message for a manual shift names the generation it expects, and the keeper reads the current generation before acting. If two sources race, the second one fails its check and nothing is written twice. The authority key only ever calls shift and migrate; it cannot mint, freeze, or move holder balances.
10Launch lifecycle#
11Market structure#
The curve holds virtual reserves of 1.2 ETH and 1,073,000,000 tokens at launch (an initial market cap of about 1.1 ETH). Buying moves ETH in and tokens out along x·y = k; selling does the reverse. The curve completes when 800,000,000 tokens have left it, which raises about 3.5 ETH. At that point trading on the curve stops and the pool graduates to Uniswap v4 on Robinhood Chain, where the token trades freely with the rest of the chain's liquidity.
virtualEth = 1.2 ETH + ethRaised
virtualTokens = 1,073,000,000 − tokensSold
tokensOut = virtualTokens − k / (virtualEth + ethIn·(1 − fee))
graduation : tokensSold == 800,000,000 (≈ 3.5 ETH raised)12Trust model#
Holders trust the launchpad with exactly one thing: the identity. The launchpad can rename a token; it cannot take it. Balances, supply and the address are enforced by the token contract, and the authority key has no path to them. The curve contract holds ETH only until graduation, and the code that moves it out is the migration into the public pool. Everything the launchpad does is an on-chain event that anyone can audit.
13Integrating#
Detecting STS-1 tokens#
An STS-1 token is any contract deployed by the launchpad: check ShiftLaunchpad.pools(token).creator != 0, or scan Launched events. The token itself reports launchpad() and generation().
Indexing shifts#
Subscribe to Shifted(token, generation, name, symbol, uri, by) on the launchpad to follow every rewrite on the platform, or to Shift on a single token. Refresh cached names when you see one.
HTTP API#
14FAQ#
Do I need to do anything when a token I hold shifts?+
No. Same token, same balance, same address. Your wallet shows the new name and image the next time it refreshes the token.
Can the launchpad take my tokens?+
No. The launchpad can only call shift() on the token, which changes name, symbol and tokenURI. Transfers and balances are standard ERC-20 code with no admin path.
Does a shift cost the creator anything?+
No. The creator signs a message; the launchpad pays the gas for the on-chain rewrite.
What happens after graduation?+
Trading moves to a Uniswap v4 pool on Robinhood Chain seeded with the raised ETH and the remaining 200M tokens. The token keeps shifting according to its mode.
Which chain is this on?+
Robinhood Chain (chain id 4663), an Arbitrum Orbit L2. Gas is paid in ETH.
15Versioning#
This document describes STS-1 revision 2026-10-24. Changes that alter the invariants in section 05 would be a new major version (STS-2). Additions that keep them, such as new shift modes or new curve parameters, are revisions of STS-1 and are dated.