Stake pool improvements and fixes (#665)
* Added address type in programm address generation for the stake pool, renamed nonce to bump seed * Formatting fixed * Bump seed calculation moved to the smart contract, test for fee > 1 added, state length public constant added * Added claim method to stake pool, fixed program address generation in token mint and burn calls * Refactored signers management when calling other contracts * Signers formation put back into calling functions, deposit/withdraw/claim method reworked, state serialization bug fixed
This commit is contained in:
parent
5ceeefca5a
commit
df63d6a0f0
|
@ -40,6 +40,9 @@ pub enum Error {
|
|||
/// The calculation failed.
|
||||
#[error("CalculationFailure")]
|
||||
CalculationFailure,
|
||||
/// Stake pool fee > 1.
|
||||
#[error("FeeTooHigh")]
|
||||
FeeTooHigh,
|
||||
}
|
||||
impl From<Error> for ProgramError {
|
||||
fn from(e: Error) -> Self {
|
||||
|
|
|
@ -25,11 +25,6 @@ pub struct Fee {
|
|||
pub struct InitArgs {
|
||||
/// Fee paid to the owner in pool tokens
|
||||
pub fee: Fee,
|
||||
/// Nonce used for the deposit program address
|
||||
pub deposit_bump_seed: u8,
|
||||
/// Nonce used for the withdraw program address
|
||||
/// This program address is used as the stake withdraw key as well
|
||||
pub withdraw_bump_seed: u8,
|
||||
}
|
||||
|
||||
/// Instructions supported by the StakePool program.
|
||||
|
@ -48,29 +43,42 @@ pub enum StakePoolInstruction {
|
|||
/// Deposit some stake into the pool. The output is a "pool" token representing ownership
|
||||
/// into the pool. Inputs are converted to the current ratio.
|
||||
///
|
||||
/// 0. `[]` StakePool
|
||||
/// 1. `[]` deposit authority
|
||||
/// 2. `[]` withdraw authority
|
||||
/// 3. `[w]` Stake, deposit authority is set as the withdrawal key
|
||||
/// 4. `[w]` Pool MINT account, authority is the owner.
|
||||
/// 5. `[w]` Pool Account to deposit the generated tokens.
|
||||
/// 6. `[w]` Pool Account to deposit the generated fee for owner.
|
||||
/// 7. `[]` Token program id
|
||||
/// 0. `[w]` Stake pool
|
||||
/// 1. `[]` Stake pool deposit authority
|
||||
/// 2. `[]` Stake pool withdraw authority
|
||||
/// 3. `[w]` Stake account to join the pool (withdraw should be set to stake pool deposit)
|
||||
/// 4. `[w]` User account to receive pool tokens
|
||||
/// 5. `[w]` Account to receive pool fee tokens
|
||||
/// 6. `[w]` Pool token mint account
|
||||
/// 7. `[]` Pool token program id
|
||||
Deposit,
|
||||
|
||||
/// Withdraw the token from the pool at the current ratio.
|
||||
/// The amount withdrawn is the MIN(u64, stake size)
|
||||
///
|
||||
/// 0. `[]` StakePool
|
||||
/// 1. `[]` withdraw authority
|
||||
/// 2. `[w]` SOURCE Pool account, amount is transferable by authority
|
||||
/// 3. `[w]` Pool MINT account, authority is the owner
|
||||
/// 4. `[w]` Stake SOURCE owned by the withdraw authority
|
||||
/// 6. `[w]` Stake destination, uninitialized, for the user stake
|
||||
/// 7. `[]` Token program id
|
||||
/// 0. `[w]` Stake pool
|
||||
/// 1. `[]` Stake pool withdraw authority
|
||||
/// 2. `[w]` Stake account to split
|
||||
/// 3. `[w]` Unitialized stake account to receive withdrawal
|
||||
/// 4. `[]` User account to set as a new withdraw authority
|
||||
/// 5. `[w]` User account with pool tokens to burn from
|
||||
/// 6. `[w]` Pool token mint account
|
||||
/// 7. `[]` Pool token program id
|
||||
/// userdata: amount to withdraw
|
||||
Withdraw(u64),
|
||||
|
||||
/// Claim ownership of a whole stake account.
|
||||
/// Also burns enough tokens to make up for the stake account balance
|
||||
///
|
||||
/// 0. `[w]` Stake pool
|
||||
/// 1. `[]` Stake pool withdraw authority
|
||||
/// 2. `[w]` Stake account to claim
|
||||
/// 3. `[]` User account to set as a new withdraw authority
|
||||
/// 4. `[w]` User account with pool tokens to burn from
|
||||
/// 5. `[w]` Pool token mint account
|
||||
/// 6. `[]` Pool token program id
|
||||
Claim,
|
||||
|
||||
/// Update the staking pubkey for a stake
|
||||
///
|
||||
/// 0. `[w]` StakePool
|
||||
|
@ -106,8 +114,9 @@ impl StakePoolInstruction {
|
|||
let val: &u64 = unpack(input)?;
|
||||
Self::Withdraw(*val)
|
||||
}
|
||||
3 => Self::SetStakingAuthority,
|
||||
4 => Self::SetOwner,
|
||||
3 => Self::Claim,
|
||||
4 => Self::SetStakingAuthority,
|
||||
5 => Self::SetOwner,
|
||||
_ => return Err(ProgramError::InvalidAccountData),
|
||||
})
|
||||
}
|
||||
|
@ -132,12 +141,15 @@ impl StakePoolInstruction {
|
|||
let value = unsafe { &mut *(&mut output[1] as *mut u8 as *mut u64) };
|
||||
*value = *val;
|
||||
}
|
||||
Self::SetStakingAuthority => {
|
||||
Self::Claim => {
|
||||
output[0] = 3;
|
||||
}
|
||||
Self::SetOwner => {
|
||||
Self::SetStakingAuthority => {
|
||||
output[0] = 4;
|
||||
}
|
||||
Self::SetOwner => {
|
||||
output[0] = 5;
|
||||
}
|
||||
}
|
||||
Ok(output)
|
||||
}
|
||||
|
|
|
@ -40,18 +40,29 @@ impl Processor {
|
|||
)
|
||||
.or(Err(Error::InvalidProgramAddress))
|
||||
}
|
||||
/// Generates seed bump for stake pool authorities
|
||||
pub fn find_authority_bump_seed(
|
||||
program_id: &Pubkey,
|
||||
my_info: &Pubkey,
|
||||
authority_type: &[u8],
|
||||
) -> u8 {
|
||||
let (_pubkey, bump_seed) =
|
||||
Pubkey::find_program_address(&[&my_info.to_bytes()[..32], authority_type], program_id);
|
||||
bump_seed
|
||||
}
|
||||
|
||||
/// Issue a stake_split instruction.
|
||||
pub fn stake_split<'a>(
|
||||
stake_pool: &Pubkey,
|
||||
stake_account: AccountInfo<'a>,
|
||||
authority: AccountInfo<'a>,
|
||||
nonce: u8,
|
||||
authority_type: &[u8],
|
||||
bump_seed: u8,
|
||||
amount: u64,
|
||||
split_stake: AccountInfo<'a>,
|
||||
) -> Result<(), ProgramError> {
|
||||
let me_bytes = stake_pool.to_bytes();
|
||||
let authority_signature_seeds = [&me_bytes[..32], &[nonce]];
|
||||
let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]];
|
||||
let signers = &[&authority_signature_seeds[..]];
|
||||
|
||||
let ix = stake::split_only(stake_account.key, authority.key, amount, split_stake.key);
|
||||
|
@ -64,12 +75,13 @@ impl Processor {
|
|||
stake_pool: &Pubkey,
|
||||
stake_account: AccountInfo<'a>,
|
||||
authority: AccountInfo<'a>,
|
||||
nonce: u8,
|
||||
authority_type: &[u8],
|
||||
bump_seed: u8,
|
||||
new_staker: &Pubkey,
|
||||
staker_auth: stake::StakeAuthorize,
|
||||
) -> Result<(), ProgramError> {
|
||||
let me_bytes = stake_pool.to_bytes();
|
||||
let authority_signature_seeds = [&me_bytes[..32], &[nonce]];
|
||||
let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]];
|
||||
let signers = &[&authority_signature_seeds[..]];
|
||||
|
||||
let ix = stake::authorize(stake_account.key, authority.key, new_staker, staker_auth);
|
||||
|
@ -78,17 +90,19 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Issue a spl_token `Burn` instruction.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn token_burn<'a>(
|
||||
stake_pool: &Pubkey,
|
||||
token_program: AccountInfo<'a>,
|
||||
burn_account: AccountInfo<'a>,
|
||||
mint: AccountInfo<'a>,
|
||||
authority: AccountInfo<'a>,
|
||||
nonce: u8,
|
||||
authority_type: &[u8],
|
||||
bump_seed: u8,
|
||||
amount: u64,
|
||||
) -> Result<(), ProgramError> {
|
||||
let me_bytes = stake_pool.to_bytes();
|
||||
let authority_signature_seeds = [&me_bytes[..32], &[nonce]];
|
||||
let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]];
|
||||
let signers = &[&authority_signature_seeds[..]];
|
||||
|
||||
let ix = spl_token::instruction::burn(
|
||||
|
@ -108,18 +122,21 @@ impl Processor {
|
|||
}
|
||||
|
||||
/// Issue a spl_token `MintTo` instruction.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn token_mint_to<'a>(
|
||||
stake_pool: &Pubkey,
|
||||
token_program: AccountInfo<'a>,
|
||||
mint: AccountInfo<'a>,
|
||||
destination: AccountInfo<'a>,
|
||||
authority: AccountInfo<'a>,
|
||||
nonce: u8,
|
||||
authority_type: &[u8],
|
||||
bump_seed: u8,
|
||||
amount: u64,
|
||||
) -> Result<(), ProgramError> {
|
||||
let me_bytes = stake_pool.to_bytes();
|
||||
let authority_signature_seeds = [&me_bytes[..32], &[nonce]];
|
||||
let authority_signature_seeds = [&me_bytes[..32], authority_type, &[bump_seed]];
|
||||
let signers = &[&authority_signature_seeds[..]];
|
||||
|
||||
let ix = spl_token::instruction::mint_to(
|
||||
token_program.key,
|
||||
mint.key,
|
||||
|
@ -134,7 +151,7 @@ impl Processor {
|
|||
|
||||
/// Processes an [Initialize](enum.Instruction.html).
|
||||
pub fn process_initialize(
|
||||
_program_id: &Pubkey,
|
||||
program_id: &Pubkey,
|
||||
init: InitArgs,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
|
@ -145,14 +162,28 @@ impl Processor {
|
|||
let owner_fee_info = next_account_info(account_info_iter)?;
|
||||
let token_program_info = next_account_info(account_info_iter)?;
|
||||
|
||||
// Stake pool account should not be already initialized
|
||||
if State::Unallocated != State::deserialize(&stake_pool_info.data.borrow())? {
|
||||
return Err(Error::AlreadyInUse.into());
|
||||
}
|
||||
|
||||
// Numerator should be smaller than or equal to denominator (fee <= 1)
|
||||
if init.fee.numerator > init.fee.denominator {
|
||||
return Err(Error::FeeTooHigh.into());
|
||||
}
|
||||
|
||||
let stake_pool = State::Init(StakePool {
|
||||
owner: *owner_info.key,
|
||||
deposit_bump_seed: init.deposit_bump_seed,
|
||||
withdraw_bump_seed: init.withdraw_bump_seed,
|
||||
deposit_bump_seed: Self::find_authority_bump_seed(
|
||||
program_id,
|
||||
stake_pool_info.key,
|
||||
Self::AUTHORITY_DEPOSIT,
|
||||
),
|
||||
withdraw_bump_seed: Self::find_authority_bump_seed(
|
||||
program_id,
|
||||
stake_pool_info.key,
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
),
|
||||
pool_mint: *pool_mint_info.key,
|
||||
owner_fee_account: *owner_fee_info.key,
|
||||
token_program_id: *token_program_info.key,
|
||||
|
@ -163,16 +194,24 @@ impl Processor {
|
|||
stake_pool.serialize(&mut stake_pool_info.data.borrow_mut())
|
||||
}
|
||||
|
||||
/// Processes an [Withdraw](enum.Instruction.html).
|
||||
/// Processes [Deposit](enum.Instruction.html).
|
||||
pub fn process_deposit(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||
let account_info_iter = &mut accounts.iter();
|
||||
// Stake pool
|
||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||
// Stake pool deposit authority
|
||||
let deposit_info = next_account_info(account_info_iter)?;
|
||||
// Stake pool withdraw authority
|
||||
let withdraw_info = next_account_info(account_info_iter)?;
|
||||
// Stake account to join the pool (withdraw should be set to stake pool deposit)
|
||||
let stake_info = next_account_info(account_info_iter)?;
|
||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||
// User account to receive pool tokens
|
||||
let dest_user_info = next_account_info(account_info_iter)?;
|
||||
// Account to receive pool fee tokens
|
||||
let owner_fee_info = next_account_info(account_info_iter)?;
|
||||
// Pool token mint account
|
||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||
// Pool token program id
|
||||
let token_program_info = next_account_info(account_info_iter)?;
|
||||
|
||||
let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?;
|
||||
|
@ -223,6 +262,7 @@ impl Processor {
|
|||
stake_pool_info.key,
|
||||
stake_info.clone(),
|
||||
deposit_info.clone(),
|
||||
Self::AUTHORITY_DEPOSIT,
|
||||
stake_pool.deposit_bump_seed,
|
||||
withdraw_info.key,
|
||||
stake::StakeAuthorize::Withdrawer,
|
||||
|
@ -235,7 +275,8 @@ impl Processor {
|
|||
pool_mint_info.clone(),
|
||||
dest_user_info.clone(),
|
||||
withdraw_info.clone(),
|
||||
stake_pool.withdraw_bump_seed,
|
||||
Self::AUTHORITY_DEPOSIT,
|
||||
stake_pool.deposit_bump_seed,
|
||||
user_amount,
|
||||
)?;
|
||||
let fee_amount = <u64>::try_from(fee_amount).or(Err(Error::CalculationFailure))?;
|
||||
|
@ -245,6 +286,7 @@ impl Processor {
|
|||
pool_mint_info.clone(),
|
||||
owner_fee_info.clone(),
|
||||
withdraw_info.clone(),
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
fee_amount as u64,
|
||||
)?;
|
||||
|
@ -255,19 +297,28 @@ impl Processor {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Processes an [Withdraw](enum.Instruction.html).
|
||||
/// Processes [Withdraw](enum.Instruction.html).
|
||||
pub fn process_withdraw(
|
||||
program_id: &Pubkey,
|
||||
stake_amount: u64,
|
||||
accounts: &[AccountInfo],
|
||||
) -> ProgramResult {
|
||||
let account_info_iter = &mut accounts.iter();
|
||||
// Stake pool
|
||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||
// Stake pool withdraw authority
|
||||
let withdraw_info = next_account_info(account_info_iter)?;
|
||||
let source_info = next_account_info(account_info_iter)?;
|
||||
// Stake account to split
|
||||
let stake_split_from = next_account_info(account_info_iter)?;
|
||||
// Unitialized stake account to receive withdrawal
|
||||
let stake_split_to = next_account_info(account_info_iter)?;
|
||||
// User account to set as a new withdraw authority
|
||||
let user_stake_authority = next_account_info(account_info_iter)?;
|
||||
// User account with pool tokens to burn from
|
||||
let burn_from_info = next_account_info(account_info_iter)?;
|
||||
// Pool token mint account
|
||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||
let stake_info = next_account_info(account_info_iter)?;
|
||||
let dest_user_info = next_account_info(account_info_iter)?;
|
||||
// Pool token program id
|
||||
let token_program_info = next_account_info(account_info_iter)?;
|
||||
|
||||
let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?;
|
||||
|
@ -293,28 +344,31 @@ impl Processor {
|
|||
|
||||
Self::stake_split(
|
||||
stake_pool_info.key,
|
||||
source_info.clone(),
|
||||
stake_split_from.clone(),
|
||||
withdraw_info.clone(),
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
stake_amount,
|
||||
stake_info.clone(),
|
||||
stake_split_to.clone(),
|
||||
)?;
|
||||
|
||||
Self::stake_authorize(
|
||||
stake_pool_info.key,
|
||||
stake_info.clone(),
|
||||
stake_split_to.clone(),
|
||||
withdraw_info.clone(),
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
dest_user_info.key,
|
||||
user_stake_authority.key,
|
||||
stake::StakeAuthorize::Withdrawer,
|
||||
)?;
|
||||
|
||||
Self::token_burn(
|
||||
stake_pool_info.key,
|
||||
token_program_info.clone(),
|
||||
source_info.clone(),
|
||||
burn_from_info.clone(),
|
||||
pool_mint_info.clone(),
|
||||
withdraw_info.clone(),
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
pool_amount,
|
||||
)?;
|
||||
|
@ -324,7 +378,73 @@ impl Processor {
|
|||
State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?;
|
||||
Ok(())
|
||||
}
|
||||
/// Processes an [SetStakeAuthority](enum.Instruction.html).
|
||||
/// Processes [Claim](enum.Instruction.html).
|
||||
pub fn process_claim(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||
let account_info_iter = &mut accounts.iter();
|
||||
// Stake pool
|
||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||
// Stake pool withdraw authority
|
||||
let withdraw_info = next_account_info(account_info_iter)?;
|
||||
// Stake account to claim
|
||||
let stake_to_claim = next_account_info(account_info_iter)?;
|
||||
// User account to set as a new withdraw authority
|
||||
let user_stake_authority = next_account_info(account_info_iter)?;
|
||||
// User account with pool tokens to burn from
|
||||
let burn_from_info = next_account_info(account_info_iter)?;
|
||||
// Pool token account
|
||||
let pool_mint_info = next_account_info(account_info_iter)?;
|
||||
// Pool token program id
|
||||
let token_program_info = next_account_info(account_info_iter)?;
|
||||
|
||||
let mut stake_pool = State::deserialize(&stake_pool_info.data.borrow())?.stake_pool()?;
|
||||
|
||||
if *withdraw_info.key
|
||||
!= Self::authority_id(
|
||||
program_id,
|
||||
stake_pool_info.key,
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
)?
|
||||
{
|
||||
return Err(Error::InvalidProgramAddress.into());
|
||||
}
|
||||
if stake_pool.token_program_id != *token_program_info.key {
|
||||
return Err(Error::InvalidInput.into());
|
||||
}
|
||||
|
||||
let stake_amount = **stake_to_claim.lamports.borrow();
|
||||
let pool_amount = stake_pool
|
||||
.calc_pool_withdraw_amount(stake_amount)
|
||||
.ok_or(Error::CalculationFailure)?;
|
||||
let pool_amount = <u64>::try_from(pool_amount).or(Err(Error::CalculationFailure))?;
|
||||
|
||||
Self::stake_authorize(
|
||||
stake_pool_info.key,
|
||||
stake_to_claim.clone(),
|
||||
withdraw_info.clone(),
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
user_stake_authority.key,
|
||||
stake::StakeAuthorize::Withdrawer,
|
||||
)?;
|
||||
|
||||
Self::token_burn(
|
||||
stake_pool_info.key,
|
||||
token_program_info.clone(),
|
||||
burn_from_info.clone(),
|
||||
pool_mint_info.clone(),
|
||||
withdraw_info.clone(),
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
pool_amount,
|
||||
)?;
|
||||
|
||||
stake_pool.pool_total -= pool_amount;
|
||||
stake_pool.stake_total -= stake_amount;
|
||||
State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?;
|
||||
Ok(())
|
||||
}
|
||||
/// Processes [SetStakeAuthority](enum.Instruction.html).
|
||||
pub fn process_set_staking_auth(
|
||||
program_id: &Pubkey,
|
||||
accounts: &[AccountInfo],
|
||||
|
@ -355,10 +475,12 @@ impl Processor {
|
|||
{
|
||||
return Err(Error::InvalidProgramAddress.into());
|
||||
}
|
||||
|
||||
Self::stake_authorize(
|
||||
stake_info.key,
|
||||
stake_pool_info.key,
|
||||
stake_info.clone(),
|
||||
withdraw_info.clone(),
|
||||
Self::AUTHORITY_WITHDRAW,
|
||||
stake_pool.withdraw_bump_seed,
|
||||
staker_info.key,
|
||||
stake::StakeAuthorize::Staker,
|
||||
|
@ -366,7 +488,7 @@ impl Processor {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Processes an [SetOwner](enum.Instruction.html).
|
||||
/// Processes [SetOwner](enum.Instruction.html).
|
||||
pub fn process_set_owner(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||
let account_info_iter = &mut accounts.iter();
|
||||
let stake_pool_info = next_account_info(account_info_iter)?;
|
||||
|
@ -387,7 +509,7 @@ impl Processor {
|
|||
State::Init(stake_pool).serialize(&mut stake_pool_info.data.borrow_mut())?;
|
||||
Ok(())
|
||||
}
|
||||
/// Processes an [Instruction](enum.Instruction.html).
|
||||
/// Processes [Instruction](enum.Instruction.html).
|
||||
pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult {
|
||||
let instruction = StakePoolInstruction::deserialize(input)?;
|
||||
match instruction {
|
||||
|
@ -403,6 +525,10 @@ impl Processor {
|
|||
info!("Instruction: Withdraw");
|
||||
Self::process_withdraw(program_id, amount, accounts)
|
||||
}
|
||||
StakePoolInstruction::Claim => {
|
||||
info!("Instruction: Claim");
|
||||
Self::process_claim(program_id, accounts)
|
||||
}
|
||||
StakePoolInstruction::SetStakingAuthority => {
|
||||
info!("Instruction: SetStakingAuthority");
|
||||
Self::process_set_staking_auth(program_id, accounts)
|
||||
|
@ -476,6 +602,7 @@ impl PrintProgramError for Error {
|
|||
Error::InvalidInput => info!("Error: InvalidInput"),
|
||||
Error::InvalidOutput => info!("Error: InvalidOutput"),
|
||||
Error::CalculationFailure => info!("Error: CalculationFailure"),
|
||||
Error::FeeTooHigh => info!("Error: FeeTooHigh"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -627,10 +754,8 @@ mod tests {
|
|||
&pool_token_key,
|
||||
&TOKEN_PROGRAM_ID,
|
||||
InitArgs {
|
||||
deposit_bump_seed: 0,
|
||||
withdraw_bump_seed: 0,
|
||||
fee: Fee {
|
||||
denominator: 1,
|
||||
denominator: 10,
|
||||
numerator: 2,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -12,10 +12,10 @@ pub struct StakePool {
|
|||
/// Owner authority
|
||||
/// allows for updating the staking authority
|
||||
pub owner: Pubkey,
|
||||
/// Deposit authority nonce
|
||||
/// Deposit authority bump seed
|
||||
/// for `create_program_address(&[state::StakePool account, "deposit"])`
|
||||
pub deposit_bump_seed: u8,
|
||||
/// Withdrawal authority nonce
|
||||
/// Withdrawal authority bump seed
|
||||
/// for `create_program_address(&[state::StakePool account, "withdrawal"])`
|
||||
pub withdraw_bump_seed: u8,
|
||||
/// Pool Mint
|
||||
|
@ -67,6 +67,8 @@ pub enum State {
|
|||
}
|
||||
|
||||
impl State {
|
||||
/// Length of state data when serialized
|
||||
pub const LEN: usize = size_of::<u8>() + size_of::<StakePool>();
|
||||
/// Deserializes a byte buffer into a [State](struct.State.html).
|
||||
/// TODO efficient unpacking here
|
||||
pub fn deserialize(input: &[u8]) -> Result<State, ProgramError> {
|
||||
|
@ -76,7 +78,7 @@ impl State {
|
|||
Ok(match input[0] {
|
||||
0 => State::Unallocated,
|
||||
1 => {
|
||||
let swap: &StakePool = unpack(input)?;
|
||||
let swap: &StakePool = unpack(&input[1..])?;
|
||||
State::Init(*swap)
|
||||
}
|
||||
_ => return Err(ProgramError::InvalidAccountData),
|
||||
|
|
Loading…
Reference in New Issue