Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
ece7598
relaunch scaffold
metapileks Aug 4, 2026
fde4225
state, constants, scaffolding
metapileks Aug 4, 2026
65a1ed4
sdk scaffold
metapileks Aug 4, 2026
45cb9bc
more scaffolding
metapileks Aug 4, 2026
ee4eec7
fix default strict null-checks introduced by newer default tsconfig i…
metapileks Aug 4, 2026
36418ab
amm fixtures
metapileks Aug 5, 2026
bf5509d
initialize_relaunch ix, sdk, tests
metapileks Aug 5, 2026
b984f38
start_deposits ix, sdk, tests
metapileks Aug 5, 2026
eaebc89
adjust utils
metapileks Aug 5, 2026
2fc0193
deposit ix, sdk, tests
metapileks Aug 5, 2026
f811609
close_deposits ix, sdk, tests
metapileks Aug 5, 2026
c8a387e
mark_failed ix, sdk, tests
metapileks Aug 5, 2026
4449ee2
claim_refund ix, sdk, tests
metapileks Aug 5, 2026
4a1f988
execute_sell ix, sdk, tests
metapileks Aug 6, 2026
4f31835
execute_usdc_swap ix, sdk, tests
metapileks Aug 10, 2026
8b83d38
deposit_via_buy ix, sdk, tests
metapileks Aug 10, 2026
d2c2925
complete_relaunch ix, sdk, tests
metapileks Aug 11, 2026
84c4208
claim ix, sdk, tests
metapileks Aug 11, 2026
3e4c545
integration tests
metapileks Aug 11, 2026
8ea1f77
CI/CD
metapileks Aug 11, 2026
707df37
alt tooling
metapileks Aug 12, 2026
70aaadd
compuite budget
metapileks Aug 12, 2026
e7b34a6
refactor deposit record credit logic
metapileks Aug 12, 2026
5d7a19c
sdk refactor
metapileks Aug 12, 2026
4907316
raydium fixtures
metapileks Aug 13, 2026
42050d4
initialize raydium, pump checks on pump-specific swap ixes, sdk, tests
metapileks Aug 13, 2026
c454d53
execute_sell_raydium ix, sdk, tests
metapileks Aug 13, 2026
6f08301
deposit_via_buy_radium ix, sdk, tests
metapileks Aug 13, 2026
2ec6763
relaunch integration tests - raydium ver
metapileks Aug 13, 2026
4e2090d
add raydium to alt
metapileks Aug 13, 2026
feeaf79
12.5/12.5 depositors/LP ratio
metapileks Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion .github/workflows/generate-verifiable-builds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,21 @@ jobs:
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
with:
default_author: github_actions
message: 'Update gated_mint verifiable build'
message: 'Update gated_mint verifiable build'
generate-verifiable-relaunch:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: metadaoproject/anchor-verifiable-build@6d8fc1999ea4b7ff701e8b166903b398741e1c50 # v0.4
with:
program: relaunch
anchor-version: '0.29.0'
solana-cli-version: '1.17.31'
features: 'production'
- run: 'git pull --rebase'
- run: cp target/deploy/relaunch.so ./verifiable-builds
- name: Commit verifiable build back to mainline
uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
with:
default_author: github_actions
message: 'Update relaunch verifiable build'
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ scripts/*.js
# Test ledger accounts - used when dumping accounts from mainnet to localnet
test-ledger-accounts
# Surfpool
.surfpool/
.surfpool/
vibes/
17 changes: 17 additions & 0 deletions Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
mint_governor = "gvnr27cVeyW3AVf3acL7VCJ5WjGAphytnsgcK1feHyH"
performance_package_v2 = "pPV2pfrxnmstSb9j7kEeCLny5BGj6SNwCWGd6xbGGzz"
price_based_performance_package = "pbPPQH7jyKoSLu8QYs3rSY3YkDRXEBojKbTgnUg7NDS"
relaunch = "vaMpdXN2P3Z5v8y6GtAU5NzCUjxtphnRVpvqu37Spik"

Check warning on line 20 in Anchor.toml

View workflow job for this annotation

GitHub Actions / repository-guard

Hardcoded Solana address literal; Anchor [programs.*] entry change: +relaunch = "vaMpdXN2P3Z5v8y6GtAU5NzCUjxtphnRVpvqu37Spik"

[registry]
url = "https://api.apr.dev"
Expand Down Expand Up @@ -93,3 +94,19 @@
[[test.genesis]]
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
program = "./tests/fixtures/mpl_token_metadata.so"

[[test.genesis]]
address = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"

Check warning on line 99 in Anchor.toml

View workflow job for this annotation

GitHub Actions / repository-guard

Hardcoded Solana address literal; Anchor [programs.*] entry change: +address = "pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"
program = "./tests/fixtures/pump_amm.so"

[[test.genesis]]
address = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"

Check warning on line 103 in Anchor.toml

View workflow job for this annotation

GitHub Actions / repository-guard

Hardcoded Solana address literal; Anchor [programs.*] entry change: +address = "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
program = "./tests/fixtures/pump_fees.so"

[[test.genesis]]
address = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"

Check warning on line 107 in Anchor.toml

View workflow job for this annotation

GitHub Actions / repository-guard

Hardcoded Solana address literal; Anchor [programs.*] entry change: +address = "whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc"
program = "./tests/fixtures/whirlpool.so"

[[test.genesis]]
address = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"

Check warning on line 111 in Anchor.toml

View workflow job for this annotation

GitHub Actions / repository-guard

Hardcoded Solana address literal; Anchor [programs.*] entry change: +address = "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"
program = "./tests/fixtures/raydium_amm.so"
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,20 +191,20 @@ Tests use `solana-bankrun` for deterministic testing without external RPC:
- `advanceBySlots()` - Simulate time progression
- Time constants: `TEN_SECONDS_IN_SLOTS`, `ONE_MINUTE_IN_SLOTS`, `HOUR_IN_SLOTS`, `DAY_IN_SLOTS`

**Getting unique transaction signatures:** When testing error cases that call the same instruction multiple times (e.g., verifying an action fails after state changes), add a `ComputeBudgetProgram.setComputeUnitLimit()` instruction with incrementing values to produce different transaction signatures:
**Getting unique transaction signatures:** When testing error cases that call the same instruction multiple times (e.g., verifying an action fails after state changes), add a `ComputeBudgetProgram.setComputeUnitPrice()` instruction to make the transaction hash unique, so the retry isn't rejected as a duplicate of the earlier byte-identical transaction:

```typescript
// First call (200_000), second call (200_001), etc.
// If the same call site needs several unique retries, increment microLamports (1, 2, ...).
await client
.someIx({ ... })
.postInstructions([
ComputeBudgetProgram.setComputeUnitLimit({ units: 200_000 }),
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 }),
])
.signers([signer])
.rpc();
```

Do NOT use `advanceBySlots()` for this purpose - it changes the clock which may affect time-dependent tests.
Do NOT use `setComputeUnitLimit()` for this — reserve it for genuinely raising a transaction's compute budget. Do NOT use `advanceBySlots()` either - it changes the clock which may affect time-dependent tests.

**Isolating tests during development:** When writing or editing tests, ALWAYS add `.only` to the `describe`/`it` block you're working on before running. This keeps feedback fast and output clean. Once your changes pass, remove `.only` and run the full suite (`anchor test --skip-build`) to confirm nothing else broke.

Expand Down
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Programs for unruggable capital formation and market-driven governance.

| program | tag | program ID |
| ----------------- | ---- | -------------------------------------------- |
| relaunch | v0.1.0 | vaMpdXN2P3Z5v8y6GtAU5NzCUjxtphnRVpvqu37Spik |
| gated_mint | v0.1.0 | GaTEjZy6eMdHg2BcL8dk3iE78jkJ9sPtyw1q2tMNi8PA |
| launchpad | v0.8.0 | moonDJUoHteKkGATejA5bdJVwJ6V6Dg74gyqyJTx73n |
| launchpad | v0.7.0 | moontUzsdepotRGe5xsfip7vLPTJnVuafqdUWexVnPM |
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"redeem-launch": "NODE_OPTIONS=\"--no-deprecation\" tsx --tsconfig tsconfig.json scripts/redeemLaunch.ts",
"setup-futarchy-amm": "NODE_OPTIONS=\"--no-deprecation\" tsx --tsconfig tsconfig.json scripts/setupFutarchyAmm.ts",
"initialize-dao": "NODE_OPTIONS=\"--no-deprecation\" tsx --tsconfig tsconfig.json scripts/v0.6/initializeDao.ts",
"relaunch-create-alt": "NODE_OPTIONS=\"--no-deprecation\" tsx --tsconfig tsconfig.json scripts/relaunch/createAlt.ts",
"prepare": "husky"
},
"lint-staged": {
Expand Down
24 changes: 24 additions & 0 deletions programs/relaunch/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "relaunch"
version = "0.1.0"
description = "Created with Anchor"
edition = "2021"

[lib]
crate-type = ["cdylib", "lib"]
name = "relaunch"

[features]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []
production = []

[dependencies]
anchor-lang = { version = "=0.29.0", features = ["init-if-needed", "event-cpi"] }
anchor-spl = { version = "=0.29.0", features = ["metadata"] }
solana-security-txt = "=1.1.1"
futarchy = { path = "../futarchy", features = ["cpi"] }
squads-multisig-program = { git = "https://github.com/Squads-Protocol/v4", package = "squads-multisig-program", rev = "6d5235da621a2e9b7379ea358e48760e981053be", features = ["cpi"] }
2 changes: 2 additions & 0 deletions programs/relaunch/Xargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []
132 changes: 132 additions & 0 deletions programs/relaunch/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
pub const TOKEN_SCALE: u64 = 1_000_000;

pub const PRICE_SCALE: u128 = 1_000_000_000_000;

/// 12.5M tokens with 6 decimals, distributed pro-rata to depositors.
pub const TOKENS_TO_DEPOSITORS: u64 = 12_500_000 * TOKEN_SCALE;
/// 12.5M tokens with 6 decimals, paired with all recovered USDC in the
/// futarchy AMM.
pub const TOKENS_TO_FUTARCHY_LIQUIDITY: u64 = 12_500_000 * TOKEN_SCALE;
/// 1.5M tokens with 6 decimals, staked to create a proposal (launchpad's value).
pub const PROPOSAL_MIN_STAKE_TOKENS: u64 = 1_500_000 * TOKEN_SCALE;

/// 1 year.
pub const MAX_SECONDS_FOR_DEPOSITS: u32 = 60 * 60 * 24 * 365;

pub mod wsol_mint {
use anchor_lang::prelude::declare_id;

declare_id!("So11111111111111111111111111111111111111112");

Check warning on line 19 in programs/relaunch/src/constants.rs

View workflow job for this annotation

GitHub Actions / repository-guard

declare_id! literal change; Hardcoded Solana address literal: + declare_id!("So11111111111111111111111111111111111111112");
}

pub mod usdc_mint {
use anchor_lang::prelude::declare_id;

declare_id!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");

Check warning on line 25 in programs/relaunch/src/constants.rs

View workflow job for this annotation

GitHub Actions / repository-guard

declare_id! literal change; Hardcoded Solana address literal: + declare_id!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
}

// pump

/// Seed of the pump pool-authority PDA, derived under the pump bonding-curve
/// program: `["pool-authority", mint]`. The canonical PumpSwap pool for a
/// mint has this PDA as its `creator`.
pub const PUMP_POOL_AUTHORITY_SEED: &[u8] = b"pool-authority";

/// Seed of PumpSwap pool PDAs, derived under pump_amm:
/// `["pool", index_le_u16, creator, base_mint, quote_mint]`.
pub const PUMP_POOL_SEED: &[u8] = b"pool";

/// The pump bonding-curve program. The pool-authority PDA that creates
/// canonical PumpSwap pools at graduation is derived under this program.
pub mod pump_program {
use anchor_lang::prelude::declare_id;

declare_id!("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");

Check warning on line 44 in programs/relaunch/src/constants.rs

View workflow job for this annotation

GitHub Actions / repository-guard

declare_id! literal change; Hardcoded Solana address literal: + declare_id!("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");
}

/// PumpSwap — the AMM that canonical graduation pools live on.
pub mod pump_amm_program {
use anchor_lang::prelude::declare_id;

declare_id!("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA");

Check warning on line 51 in programs/relaunch/src/constants.rs

View workflow job for this annotation

GitHub Actions / repository-guard

declare_id! literal change; Hardcoded Solana address literal: + declare_id!("pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA");
}

/// The pump fee program that PumpSwap consults for its dynamic fee tiers.
pub mod pump_fees_program {
use anchor_lang::prelude::declare_id;

declare_id!("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ");

Check warning on line 58 in programs/relaunch/src/constants.rs

View workflow job for this annotation

GitHub Actions / repository-guard

declare_id! literal change; Hardcoded Solana address literal: + declare_id!("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ");
}

/// pump_amm's global config: the `["global_config"]` PDA under pump_amm.
pub mod pump_amm_global_config {
use anchor_lang::prelude::declare_id;

declare_id!("ADyA8hdefvWN2dbGGWFotbzWxrAvLW83WG6QCVXvJKqw");
}

/// pump_amm's event authority: the `["__event_authority"]` PDA under pump_amm.
pub mod pump_amm_event_authority {
use anchor_lang::prelude::declare_id;

declare_id!("GS4CU59F31iL7aR2Q8zVS8DRrcRnXX1yjQ66TqNVQnaR");
}

/// The fee config the pump fee program keeps for pump_amm: the
/// `["fee_config", pump_amm program id]` PDA under pump_fees.
pub mod pump_amm_fee_config {
use anchor_lang::prelude::declare_id;

declare_id!("5PHirr8joyTMp9JMm6nW7hNDVyEYdkzDqazxPD7RaTjx");
}

// Raydium

/// Raydium's legacy "Standard" AMM v4, where pre-PumpSwap pump graduations
/// live.
pub mod raydium_amm_program {
use anchor_lang::prelude::declare_id;

declare_id!("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8");
}

/// The global authority PDA over every AMM v4 vault: `["amm authority"]`.
pub mod raydium_amm_authority {
use anchor_lang::prelude::declare_id;

declare_id!("5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1");
}

/// OpenBook v1. Stored as `market_program` by every orderbook-era AMM v4
/// pool. All pump graduations have this as an orderbook.
pub mod openbook_program {
use anchor_lang::prelude::declare_id;

declare_id!("srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX");
}

/// A Raydium source pool must have at least this much LP burned
/// (`lp_amount - lp_mint.supply`, raw units, 9 decimals).
pub const RAYDIUM_MIN_BURNED_LP: u64 = 4_000_000_000_000;

// Orca

pub mod whirlpool_program {
use anchor_lang::prelude::declare_id;

declare_id!("whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc");
}

/// Orca Whirlpool SOL/USDC 0.04% — the pinned venue for the WSOL→USDC swap leg.
pub mod usdc_swap_pool {
use anchor_lang::prelude::declare_id;

declare_id!("Czfq3xZZDmsdGdUyrNLtRhGc47cXcZtLG4crryfu44zE");
}

/// SPL Memo, required by whirlpool's v2 instructions.
pub mod memo_program {
use anchor_lang::prelude::declare_id;

declare_id!("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr");
}
67 changes: 67 additions & 0 deletions programs/relaunch/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use anchor_lang::prelude::*;

#[error_code]
pub enum RelaunchError {
#[msg("New mint supply must be zero")]
SupplyNonZero,
#[msg("New mint must not have a freeze authority")]
FreezeAuthoritySet,
#[msg("Source pool is not the canonical PumpSwap pool for the old mint")]
SourcePoolNotCanonical,
#[msg("Source quote mint does not match the source pool's quote mint")]
SourcePoolQuoteMintMismatch,
#[msg("Source quote mint must be WSOL or USDC")]
InvalidQuoteMint,
#[msg("Old mint carries a Token-2022 extension outside the metadata allowlist")]
ForbiddenOldMintExtension,
#[msg("Threshold must be between 1 and 10000 bps")]
InvalidThresholdBps,
#[msg("Deposit period must be at most 1 year")]
InvalidSecondsForDeposits,
#[msg("Monthly spending limit amount and members must both be set or both be empty")]
InvalidMonthlySpendingLimit,
#[msg("There can be at most 10 monthly spending limit members, without duplicates")]
InvalidMonthlySpendingLimitMembers,
#[msg("Relaunch must be in the Initialized state")]
RelaunchNotInitialized,
#[msg("Relaunch must be in the Live state")]
RelaunchNotLive,
#[msg("Deposit window has closed")]
DepositWindowClosed,
#[msg("Amount must be greater than zero")]
InvalidAmount,
#[msg("Insufficient balance")]
InsufficientFunds,
#[msg("Deposit window is still open")]
DepositWindowStillOpen,
#[msg("Relaunch must be in the SellPending state")]
RelaunchNotSellPending,
#[msg("Grace period has not elapsed")]
GracePeriodStillActive,
#[msg("Relaunch must be in the Failed state")]
RelaunchNotFailed,
#[msg("Deposit record has already been claimed")]
AlreadyClaimed,
#[msg("Grace period has elapsed")]
GracePeriodElapsed,
#[msg("Relaunch must be in the Sold state")]
RelaunchNotSold,
#[msg("Swap output is below the minimum output amount")]
SlippageExceeded,
#[msg("Relaunch must be in the Swapped state")]
RelaunchNotSwapped,
#[msg("Relaunch must be in the Complete state")]
RelaunchNotComplete,
#[msg("Casting overflow. If you're seeing this, please report this")]
CastingOverflow,
#[msg("Source pool LP mint must be supplied for Raydium sources only and match the pool's stored LP mint")]
SourcePoolLpMintMismatch,
#[msg("Source pool's burned LP is below the required floor")]
SourcePoolLpNotBurned,
#[msg("Source pool's status does not permit swaps")]
SourcePoolSwapsDisabled,
#[msg("Source pool was not created in the orderbook era")]
SourcePoolWrongEra,
#[msg("Instruction does not match the relaunch's source venue")]
WrongSourceVenue,
}
Loading
Loading