Skip to content
Open
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
7 changes: 7 additions & 0 deletions Anchor.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ v06-dump-daos-proposals = "yarn run tsx scripts/v0.6/dumpDaosProposals.ts"
v06-migrate-daos-proposals = "yarn run tsx scripts/v0.6/migrateDaosProposals.ts"
v06-create-dao = "yarn run tsx scripts/v0.6/createDao.ts"
v06-provide-liquidity = "yarn run tsx scripts/v0.6/provideLiquidity.ts"
v07-launch-template = "yarn run tsx scripts/v0.7/launchTemplate.ts"
v07-start-launch = "yarn run tsx scripts/v0.7/startLaunch.ts"
v07-complete-launch = "yarn run tsx scripts/v0.7/completeLaunch.ts"
v07-claim-all-launch = "yarn run tsx scripts/v0.7/claimAllLaunch.ts"
v07-approve-points-based = "yarn run tsx scripts/v0.7/pointsBased/approveWithPointsWeightedPhase.ts"
v07-close-launch = "yarn run tsx scripts/v0.7/closeLaunch.ts"
v07-initialize-performance-package = "yarn run tsx scripts/v0.7/initializePerformancePackage.ts"

[test]
startup_wait = 5000
Expand Down
34 changes: 19 additions & 15 deletions scripts/v0.7/claimAllLaunch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const provider = anchor.AnchorProvider.env();
const payer = provider.wallet["payer"];

const launchAddr = new PublicKey(
"9kx7UDFzFt7e2V4pFtawnupKKvRR3EhV7P1Pxmc5XCQj",
"FvQCwxmELEr7Dis8eQsij1F53wxgMohSiEZ9jMLMCapm",
);

const launchpad: LaunchpadClient = LaunchpadClient.createClient({ provider });
Expand Down Expand Up @@ -54,29 +54,33 @@ async function main() {
const tx = new Transaction();

// Add compute budget instruction to handle multiple claims
tx.add(ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }));
// tx.add(ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }));

// Add claim instructions for each record in the batch
for (const record of batch) {
const claimIx = await launchpad
.claimIx(launchAddr, launch.baseMint, record.account.funder)
.transaction();
if (!record.account.isTokensClaimed) {
const claimIx = await launchpad
.claimIx(launchAddr, launch.baseMint, record.account.funder)
.transaction();

tx.add(claimIx);
tx.add(claimIx);
}
}

await sendAndConfirmTransaction(tx, `Claim batch ${i / batchSize + 1}`);

for (const record of batch) {
const refundIx = await launchpad
.refundIx({
launch: launchAddr,
funder: record.account.funder,
quoteMint: launch.baseMint,
})
.transaction();

tx.add(refundIx);
if (!record.account.isUsdcRefunded) {
const refundIx = await launchpad
.refundIx({
launch: launchAddr,
funder: record.account.funder,
quoteMint: launch.quoteMint,
})
.transaction();

tx.add(refundIx);
}
}

await sendAndConfirmTransaction(tx, `Refund batch ${i / batchSize + 1}`);
Expand Down
8 changes: 3 additions & 5 deletions scripts/v0.7/closeLaunch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ const payer = provider.wallet["payer"];

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

