Skip to content

Project README

OhShii Launcher is a token-launch and DAO-bootstrap platform on the Internet Computer. It lets projects create ICRC tokens, run LGE (Liquidity Generation Event) campaigns with bonding-curve pricing, and automatically create a liquidity pool on ICPSwap. Every LGE gets its own governance canister from day one: treasury, proposals, and voting are powered by the campaign token from the start. The DAO becomes autonomous at completion (the campaign sells out its curve and is finalized) — the backend creates and funds the pool, transfers the liquidity position to the governance canister, and OhShii steps back (the backend and ohshii_governance are removed from the controllers of the governance canister and of the campaign’s token ledger, index, and archives — the DAO’s own governance canister is guaranteed to control them from that moment).

The platform offers three distinct ways to put a token on-chain:

  • Create a token (standalone): Deploy an ICRC-1/2/3 token ledger (with an index canister by default, or index-only) for a fixed platform fee (currently 5 ICP) plus the on-chain cycles. A standalone token is not a DAO by default — use it for any dapp utility, and (if you want) later turn it into a governance token via Import a DAO below. See Beyond LGEs.
  • Run an LGE: Launch a token through a fundraising event on a SigmoidV2 bonding curve with a fixed 1B supply (700M sold on the curve, 200M + the pool ICP seed the ICPSwap pool, 100M to the campaign DAO treasury). The creator chooses the total ICP raised500 ICP default, up to 5000 ICP in steps of 500 (k = target/500); the curve keeps the same shape and sells the same 700M tokens, only the prices (and so the raise, the ~90% pool ICP = 450·k, and the sponsor fees) scale by k, with the end-of-LGE-price : ICPSwap-listing ratio held invariant. Every LGE automatically gets its own governance canister — the token is a governance token from day one. The LGE creation fee is set by OhShii governance (current default ≈4 ICP treasury fee + a pool-creation reserve sized live from ICPSwap + optional banner fee + on-chain cycles + the creator’s own first purchase along the curve). Each LGE also carries a creator-configured regional participation eligibility list — the countries excluded from participating (ISO 3166-1 codes; a suggested starting list is provided but fully customizable, and a DAO proposal can replace a campaign’s list later). Participants confirm their eligibility via a frontend self-declaration against the campaign’s current list; see docs/WORKFLOWS.md.
  • Import a DAO (govern an existing token): Turn an already-deployed ICRC token (8 decimals, ICRC-1 and ICRC-2) into a governance token without an LGE — whether you minted it standalone on OhShii or deployed it elsewhere. The launcher deploys only a fresh sons_governance canister for it (no new ledger/index/pool, no fundraising, no bonding curve), links its existing ICPSwap pool, and reads the token name/symbol from the ledger metadata. Fixed 20 ICP + cycles for one governance canister; the importer keeps control of their token (and can hand the ledger/index/pool — and the dapp the token powers — to the DAO whenever they choose). The importer also chooses at creation whether governance participation requires identity verification (World ID / DecideID): checked by default, but deselectable for an imported DAO — when off, voting/proposals/follow are gated by holding vesting-locked tokens (anti-Sybil) instead. LGE campaigns are always identity-gated. The setting is fixed at creation and only a Critical DAO vote can change it afterwards.

