Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions scripts/assets/P2P/P2P.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "P2P Protocol",
"symbol": "P2P",
"description": "Futarchy Ownership, Protocol Governance and Trust Staking token of the P2P Protocol",
"image": "https://raw.githubusercontent.com/metaDAOproject/programs/refs/heads/develop/scripts/assets/P2P/P2P.png"
}
Binary file added scripts/assets/P2P/P2P.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
158 changes: 158 additions & 0 deletions scripts/v0.7/launchP2P.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import * as anchor from "@coral-xyz/anchor";
import {
LaunchpadClient,
getLaunchAddr,
getLaunchSignerAddr,
} from "@metadaoproject/futarchy/v0.7";
import {
ComputeBudgetProgram,
PublicKey,
SystemProgram,
Transaction,
} from "@solana/web3.js";
import BN from "bn.js";
import * as token from "@solana/spl-token";

const provider = anchor.AnchorProvider.env();
const payer = provider.wallet["payer"];

const LAUNCH_AUTHORITY = payer.publicKey;

const TEAM_ADDRESS = new PublicKey(
"63miwxnMci7L76tWBGFfmHjbm199MKiteiWrNY1ShQhV",
); // P2P team address

// Launch details
const MIN_GOAL = 6_000_000; // 6M USDC

const SPENDING_MEMBERS = [
new PublicKey("G4vHnTW7PSgTtHAYwmrBvUydWGmz8Bd2px9XYAsBQWgu"),
new PublicKey("6fwrmfLPCQJmF47LdoLTBBojtw8Qbq2wicRyDpzsQjBk"),
new PublicKey("CTDAar2UbkpVq21u8RRvzWT3rtjvoeV2PFZp7PdiMZWg"),
];
const SPENDING_LIMIT = 175_000; // 175k USDC

const PERFORMANCE_PACKAGE_GRANTEE = TEAM_ADDRESS;
const PERFORMANCE_PACKAGE_TOKEN_AMOUNT = 7_740_000; // 7.74M P2P
const PERFORMANCE_PACKAGE_UNLOCK_MONTHS = 12; // 12 months

// Additional carveout details
const ADDITIONAL_CARVEOUT = 5_160_000; // 5.16M P2P
const ADDITIONAL_CARVEOUT_RECIPIENT = new PublicKey(
"BzZhwMzoY5ikk9mWBejb3dKbYXCYZ6eJhijk71WfvTYt",
); // MetaDAO P2P Launch Custody Multisig

const TOKEN_SEED = "ltSNHJR5jLfmx0Zs";
const TOKEN_NAME = "P2P Protocol";
const TOKEN_SYMBOL = "P2P";
const TOKEN_URI =
"https://raw.githubusercontent.com/metaDAOproject/programs/refs/heads/develop/scripts/assets/P2P/P2P.json";

const secondsPerDay = 86_400;
const numberOfDays = 4;
const launchDurationSeconds = secondsPerDay * numberOfDays; // 4 days

const launchpad: LaunchpadClient = LaunchpadClient.createClient({ provider });

export const launch = async () => {
const lamports = await provider.connection.getMinimumBalanceForRentExemption(
token.MINT_SIZE,
);

const TOKEN = await PublicKey.createWithSeed(
payer.publicKey,
TOKEN_SEED,
token.TOKEN_PROGRAM_ID,
);
console.log("Token address:", TOKEN.toBase58());

const [launch] = getLaunchAddr(undefined, TOKEN);
const [launchSigner] = getLaunchSignerAddr(undefined, launch);

const createTokenAccountIx = SystemProgram.createAccountWithSeed({
fromPubkey: payer.publicKey,
newAccountPubkey: TOKEN,
basePubkey: payer.publicKey,
seed: TOKEN_SEED,
lamports: lamports,
space: token.MINT_SIZE,
programId: token.TOKEN_PROGRAM_ID,
});

const initializeMintIx = token.createInitializeMint2Instruction(
TOKEN,
6,
launchSigner,
null,
);

const launchIx = await launchpad
.initializeLaunchIx({
tokenName: TOKEN_NAME,
tokenSymbol: TOKEN_SYMBOL,
tokenUri: TOKEN_URI,
minimumRaiseAmount: new BN(MIN_GOAL * 10 ** 6),
baseMint: TOKEN,
monthlySpendingLimitAmount: new BN(SPENDING_LIMIT * 10 ** 6),
monthlySpendingLimitMembers: SPENDING_MEMBERS,
performancePackageGrantee: PERFORMANCE_PACKAGE_GRANTEE,
performancePackageTokenAmount: new BN(
PERFORMANCE_PACKAGE_TOKEN_AMOUNT * 10 ** 6,
),
monthsUntilInsidersCanUnlock: PERFORMANCE_PACKAGE_UNLOCK_MONTHS,
secondsForLaunch: launchDurationSeconds,
teamAddress: TEAM_ADDRESS,
additionalTokensAmount: ADDITIONAL_CARVEOUT
? new BN(ADDITIONAL_CARVEOUT * 10 ** 6)
: undefined,
additionalTokensRecipient: ADDITIONAL_CARVEOUT_RECIPIENT,
launchAuthority: LAUNCH_AUTHORITY,
})
.instruction();

const tx = new Transaction().add(
createTokenAccountIx,
initializeMintIx,
launchIx,
);
const { blockhash } = await provider.connection.getLatestBlockhash();
tx.recentBlockhash = blockhash;
tx.feePayer = payer.publicKey;
tx.sign(payer);
const simulation = await provider.connection.simulateTransaction(tx);

if (simulation.value.err) {
console.error("Transaction simulation failed:", simulation.value.err);
throw new Error(
`Simulation failed: ${JSON.stringify(simulation.value.err)}`,
);
}

const computeUnitsUsed = simulation.value.unitsConsumed || 200_000;
// Add 20% buffer to the compute units
const computeUnitsWithBuffer = Math.floor(computeUnitsUsed * 1.2);

console.log(`Simulated compute units: ${computeUnitsUsed}`);
console.log(`Setting compute unit limit: ${computeUnitsWithBuffer}`);

// Rebuild transaction with compute budget
const finalTx = new Transaction().add(
ComputeBudgetProgram.setComputeUnitLimit({ units: computeUnitsWithBuffer }),
createTokenAccountIx,
initializeMintIx,
launchIx,
);

finalTx.recentBlockhash = blockhash;
finalTx.feePayer = payer.publicKey;
finalTx.sign(payer);

const txHash = await provider.connection.sendRawTransaction(
finalTx.serialize(),
);
await provider.connection.confirmTransaction(txHash, "confirmed");

console.log("Launch initialized, P2P for you and for me!", txHash);
};

launch().catch(console.error);
Loading