export const closeLaunch = async () => {
const mintKp = new PublicKey("PRVT6TB7uss3FrUd2D9xs2zqDBsa3GbMJMwCQsgmeta");

const [launch] = getLaunchAddr(undefined, mintKp);
const launch = new PublicKey("FvQCwxmELEr7Dis8eQsij1F53wxgMohSiEZ9jMLMCapm");

console.log(`Closing launch at address: ${launch.toString()}`);
export const closeLaunch = async () => {
console.log(`Closing launch at address: ${launch.toBase58()}`);

await launchpad.closeLaunchIx({ launch }).rpc();

Expand Down
30 changes: 15 additions & 15 deletions scripts/v0.7/completeLaunch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,29 @@ import {
} from "@solana/web3.js";
import { createLookupTableForTransaction } from "../utils/utils.js";

const LAUNCH_TO_COMPLETE: PublicKey | undefined = new PublicKey(
"FvQCwxmELEr7Dis8eQsij1F53wxgMohSiEZ9jMLMCapm",
);

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

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

const BID_WALL_FEE_RECIPIENT: PublicKey | undefined = undefined;

export const completeLaunch = async () => {
if (BID_WALL_FEE_RECIPIENT === undefined) {
if (LAUNCH_TO_COMPLETE === undefined) {
throw new Error(
"BID_WALL_FEE_RECIPIENT is not set. Please set it in the script.",
"LAUNCH_TO_COMPLETE is not set. Please set it in the script.",
);
}

const mintKp = new PublicKey("PRVT6TB7uss3FrUd2D9xs2zqDBsa3GbMJMwCQsgmeta");

const [launch] = getLaunchAddr(undefined, mintKp);
let launchAccount = await launchpad.fetchLaunch(LAUNCH_TO_COMPLETE);

const tx = await launchpad
.completeLaunchIx({
launch,
baseMint: mintKp,
launch: LAUNCH_TO_COMPLETE,
baseMint: launchAccount.baseMint,
launchAuthority: payer.publicKey,
feeRecipient: BID_WALL_FEE_RECIPIENT,
})
.transaction();

Expand All @@ -51,20 +50,21 @@ export const completeLaunch = async () => {
const vtx = new VersionedTransaction(message);
vtx.sign([payer]);

const completeTxHash = await provider.connection.sendTransaction(vtx, {
skipPreflight: true,
});
const completeTxHash = await provider.connection.sendTransaction(vtx);

console.log(`Complete launch transaction sent: ${completeTxHash}`);

console.log("Launch completed successfully!");

console.log("Setting up performance package...");

// Refresh launch account to get the updated base mint
launchAccount = await launchpad.fetchLaunch(LAUNCH_TO_COMPLETE);

const initializePerformancePackageTxHash = await launchpad
.initializePerformancePackageIx({
launch,
baseMint: mintKp,
launch: LAUNCH_TO_COMPLETE,
baseMint: launchAccount.baseMint,
payer: payer.publicKey,
})
.rpc();
Expand Down
40 changes: 40 additions & 0 deletions scripts/v0.7/initializePerformancePackage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as anchor from "@coral-xyz/anchor";
import { LaunchpadClient } from "@metadaoproject/futarchy/v0.7";
import { PublicKey } from "@solana/web3.js";

const LAUNCH_TO_COMPLETE: PublicKey | undefined = new PublicKey(
"FvQCwxmELEr7Dis8eQsij1F53wxgMohSiEZ9jMLMCapm",
);

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

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

export const completeLaunch = async () => {
if (LAUNCH_TO_COMPLETE === undefined) {
throw new Error(
"LAUNCH_TO_COMPLETE is not set. Please set it in the script.",
);
}

const launchAccount = await launchpad.fetchLaunch(LAUNCH_TO_COMPLETE);

console.log("Setting up performance package...");

const initializePerformancePackageTxHash = await launchpad
.initializePerformancePackageIx({
launch: LAUNCH_TO_COMPLETE,
baseMint: launchAccount.baseMint,
payer: payer.publicKey,
})
.rpc();

console.log(
`Initialize performance package transaction sent: ${initializePerformancePackageTxHash}`,
);

console.log("Performance package set up successfully!");
};

completeLaunch().catch(console.error);
6 changes: 4 additions & 2 deletions scripts/v0.7/launchTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export const launch = async () => {
const txHash = await provider.connection.sendRawTransaction(tx.serialize());
await provider.connection.confirmTransaction(txHash, "confirmed");

const launchIx = await launchpad
const initializeLaunchTxSignature = await launchpad
.initializeLaunchIx({
tokenName: TOKEN_NAME,
tokenSymbol: TOKEN_SYMBOL,
Expand All @@ -101,7 +101,9 @@ export const launch = async () => {
})
.rpc();

console.log("Launch initialized", launchIx);
console.log("Launch initialized", initializeLaunchTxSignature);

console.log("Launch address:", launch.toBase58());
// await launchpad.startLaunchIx({ launch }).rpc();
};

Expand Down
1 change: 1 addition & 0 deletions scripts/v0.7/pointsBased/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
points.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,22 @@ const payer = provider.wallet["payer"];
const launchpad: LaunchpadClient = LaunchpadClient.createClient({ provider });

// How many approvals to perform per transaction
const batchSize = 5;
const batchSize = 20;

// The launch address
const launchAddr = new PublicKey(
"9kx7UDFzFt7e2V4pFtawnupKKvRR3EhV7P1Pxmc5XCQj",
"FvQCwxmELEr7Dis8eQsij1F53wxgMohSiEZ9jMLMCapm",
);

// The final raise amount (USDC, in atoms)
const finalRaiseAmount = 1_000_000_000000;
const finalRaiseAmount = 10_000000;

async function main() {
const pointsAllocations: PointsAllocation[] = JSON.parse(
fs.readFileSync(path.join(__dirname, "pointsAllocations.json"), "utf8"),
fs.readFileSync(
path.join(process.cwd(), "scripts/v0.7/pointsBased/points.json"),
"utf8",
),
).map((x) => ({
user: new PublicKey(x.user),
points: x.points,
Expand Down Expand Up @@ -115,9 +118,12 @@ async function main() {

// Assign amount to approve to each record
for (const record of allFundingRecordsWithPointsOwners) {
record.amountToApprove = record.account.committedAmount
.mul(new BN(record.pointsOwner?.points ?? 0)) // In this phase, if there is no points owner, then they get no allocation, so we multiply by 0.
.div(totalPointsWithinLaunch);
record.amountToApprove = BN.min(
record.account.committedAmount,
new BN(finalRaiseAmount)
.mul(new BN(record.pointsOwner?.points ?? 0)) // In this phase, if there is no points owner, then they get no allocation, so we multiply by 0.
.div(totalPointsWithinLaunch),
);
}

// Sum up total amount to approve
Expand Down Expand Up @@ -152,15 +158,22 @@ async function main() {
}
}

// // IMPORTANT - PLEASE READ
// // Uncomment this if we want the final raise amount to be a bit over the total committed amount
// // This might be important if we want to ensure that the launch is successful in cases where the final raise amount is exactly equal to the minimum raise amount.
// // A small dust difference will occur due to rounding which could normally fail the launch, so we need to add 1 to all of the records that have an amount to approve that is not equal to the committed amount.
// // A small dust difference will occur due to rounding which could normally fail the launch, so we need to add 1 atom to all of the records that have an amount to approve that is not equal to the committed amount.
// for (const record of allFundingRecordsWithPointsOwners) {
// if (record.amountToApprove.lt(record.account.committedAmount)) {
// record.amountToApprove = record.amountToApprove.add(new BN(1));
// }
// }

for (const record of allFundingRecordsWithPointsOwners) {
console.log(
`${record.account.funder.toBase58()}:\t${record.amountToApprove.toString()}`,
);
}

// Sum up total amount to approve and render it to the user
const finalAmountToApprove = allFundingRecordsWithPointsOwners.reduce(
(acc, curr) => acc.add(curr.amountToApprove),
Expand Down
4 changes: 4 additions & 0 deletions scripts/v0.7/pointsBased/points.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
{ "user": "11111111111111111111111111111111", "points": 100 },
{ "user": "22222222222222222222222222222222", "points": 2 }
]
74 changes: 74 additions & 0 deletions scripts/v0.7/startLaunch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Keypair, PublicKey, Transaction } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";
import { LaunchpadClient } from "@metadaoproject/futarchy/v0.7";

import dotenv from "dotenv";

dotenv.config();

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

const LAUNCH_TO_START = new PublicKey(
"FvQCwxmELEr7Dis8eQsij1F53wxgMohSiEZ9jMLMCapm",
);

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

async function main() {
const launchAuthorityKeypair = payer;

console.log(
"Launch authority public key:",
launchAuthorityKeypair.publicKey.toBase58(),
);

console.log("Starting launch...");

const tx = await launchpad
.startLaunchIx({
launch: LAUNCH_TO_START,
launchAuthority: launchAuthorityKeypair.publicKey,
})
.transaction();

await sendAndConfirmTransaction(tx, "Start launch", [launchAuthorityKeypair]);

console.log("Launch started!");
console.log("Launch address:", LAUNCH_TO_START.toBase58());
}

// Make sure the promise rejection is handled
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});

async function sendAndConfirmTransaction(
tx: Transaction,
label: string,
signers: Keypair[] = [],
) {
tx.feePayer = payer.publicKey;
tx.recentBlockhash = (
await provider.connection.getLatestBlockhash()
).blockhash;
tx.partialSign(payer, ...signers);
const txHash = await provider.connection.sendRawTransaction(tx.serialize());
console.log(`${label} transaction sent:`, txHash);

await provider.connection.confirmTransaction(txHash, "confirmed");
const txStatus = await provider.connection.getTransaction(txHash, {
maxSupportedTransactionVersion: 0,
commitment: "confirmed",
});
if (txStatus?.meta?.err) {
throw new Error(
`Transaction failed: ${txHash}\nError: ${JSON.stringify(
txStatus?.meta?.err,
)}\n\n${txStatus?.meta?.logMessages?.join("\n")}`,
);
}
console.log(`${label} transaction confirmed`);
return txHash;
}