These three paths share a common set of core mechanics (not separate entry points):

  • DAO bootstrap: The backend creates an empty governance canister per campaign, deploys the campaign’s ledger and index with that canister as a controller, and installs the SONS governance WASM. That sons_governance holds the campaign’s treasury, runs proposals, and lets token holders vote with the LGE token (quadratic voting on locked tokens). At completion the backend removes itself and ohshii_governance from the controllers of the governance canister and of the token ledger/index/archives (the governance canister is guaranteed to remain a controller of each), so the DAO is fully autonomous — including full custody of its own token canisters.
  • Refund on failure: If a campaign fails (expires without selling out, or is marked Failed), contributors can request a refund within 7 days of expiry: contributors recover ~95% of contributed ICP (the ~90% net plus the held 5% referral band, tier-independent), creators ~70%, and Guest-tier contributors also get their 30,000 OHSHII guest fee back (snapshotted, idempotent). Refunds are paid on-chain from the campaign’s held sub-accounts — never the treasury. After the 7-day window, any un-refunded residual is swept on-chain to the OhShii platform treasury (campaign sub-account) and to OHSHII (referral sub-account). See docs/WORKFLOWS.md (Campaign failure and refunds).
  • Campaign states: CampaignState has 5 variants: Active (LGE in progress), Finalizing (target reached, finalization underway), Completed (terminal, finalization succeeded), Failed (did not sell out by the deadline), and Frozen (recoverable failure during finalization — finalization can be retried via the authorized-caller path or the governance-set guardian).
  • Two-tier governance: ONS (OHSHII Governance) governs the OhShii ecosystem — launcher canisters, the OhShii Locker token list and lock operations, and the OHSHII token. SONS (LGE Governance) is one DAO per campaign, governing that campaign’s treasury, ledger/index/governance WASM, asset (frontend) canister, and pool. Both ONS and SONS can additionally upgrade external dapps they are a controller of — backend code (UpgradeCanister / UpgradeCanisterBatch / UpgradeDappBatch) and frontend assets (UpgradeAssetCanister). ONS does not govern SONS: ONS (and the backend) are only temporary controllers of a campaign during the LGE and are removed at completion, so ONS can act on a campaign only before it becomes autonomous.
  • OhShii Locker: The launcher integrates with OhShii Locker (separate app): existing locker tokens and lock operations are managed via ONS proposals (new token listings are currently disabled, and OHSHII can never be removed); the backend can create locks on behalf of users. SONS vesting locks live in the campaign’s sons_governance canister and are surfaced/managed through the Locker frontend — the Locker canister never custodies them.

For canister layout, governance scope, and workflows, see the docs below.


Besides launching LGEs, the platform exposes several standalone functions:

  • Standalone token deploy — create an ICRC-1/2/3 ledger with an index canister (default) or ledger-only; 5 ICP platform fee + on-chain cycles (≈4T with index, ≈2T without — every canister the platform deploys is funded with 2T). You choose name, symbol, decimals, transfer fee, supply, subnet, minting account, and (optionally) extra controllers. The token is deployed creator-controlled and non-custody: your principal is a persistent controller, together with any controllers you explicitly choose — and nothing else. The OhShii backend is never a persistent controller (it is rejected even on request): it holds control only transiently during the install and removes itself as the final step of the deployment, so the platform keeps no control over the ledger. The CycleOps and NNS Root cycles-monitoring canisters are optional opt-ins, not defaults (a controller has full control of a canister, so granting it to a third party is always an explicit choice). The token name/symbol must not collide with a token already created on the platform.
  • Standalone token updates (creator-only) — from the Mint Token page (“My Minted Tokens”) the creator can update the token name, symbol and logo, add/remove controllers (max 9 persistent controllers; one slot stays reserved for updates) — of the token and of its index canister (index controller changes are a single creator-signed settings call, no platform involvement) — and, with extreme caution, change the transfer fee (a breaking-change lever for dapps/locks/DEX integrations that cache the fee; bounded to < 1% of supply and gated by an explicit risk acknowledgement). The first update is available immediately after minting; after each update a 24-hour per-token cooldown applies, and each token has a lifetime allowance of 5 creator updates through the platform tool (only applied changes count; past it, changes go through your own controller access — the ledger remains fully yours). The backend applies the changes through an official ICRC-1 ledger upgrade after you grant it temporary control with an explicit, consent-gated signature; it removes itself at the end of the same call on every exit path (errors included) and reports a verified removal state — the creator’s controllership is always preserved in the same atomic settings change, so the token can never be left without its creator in control (the UI additionally verifies the result with a certified read and never claims an unverified removal). Decimals, minting account and supply are permanent — the ledger upgrade interface cannot change them. Tokens minted before this feature have no creator controller and remain fully immutable. A minted token can later become a DAO via Import a DAO (mint with 8 decimals if you want that path), optionally adding the DAO’s governance canister as a controller. Full details: docs/STANDALONE_TOKENS.md.
  • Index-only deploy — attach a transaction-history index canister to an existing ledger that lacks one (e.g. a token brought in as an Imported DAO); 5 ICP + ≈2T cycles.
  • Cycles top-up — top up any canister with cycles: pay ICP (converted via the Cycle Minting Canister) or withdraw from your own Cycles Ledger, with a 2% fee routed to the OhShii treasury; a discounted “$1 per 1 TC” mode is offered while the operator reserve is funded.
  • Sponsor / referral code — register a referral code (free for a generated code, or 3 ICP for a custom 6-character code); the reward is a share of a capped referral band (≤5% of the curve, ≈25 ICP), paid only on a successful LGE and claimed from the campaign’s own SONS DAO (the earned Σtier is transferred there; the unearned remainder → OHSHII treasury). The per-sponsor share is governed by Voting Power and active-voter status.

