More Solana Contribute functionality
This commit is contained in:
parent
61083a86e3
commit
213f999cd2
|
@ -74,6 +74,7 @@ impl<'b, const STATE: AccountState> Seeded<&ContributionStateAccountDerivationDa
|
|||
pub type CustodyAccount<'b, const STATE: AccountState> = Data<'b, SplAccount, { STATE }>;
|
||||
|
||||
pub struct CustodyAccountDerivationData {
|
||||
pub sale_id: u128,
|
||||
pub mint: Pubkey,
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ use crate::{
|
|||
CustodyAccountDerivationData,
|
||||
ContributionStateAccount,
|
||||
ContributionStateAccountDerivationData,
|
||||
AuthoritySigner,
|
||||
},
|
||||
errors::Error::*,
|
||||
types::*,
|
||||
};
|
||||
|
||||
|
@ -62,6 +64,7 @@ pub struct ContributeIccoSale<'b> {
|
|||
|
||||
pub from: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>, // From account
|
||||
pub mint: Mut<Data<'b, SplMint, { AccountState::Initialized }>>, // From token
|
||||
pub authority_signer: AuthoritySigner<'b>,
|
||||
|
||||
pub custody_signer: CustodySigner<'b>,
|
||||
pub custody: Mut<CustodyAccount<'b, { AccountState::MaybeInitialized }>>, // TBD Move custody Account init to separate call. By Sale creator before init sale. In case sale creator needs to pay for it.
|
||||
|
@ -80,6 +83,7 @@ impl<'a> From<&ContributeIccoSale<'a>> for SaleStateDerivationData {
|
|||
impl<'a> From<&ContributeIccoSale<'a>> for CustodyAccountDerivationData {
|
||||
fn from(accs: &ContributeIccoSale<'a>) -> Self {
|
||||
CustodyAccountDerivationData {
|
||||
sale_id: accs.init_sale_vaa.sale_id,
|
||||
mint: *accs.mint.info().key,
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +102,8 @@ impl<'a> From<&ContributeIccoSale<'a>> for ContributionStateAccountDerivationDat
|
|||
|
||||
#[derive(BorshDeserialize, BorshSerialize, Default)]
|
||||
pub struct ContributeIccoSaleData {
|
||||
amount: u128,
|
||||
amount: u64,
|
||||
token_idx: u8,
|
||||
}
|
||||
|
||||
impl<'b> InstructionContext<'b> for ContributeIccoSale<'b> {
|
||||
|
@ -111,6 +116,34 @@ pub fn contribute_icco_sale(
|
|||
) -> Result<()> {
|
||||
msg!("bbrp in contribute_icco_sale!");
|
||||
|
||||
// Check sale status.
|
||||
if accs.sale_state.is_sealed || accs.sale_state.is_aborted {
|
||||
return Err(SaleSealedOrAborted.into());
|
||||
}
|
||||
|
||||
// Check if sale started.
|
||||
// require(block.timestamp >= start, "sale not yet started");
|
||||
// require(block.timestamp <= end, "sale has ended");
|
||||
let now_time = accs.clock.unix_timestamp as u128; // i64 ->u128
|
||||
if now_time < accs.init_sale_vaa.get_sale_start(&accs.init_sale_vaa.meta().payload[..]).0 {
|
||||
return Err(SaleHasNotStarted.into());
|
||||
}
|
||||
if now_time > accs.init_sale_vaa.get_sale_end(&accs.init_sale_vaa.meta().payload[..]).0 {
|
||||
return Err(SaleHasEnded.into());
|
||||
}
|
||||
|
||||
// Make sure token Idx matches passed in token mint addr.
|
||||
let token_idx = data.token_idx;
|
||||
if token_idx >= accs.init_sale_vaa.token_cnt {
|
||||
return Err(InvalidTokenIndex.into());
|
||||
}
|
||||
let token_idx = usize::from(token_idx);
|
||||
let &token_addr = &accs.init_sale_vaa.get_accepted_token_address(token_idx, &accs.init_sale_vaa.meta().payload[..]);
|
||||
let token_chain = accs.init_sale_vaa.get_accepted_token_chain(token_idx, &accs.init_sale_vaa.meta().payload[..]);
|
||||
if &token_addr != accs.mint.info().key || token_chain != CHAIN_ID_SOLANA {
|
||||
return Err(InvalidTokenAddress.into());
|
||||
}
|
||||
|
||||
// Create and init custody account as needed.
|
||||
// https://github.com/certusone/wormhole/blob/1792141307c3979b1f267af3e20cfc2f011d7051/solana/modules/token_bridge/program/src/api/transfer.rs#L159
|
||||
if !accs.custody.is_initialized() {
|
||||
|
@ -130,7 +163,16 @@ pub fn contribute_icco_sale(
|
|||
accs.contribution_state.create(&(&*accs).into(), ctx, accs.payer.key, Exempt)?;
|
||||
}
|
||||
|
||||
// TBD Do the from->custody non-WH transfer.
|
||||
// TBD Transfer tokens from->custody non-WH transfer.
|
||||
let transfer_ix = spl_token::instruction::transfer(
|
||||
&spl_token::id(),
|
||||
accs.from.info().key,
|
||||
accs.custody.info().key,
|
||||
accs.authority_signer.key,
|
||||
&[],
|
||||
data.amount,
|
||||
)?;
|
||||
invoke_seeded(&transfer_ix, ctx, &accs.authority_signer, None)?;
|
||||
|
||||
// store new amount.
|
||||
accs.contribution_state.amount = accs.contribution_state.amount + data.amount;
|
||||
|
|
|
@ -29,15 +29,11 @@ use crate::{
|
|||
SaleStateAccount,
|
||||
SaleStateDerivationData,
|
||||
},
|
||||
};
|
||||
|
||||
use crate:: {
|
||||
errors::Error::{
|
||||
VAAInvalidEmitterChain,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
use solana_program::msg;
|
||||
|
||||
use solana_program::{
|
||||
|
|
|
@ -9,6 +9,11 @@ pub enum Error {
|
|||
VAAAlreadyExecuted,
|
||||
VAAInvalidEmitterChain,
|
||||
VAAInvalid,
|
||||
InvalidTokenAddress,
|
||||
InvalidTokenIndex,
|
||||
SaleSealedOrAborted,
|
||||
SaleHasNotStarted,
|
||||
SaleHasEnded,
|
||||
}
|
||||
|
||||
/// Errors thrown by the program will bubble up to the solitaire wrapper, which needs a way to
|
||||
|
|
|
@ -41,8 +41,8 @@ fn read_u256(buf: &[u8]) -> (u128, u128) {
|
|||
#[derive(PartialEq, Debug)]
|
||||
#[allow(non_snake_case)]
|
||||
pub struct SaleInit {
|
||||
payload_id: u8, // Sale ID
|
||||
token_cnt: u8,
|
||||
payload_id: u8, // 1
|
||||
pub token_cnt: u8,
|
||||
pub sale_id: u128,
|
||||
}
|
||||
|
||||
|
|
|
@ -27,8 +27,8 @@ impl Owned for Config {
|
|||
/// icco sale state. Writeable in init, seal, abort.
|
||||
#[derive(Default, Clone, Copy, BorshDeserialize, BorshSerialize, Serialize, Deserialize)]
|
||||
pub struct SaleState {
|
||||
pub is_sealed: u8,
|
||||
pub is_aborted: u8,
|
||||
pub is_sealed: bool,
|
||||
pub is_aborted: bool,
|
||||
}
|
||||
|
||||
impl Owned for SaleState {
|
||||
|
@ -41,7 +41,7 @@ impl Owned for SaleState {
|
|||
/// icco contribution state. Writeable in contribute, redeem, refund.
|
||||
#[derive(Default, Clone, Copy, BorshDeserialize, BorshSerialize, Serialize, Deserialize)]
|
||||
pub struct ContributionState {
|
||||
pub amount: u128,
|
||||
pub amount: u64,
|
||||
pub is_redeemed_or_refunded: u8,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue