Fair launch update to anchor 14 and finish fleshing out commands

This commit is contained in:
Jordan Prince 2021-09-04 18:40:27 -05:00
parent a6e4b02a74
commit 71ece1b8bb
2 changed files with 108 additions and 8 deletions

View File

@ -15,6 +15,7 @@ cpi = ["no-entrypoint"]
default = []
[dependencies]
anchor-lang = "0.13.2"
anchor-lang = "0.14.0"
anchor-spl = "0.14.0"
arrayref = "0.3.6"
spl-token = { version="3.1.1", features = [ "no-entrypoint" ] }

View File

@ -7,12 +7,14 @@ use {
solana_program::{clock::UnixTimestamp, program_pack::Pack, system_program},
AnchorDeserialize, AnchorSerialize,
},
anchor_spl::token::{self, TokenAccount},
spl_token::state::{Account, Mint},
};
pub const PREFIX: &str = "fair_launch";
pub const TREASURY: &str = "treasury";
pub const MINT: &str = "mint";
pub const LOTTERY: &str="lottery";
#[program]
pub mod fair_launch {
@ -42,6 +44,7 @@ pub struct InitializeFairLaunch<'info> {
rent: Sysvar<'info, Rent>,
}
/// Can only update fair launch before phase 1 start.
#[derive(Accounts)]
pub struct UpdateFairLaunch<'info> {
#[account(mut, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &[fair_launch.bump]], has_one=authority)]
@ -50,6 +53,44 @@ pub struct UpdateFairLaunch<'info> {
authority: AccountInfo<'info>,
}
/// Limited Update that only sets phase 3 dates once bitmap is in place.
#[derive(Accounts)]
pub struct StartPhaseThree<'info> {
#[account(mut, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &[fair_launch.bump]], has_one=authority)]
fair_launch: ProgramAccount<'info, FairLaunch>,
#[account(signer)]
authority: AccountInfo<'info>,
}
/// Can only create the fair launch lottery bitmap after phase 1 has ended.
#[derive(Accounts)]
#[instruction(bump: u8)]
pub struct CreateFairLaunchLotteryBitmap<'info> {
#[account(seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &[fair_launch.bump]], has_one=authority)]
fair_launch: ProgramAccount<'info, FairLaunch>,
#[account(init, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), LOTTERY.as_bytes()], payer=payer, bump=bump, space= FAIR_LAUNCH_LOTTERY_SIZE + (fair_launch.number_tickets_sold_in_phase_1.checked_div(8).ok_or(ErrorCode::NumericalOverflowError)? as usize) + 1)]
fair_launch_lottery_bitmap: ProgramAccount<'info, FairLaunchLotteryBitmap>,
#[account(signer)]
authority: AccountInfo<'info>,
#[account(mut, signer)]
payer: AccountInfo<'info>,
#[account(address = system_program::ID)]
system_program: AccountInfo<'info>,
rent: Sysvar<'info, Rent>,
}
/// Can only set the fair launch lottery bitmap after phase 2 has ended.
#[derive(Accounts)]
pub struct UpdateFairLaunchLotteryBitmap<'info> {
#[account(seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &[fair_launch.bump]], has_one=authority)]
fair_launch: ProgramAccount<'info, FairLaunch>,
#[account(mut, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), LOTTERY.as_bytes(), &[fair_launch_lottery_bitmap.bump]])]
fair_launch_lottery_bitmap: ProgramAccount<'info, FairLaunchLotteryBitmap>,
#[account(signer)]
authority: AccountInfo<'info>,
}
/// Can only purchase a ticket in phase 1.
#[derive(Accounts)]
#[instruction(bump: u8, amount: u64)]
pub struct PurchaseTicket<'info> {
@ -59,6 +100,8 @@ pub struct PurchaseTicket<'info> {
treasury: AccountInfo<'info>,
#[account(init, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), buyer.key.as_ref()], payer=payer, bump=bump, space=FAIR_LAUNCH_TICKET_SIZE)]
fair_launch_ticket: ProgramAccount<'info, FairLaunchTicket>,
#[account(init, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &fair_launch.number_tickets_sold_in_phase_1.to_le_bytes()], payer=payer, bump=bump, space=FAIR_LAUNCH_TICKET_SEQ_SIZE)]
fair_launch_ticket_seq_lookup: ProgramAccount<'info, FairLaunchTicket>,
#[account(mut, signer, constraint= (treasury.owner == &spl_token::id() && buyer.owner == &spl_token::id()) || (treasury.owner != &spl_token::id() && buyer.data_is_empty() && buyer.lamports() > 0) )]
buyer: AccountInfo<'info>,
#[account(mut, signer)]
@ -70,11 +113,17 @@ pub struct PurchaseTicket<'info> {
rent: Sysvar<'info, Rent>,
}
/// IN phase 1, you can adjust up or down in any way
/// In phase 2, you can adjust up or down in any way
/// In phase 3, if you are above the decided_median, you can only adjust down to decided median. If below, you can only
/// adjust down, never up.
#[derive(Accounts)]
#[instruction(amount: u64)]
pub struct AdjustTicket<'info> {
#[account(mut, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), buyer.key.as_ref(), &[fair_launch_ticket.bump]], has_one=buyer, has_one=fair_launch)]
fair_launch_ticket: ProgramAccount<'info, FairLaunchTicket>,
#[account(seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &[fair_launch.bump]])]
fair_launch: ProgramAccount<'info, FairLaunch>,
#[account(mut)]
treasury: AccountInfo<'info>,
@ -85,6 +134,26 @@ pub struct AdjustTicket<'info> {
#[account(address = system_program::ID)]
system_program: AccountInfo<'info>,
}
#[derive(Accounts)]
pub struct PunchTicket<'info> {
#[account(mut, seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), buyer.key.as_ref(), &[fair_launch_ticket.bump]], has_one=buyer, has_one=fair_launch)]
fair_launch_ticket: ProgramAccount<'info, FairLaunchTicket>,
#[account(seeds=[PREFIX.as_bytes(), fair_launch.token_mint.as_ref(), &[fair_launch.bump]], has_one=token_mint)]
fair_launch: ProgramAccount<'info, FairLaunch>,
#[account(mut, signer)]
buyer: AccountInfo<'info>,
#[account(mut, owner=spl_token::id(), token::mint=token_mint, token::authority=buyer)]
buyer_token_account: CpiAccount<'info, TokenAccount>,
#[account(seeds=[PREFIX.as_bytes(), fair_launch.authority.as_ref(), MINT.as_bytes(), fair_launch.data.uuid.as_bytes()])]
token_mint: AccountInfo<'info>,
#[account(address = spl_token::id())]
token_program: AccountInfo<'info>,
}
pub const FAIR_LAUNCH_LOTTERY_SIZE: usize = 8 + // discriminator
32 + // fair launch
1 + // bump
4; // size of bitmask ones
pub const FAIR_LAUNCH_SPACE_VEC_START: usize = 8 + // discriminator
32 + // token_mint
@ -99,10 +168,14 @@ pub const FAIR_LAUNCH_SPACE_VEC_START: usize = 8 + // discriminator
8 + // phase one start
8 + // phase one end
8 + // phase two end
8 + // phase three end
9 + // phase three start
9 + // phase three end
8 + // tick size
8 + // number of tokens provided
8 + // number of tickets sold
8 + // number of tokens
8 + // number of tickets sold in phase 1
8 + // number of tickets remaining at the end in phase 2
8 + // number of tickets punched in phase 3
9 + // decided median,
4; // u32 representing number of amounts in vec so far
pub const FAIR_LAUNCH_TICKET_SIZE: usize = 8 + // discriminator
@ -110,7 +183,12 @@ pub const FAIR_LAUNCH_TICKET_SIZE: usize = 8 + // discriminator
32 + // buyer
8 + // amount paid in so far
1 + // state
1; // bump
1 + // bump
8; // seq
pub const FAIR_LAUNCH_TICKET_SEQ_SIZE: usize = 8 + //discriminator
32 + // fair launch ticket reverse lookup
8; //seq
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
pub struct FairLaunchData {
@ -120,9 +198,10 @@ pub struct FairLaunchData {
pub phase_one_start: UnixTimestamp,
pub phase_one_end: UnixTimestamp,
pub phase_two_end: UnixTimestamp,
pub phase_three_end: UnixTimestamp,
pub phase_three_start: Option<UnixTimestamp>,
pub phase_three_end: Option<UnixTimestamp>,
pub tick_size: u64,
pub number_of_tokens_provided: u64,
pub number_of_tokens: u64,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Default)]
@ -137,10 +216,21 @@ pub struct FairLaunch {
pub treasury_bump: u8,
pub token_mint_bump: u8,
pub data: FairLaunchData,
pub number_tickets_sold: u64,
pub number_tickets_sold_in_phase_1: u64,
pub number_tickets_remaining_in_phase_2: u64,
pub number_tickets_punched_in_phase_3: u64,
pub decided_median: Option<u64>,
pub median: Vec<MedianTuple>,
}
#[account]
pub struct FairLaunchLotteryBitmap {
pub fair_launch: Pubkey,
pub bump: u8,
/// This must be exactly the number of winners and is incremented precisely in each strip addition
pub bitmap_ones: u32
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub enum FairLaunchTicketState {
Unpunched,
@ -155,8 +245,17 @@ pub struct FairLaunchTicket {
pub amount: u64,
pub state: FairLaunchTicketState,
pub bump: u8,
pub seq: u64,
}
#[account]
pub struct FairLaunchTicketSeqLookup {
pub fair_launch_ticket: Pubkey,
pub seq: u64,
}
#[error]
pub enum ErrorCode {
#[msg("Account does not have correct owner!")]