Ecosystem tools (utilities, not DAO-governed)

Section titled “Ecosystem tools (utilities, not DAO-governed)”

OhShii also ships ecosystem tools — analytics and utilities, not products whose parameters a DAO votes on. They are served by the same launcher frontend canister, routed by subdomain (or ?app=), and share one Internet Identity principal (see Internet Identity).

  • OhShii Explorer (explorer.ohshii.io) — scan any ICRC token on-chain (holders, transactions, balances, a holder-graph BubbleMap) and analyze any wallet (balances, counterparties, P&L).
  • OhShii Atlas (atlas.ohshii.io) — an ICP-wide token map (bubble size = market cap, color = price move) aggregating live ICPSwap + PartyHats data, with per-token detail panels and charts.
  • OhShii Quests (quests.ohshii.io) — a separate learn-to-earn / trivia-launchpad dApp (its own canisters) where OHSHII buys quiz tickets.
  • Cross-Chain Gateway (bridge.ohshii.io) — the Menese Protocol SOL↔ICP swap UI (see Cross-Chain Swaps).

Most governance parameters and several economic parameters are chosen by the DAO (ONS, via proposals) within hardcoded bounds. The values below are the current defaults.

DAO-votable — set by ONS proposals (set_voting_parameters for voting params, admin_set_ico_fee for the treasury + banner LGE fees, admin_set_passcode_price on pool_manager for the ICPSwap pool passcode price, dedicated setters for the proposal/rejection fees):

  • LGE creation fee — treasury fee ≈4 ICP + a pool-creation reserve that tracks the ICPSwap passcode price (DAO-set via the pool_manager “Set Pool Passcode Price” proposal; creation is blocked if it falls below ICPSwap’s live price, and the platform pays only what ICPSwap actually charges) + optional 3 ICP banner.
  • Voting thresholds — Normal: 250,000 VP quorum + 15 voters, simple majority. Critical: 350,000 VP + 20 voters + ≥65% (early close at 450,000 VP + 30 voters + ≥75%). Guardian veto-override: 700,000 VP + 50 voters + ≥80%.
  • Voting windows — Normal 3 days, Critical 7 days, guardian-minimum 1 day.
  • Voting Power — quadratic (√tokens × lock-months), capped at 36,000 per user, minimum lock 1.5 months (45 days); 10,000 VP needed to create a proposal.
  • Per-user LGE purchase tiers — Guest 1M (unverified) · Human 4M (verified) · Fish 12M (≥2,000 VP) · Shark 18M (≥10,000 VP) · Whale 24M (≥30,000 VP); the tiers above Human also require active-voter status.
  • Fees in OHSHII — Guest fee 30,000 · proposal creation fee 30,000 · proposal rejection cost 25,000.

Hardcoded — changeable only by a canister upgrade (which is itself a DAO proposal):

  • The SigmoidV2 bonding curve (700M sale; creator-chosen raise 500 → 5000 ICP in steps of 500, i.e. k = target/500; end-of-LGE price 0.00000133·k, ICPSwap listing 0.00000225·k — ~90% = 450·k ICP seed the pool, the remaining ~10% cover pool creation + fees; at the 500-ICP default the curve runs 0.00000010 → 0.00000133 ICP/token) and the fixed 1,000,000,000 total supply.
  • Standalone token / index-only platform fees (5 ICP each), the imported-DAO fee (20 ICP), and the sponsor custom-code fee (3 ICP).

Terminal window
git clone <repo-url> && cd dev-ohshii-launcher
npm ci # install deps (lifecycle scripts are blocked by .npmrc)
npm rebuild esbuild fsevents secp256k1 # rebuild required native binaries
npm run build # vite build — works normally
Terminal window
cargo check --workspace # host build — no extra setup needed

The Rust toolchain is pinned and self-provisioning. rust-toolchain.toml at the repo root declares the exact channel and the wasm32-unknown-unknown target, so rustup installs both the first time you run any cargo command in this directory. You do not need to pick a version or add the target by hand, and you should not: CI, the Docker pipeline and every contributor resolve to the same compiler revision on purpose, which is what makes a build that passes locally also pass in production. The file carries the reasoning for the pin — including a wasm-bindgen constraint that breaks the canister build if it is lifted — and is the place to read before changing it.

Building the canister WASMs, running the local IC world, or regenerating Candid declarations needs a few more tools (ic-wasm, didc, a PocketIC server). They are listed, with what each one is for and what breaks without it, in docs/LOCAL_TEST_ENVIRONMENT.md → Prerequisites.

Why npm rebuild? The project ships with ignore-scripts=true in .npmrc to block postinstall-based supply-chain attacks. This stops all dependency lifecycle scripts, including the ones that esbuild, fsevents, and secp256k1 use to download their platform-specific binaries. The rebuild step runs only those trusted packages. You only need to do this after npm ci or npm install — regular npm run build, npm run dev, and dfx deploy work as usual.


Canister map, launcher vs locker, and OHSHII Governance (ONS) vs LGE Governance (SONS):


Two governance paths: ONS (single ohshii_governance, OHSHII token with quadratic voting on locked tokens) and SONS (one sons_governance per LGE, campaign token). Voting Power is quadratic on locked tokens; lock points are a separate score used by third-party dapps for utility/gating, not for voting.

In SONS CreateProposalForm, controller operations are safety-routed automatically: AddController / RemoveController become CriticalGovernanceOperation when target_canister_id matches the selected governance canister (self-target). For self-target snapshot workflows (CreateSnapshot / RestoreSnapshot), execution is delegated to ohshii_launcher_backend as orchestrator because a canister cannot stop/snapshot/start itself.

  • docs/GOVERNANCE.md — When to use ONS vs SONS, full proposal and method lists.
  • docs/GOVERNANCE_VOTING.md — How a proposal is voted and resolved: voting power, the Normal/Critical two-axis model, guardian veto + override, and the identity-verification gate. A community veto-override round additionally requires each voter to complete a fresh World ID re-attestation bound to that specific override before their vote counts: the human attests their own personhood directly on ohshii_governance, and a per-override nullifier enforces one human / one ballot regardless of how many wallets or how much voting power they control. Normal votes are unaffected.
  • docs/LIQUID_DEMOCRACY.md — Vote delegation on ONS: follow / unfollow, accept-followers toggle, dismiss-follower, the snapshot-based cascade model, four-layer rate limits, the cross-canister batched VP fetch contract with the locker, full event log reference, and end-user FAQ.
  • docs/WORKFLOWS.md — Create LGE, create token, vote, create/execute proposal, backend WASM vs frontend upgrade, self-snapshot flows, LGE finalization (success and failure), campaign failure and refunds.
  • docs/WORLD_ID_VERIFICATION.md — World ID voter verification: end-to-end flow, privacy model, three-state config (not_configured / optional / required), threshold-ECDSA RP signatures, rate limits, governance controls and operator checklist. The gate speaks World ID 4.0: the canister submits proofs to World’s /api/v4/verify endpoint, which accepts both 4.0 and legacy 3.0 proofs natively, so holders of either credential generation can verify; relying-party requests are signed on-canister via IC threshold ECDSA (the canister is its own relying-party signer, with no off-canister key custody). A governed request-preset toggle (WorldIdConfig.request_preset, default v4-capable) controls only what the IDKit widget requests — never what the canister accepts — and is settable by an admin during the pre-DAO transition phase and by ONS proposal once governance is decentralized.
  • docs/DECIDEID_VERIFICATION.md — DecideID (DecideAI Proof-of-Personhood) voter verification: alternative second method, on-canister JWT-VP verification via Internet Identity (no HTTPS outcalls), independent 3-state config from World ID. The vote gate fires on either method’s enabled flag; verification by either method satisfies the gate (universal is_verified widens to OR).

The launcher integrates with Menese Protocol as a partner dApp for cross-chain SOL↔ICP swaps. OhShii is an allowlisted partner on Menese’s Sovereign Send: free address derivation for vouched users (saving ~45B cycles per getMyAddress call) and a 20% share of the 0.1% Sovereign Send protocol fee on sendSol / signSend.

  • docs/MENESE_INTEGRATION.md — Full integration guide: partner status, conversion flows (SOL↔ICP, mSOL↔SOL), fee structure, Sovereign Send API, implementation status.

Reproducibility is not only “can I build it” — it is “can I check that the canisters running on mainnet are built from this source”. That check is read-only and needs no identity, no controller rights and no permission from anyone:

Terminal window
./scripts/verify-hash.sh # every canister, both environments
./scripts/verify-hash.sh ic # production only

It reads each canister’s installed module hash from the IC and compares it against Deploy/WASM_HASHES.txt, which records the hash of every artefact together with the commit it was built from. A hash file produced from a working tree that had uncommitted changes says so in its own header, in those words — a build nobody else can reproduce is labelled as one rather than presented as an attestation.

⚠ Read the script’s limits banner before drawing a conclusion from a green run. It states what the comparison does and does not establish; the tool is deliberate about not overclaiming, and the banner is the part that says so.

  • Local test environment (reproducible by anyone): docs/LOCAL_TEST_ENVIRONMENT.md — one command (./test-env/start.sh) boots a full local IC world (PocketIC: real ICP ledger/CMC/NNS/II + ICPSwap V3 + launcher & locker canisters at mainnet ids) with both frontends; ./test-env/stop.sh stops it and saves state. Includes faucet, test-only admin promotion and test-only World ID / DecideID verification. Full technical reference: test-env/README.md.
  • Automated test suites (what is covered, and what is not): docs/TESTING.md — the end-to-end suites that run against that local world: a per-surface inventory of all suite files with the commands that derive the totals rather than a hand-written count, which cases are opt-in (--ignored) and why, and an explicit statement of what is still being implemented and what cannot be proven locally at all.
  • Deploy and verify: Deploy/DOCKER_DEPLOY_GUIDE.md, Deploy/VOTER_VERIFICATION_GUIDE.md
  • Governance canister build: Deploy/GOVERNANCE_CANISTER_BUILD.md
  • Candid and types: Declarations in src/declarations/. Types flow via canister-types.js and domain.d.ts.
    • Canisters in dfx.json: after changing any .did, run dfx generate --network ic.
    • sons_governance (dynamic, not in dfx.json): regenerate with didc.
    • Frontend (asset canister): like ohshii-locker, declaration generation (npm run generate:did, which runs didc) does not regenerate it: ohshii_launcher_frontend has declarations: { "output": "src/declarations/.dfx_skip_ohshii_launcher_frontend", "bindings": [] } so declarations are skipped. Canonical .did is src/frontend/ohshii_launcher_frontend.did. To (re)generate frontend declarations from it, run ./Deploy/generate-frontend-declarations.sh.

PathPurpose
src/backend/ohshii_launcher_backend (LGE/token/imported-DAO creation, index/cycles/relaunch utilities, snapshot orchestrator)
src/storage/dao_storage
src/pool_manager/pool_manager
src/ohshii_governance/OHSHII governance (ONS)
src/sons_governance/SONS governance (WASM installed per campaign)
src/frontend/Web UI (Vite, React) — launcher, plus Explorer / Atlas / Bridge surfaces
Deploy/Docker build, deploy scripts, voter verification
docs/ARCHITECTURE, GOVERNANCE, GOVERNANCE_VOTING, WORKFLOWS, OHSSHII_LOCKER_INTEGRATION, MENESE_INTEGRATION, WORLD_ID_VERIFICATION, DECIDEID_VERIFICATION, FRONTEND

Production canister IDs (mainnet) are in canister_ids.json.


OhShii Launcher and OhShii Locker (and other OhShii apps) share the same Internet Identity principal per user. This is required so that lock ownership and governance voting work consistently across launcher.ohshii.io and locker.ohshii.io.

How it works:

  • Canonical derivation origin: https://v5mnw-oaaaa-aaaal-qsica-cai.icp0.io (Launcher frontend canister). Internet Identity derives the user’s principal from this origin, not from the current URL.
  • Alternative origins: The Launcher frontend serves .well-known/ii-alternative-origins listing all OhShii domains. II allows login from those origins and returns the same principal as long as the app requests that derivation origin.
  • Frontend configuration: Both Launcher and Locker set derivationOrigin: "https://v5mnw-oaaaa-aaaal-qsica-cai.icp0.io" in AuthClient login options (see Launcher src/frontend/src/utils/auth.js, Locker src/frontend/src/utils/authHelpers.js).

Files involved:

  • Launcher: src/frontend/public/.well-known/ii-alternative-origins.json (the build emits dist/.well-known/ii-alternative-origins, no extension, for IC serving).
  • Locker: same path in its repo; the Locker frontend uses the Launcher URL as derivation origin so the same principal is derived.

Current alternative origins (9 total):

{
"alternativeOrigins": [
"https://b5we6-kqaaa-aaaaj-qntgq-cai.icp0.io",
"https://iewka-oiaaa-aaaah-aq7dq-cai.icp0.io",
"https://v5mnw-oaaaa-aaaal-qsica-cai.icp0.io",
"https://launcher.ohshii.io",
"https://locker.ohshii.io",
"https://ohshii.io",
"https://atlas.ohshii.io",
"https://explorer.ohshii.io",
"https://bridge.ohshii.io"
]
}

After deploy: Users may need to log out and log in again to see the correct principal on both apps.


Three-tier logging (native IC → heap → stable memory) across all canisters. Public dashboard at /system-status. See docs/LOGGING_SYSTEM.md.

  • docs/ARCHITECTURE.md — Canister map and governance scope table.
  • docs/WORKFLOWS.md — Create LGE, token, vote, create/execute proposal, backend vs frontend upgrade, self-snapshot flows.
  • docs/OHSSHII_LOCKER_INTEGRATION.md — OhShii Locker token list and lock management via ONS proposals, SONS vesting vs Locker.
  • docs/GOVERNANCE.md — ONS vs SONS, proposal categories, snapshot/restore.
  • docs/GOVERNANCE_VOTING.md — Voting mechanics: VP, Normal/Critical tiers, guardian veto/override, verification gate.
  • docs/LIQUID_DEMOCRACY.md — ONS vote delegation: follow/unfollow, become-a-delegate toggle, dismiss-follower, snapshot cascade model, rate limits, FAQ.
  • docs/LOGGING_SYSTEM.md — Three-tier logging architecture, stable memory log details, frontend monitoring.
  • docs/FRONTEND.md — Frontend architecture: React + JSX + JSDoc @ts-check type-checking, the canister-types.js + utils/canister.js bridges, Candid wire conventions, auth providers, and the TypeScript version policy.
  • docs/MENESE_INTEGRATION.md — Menese Protocol cross-chain integration: SOL↔ICP flows, mSOL, partner fee model, Sovereign Send API.
  • docs/WORLD_ID_VERIFICATION.md — World ID 4.0 voter verification: flow, privacy model, three-state config, on-canister threshold-ECDSA RP signatures, the governed v3/v4 request-preset toggle, rate limits, governance controls and operator checklist.
  • docs/DECIDEID_VERIFICATION.md — DecideID voter verification: independent second method via ICP Verifiable Credentials, vendored ic-verifiable-credentials, OR-gate semantics, governance control.
  • Deploy/VOTER_VERIFICATION_GUIDE.md — Verifying WASM hashes for DAO proposals.

OhShii Launcher is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). The full license text is in the LICENSE file at the repository root.

What this means in practice:

  • You are free to use, study, modify and redistribute the source code.
  • If you run a modified version as a network service (which a canister deployed to the Internet Computer is), AGPL § 13 requires you to offer the corresponding source code of your modifications to all users interacting with that service. A closed-source commercial fork running on mainnet is not compatible with this license.
  • Modifications and derivative works must themselves be released under AGPL-3.0-or-later.

Vendored third-party code: The directory src/external_crates/ic-verifiable-credentials/ contains a vendored copy of dfinity/verifiable-credentials-sdk, which remains under its original Apache License 2.0 (see the LICENSE and VENDORED.md files in that directory; the single local modification is an ic-cdk version bump). Apache-2.0 and AGPL-3.0 are compatible in this configuration: we redistribute the Apache-2.0 component unchanged in source form, with attribution preserved, alongside our own AGPL-3.0 code.

Copyright: © 2026 OhShii contributors. Individual contributors retain copyright on their contributions, granted to the public under the terms above.