Allow migration liquidity removal

Change-Id: I9ec62ffa94b26ffd1776a2b76aa7586424a77b64
This commit is contained in:
Chase Moran 2021-09-13 13:17:45 -04:00 committed by Hendrik Hofstadt
parent 9b106fb7be
commit d8ad37d357
9 changed files with 205 additions and 12 deletions

View File

@ -2,3 +2,4 @@ pub mod add_liquidity;
pub mod claim_shares;
pub mod create_pool;
pub mod migrate_tokens;
pub mod remove_liquidity;

View File

@ -78,7 +78,8 @@ pub fn add_liquidity(
let to_tokens_in = if accs.from_mint.decimals > accs.to_mint.decimals {
data.amount
} else {
data.amount - (data.amount % 10u64.pow((accs.to_mint.decimals - accs.from_mint.decimals) as u32))
data.amount
- (data.amount % 10u64.pow((accs.to_mint.decimals - accs.from_mint.decimals) as u32))
};
// Transfer out-tokens in

View File

@ -8,10 +8,7 @@ use crate::{
ShareMintDerivationData,
ToCustodyTokenAccount,
},
types::{
SplAccount,
SplMint,
},
types::SplAccount,
MigrationError::WrongMint,
};
use borsh::{
@ -31,7 +28,6 @@ use solitaire::{
#[derive(FromAccounts)]
pub struct ClaimShares<'b> {
pub pool: Mut<MigrationPool<'b, { AccountState::Initialized }>>,
pub to_mint: Data<'b, SplMint, { AccountState::Initialized }>,
pub from_token_custody: Mut<ToCustodyTokenAccount<'b, { AccountState::Initialized }>>,
pub share_mint: Mut<ShareMint<'b, { AccountState::Initialized }>>,
@ -51,9 +47,6 @@ pub fn claim_shares(
accs: &mut ClaimShares,
data: ClaimSharesData,
) -> Result<()> {
if *accs.to_mint.info().key != accs.pool.to {
return Err(WrongMint.into());
}
if accs.lp_share_acc.mint != *accs.share_mint.info().key {
return Err(WrongMint.into());
}

View File

@ -18,7 +18,6 @@ use borsh::{
};
use solana_program::program::invoke_signed;
use solitaire::{
processors::seeded::Seeded,
CreationLamports::Exempt,
*,
};

View File

@ -95,7 +95,7 @@ pub fn migrate_tokens(
)?;
invoke_seeded(&transfer_ix, ctx, &accs.authority_signer, None)?;
// The share amount should be equal to the amount of from tokens an lp would be getting
// The out amount needs to be decimal adjusted
let out_amount = if accs.from_mint.decimals > accs.to_mint.decimals {
data.amount
.checked_div(10u64.pow((accs.from_mint.decimals - accs.to_mint.decimals) as u32))

View File

@ -0,0 +1,117 @@
use crate::{
accounts::{
AuthoritySigner,
CustodySigner,
MigrationPool,
MigrationPoolDerivationData,
ShareMint,
ShareMintDerivationData,
ToCustodyTokenAccount,
ToCustodyTokenAccountDerivationData,
},
types::{
SplAccount,
SplMint,
},
MigrationError::WrongMint,
};
use borsh::{
BorshDeserialize,
BorshSerialize,
};
use solitaire::{
processors::seeded::{
invoke_seeded,
Seeded,
},
*,
};
#[derive(FromAccounts)]
pub struct RemoveLiquidity<'b> {
pub pool: Mut<MigrationPool<'b, { AccountState::Initialized }>>,
pub from_mint: Data<'b, SplMint, { AccountState::Initialized }>,
pub to_mint: Data<'b, SplMint, { AccountState::Initialized }>,
pub to_token_custody: Mut<ToCustodyTokenAccount<'b, { AccountState::Initialized }>>,
pub share_mint: Mut<ShareMint<'b, { AccountState::Initialized }>>,
pub to_lp_acc: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
pub lp_share_acc: Mut<Data<'b, SplAccount, { AccountState::Initialized }>>,
pub custody_signer: CustodySigner<'b>,
pub authority_signer: AuthoritySigner<'b>,
}
#[derive(BorshDeserialize, BorshSerialize, Default)]
pub struct RemoveLiquidityData {
pub amount: u64,
}
pub fn remove_liquidity(
ctx: &ExecutionContext,
accs: &mut RemoveLiquidity,
data: RemoveLiquidityData,
) -> Result<()> {
if *accs.from_mint.info().key != accs.pool.from {
return Err(WrongMint.into());
}
if *accs.to_mint.info().key != accs.pool.to {
return Err(WrongMint.into());
}
if accs.lp_share_acc.mint != *accs.share_mint.info().key {
return Err(WrongMint.into());
}
accs.to_token_custody.verify_derivation(
ctx.program_id,
&ToCustodyTokenAccountDerivationData {
pool: *accs.pool.info().key,
},
)?;
accs.share_mint.verify_derivation(
ctx.program_id,
&ShareMintDerivationData {
pool: *accs.pool.info().key,
},
)?;
accs.pool.verify_derivation(
ctx.program_id,
&MigrationPoolDerivationData {
from: accs.pool.from,
to: accs.pool.to,
},
)?;
// The out amount needs to be decimal adjusted
let out_amount = if accs.from_mint.decimals > accs.to_mint.decimals {
data.amount
.checked_div(10u64.pow((accs.from_mint.decimals - accs.to_mint.decimals) as u32))
.unwrap()
} else {
data.amount
.checked_mul(10u64.pow((accs.to_mint.decimals - accs.from_mint.decimals) as u32))
.unwrap()
};
// Transfer removed liquidity to LP
let transfer_ix = spl_token::instruction::transfer(
&spl_token::id(),
accs.to_token_custody.info().key,
accs.to_lp_acc.info().key,
accs.custody_signer.key,
&[],
out_amount,
)?;
invoke_seeded(&transfer_ix, ctx, &accs.custody_signer, None)?;
// Burn LP shares
let mint_ix = spl_token::instruction::burn(
&spl_token::id(),
accs.lp_share_acc.info().key,
accs.share_mint.info().key,
accs.authority_signer.key,
&[],
data.amount,
)?;
invoke_seeded(&mint_ix, ctx, &accs.authority_signer, None)?;
Ok(())
}

View File

@ -16,6 +16,7 @@ use crate::{
claim_shares::ClaimSharesData,
create_pool::CreatePoolData,
migrate_tokens::MigrateTokensData,
remove_liquidity::RemoveLiquidityData,
},
};
use borsh::BorshSerialize;
@ -83,6 +84,58 @@ pub fn add_liquidity(
})
}
pub fn remove_liquidity(
program_id: Pubkey,
from_mint: Pubkey,
to_mint: Pubkey,
liquidity_token_account: Pubkey,
lp_share_token_account: Pubkey,
amount: u64,
) -> solitaire::Result<Instruction> {
let pool = MigrationPool::<'_, { AccountState::Initialized }>::key(
&MigrationPoolDerivationData {
from: from_mint,
to: to_mint,
},
&program_id,
);
Ok(Instruction {
program_id,
accounts: vec![
AccountMeta::new(pool, false),
AccountMeta::new_readonly(from_mint, false),
AccountMeta::new_readonly(to_mint, false),
AccountMeta::new(
ToCustodyTokenAccount::<'_, { AccountState::Uninitialized }>::key(
&ToCustodyTokenAccountDerivationData { pool },
&program_id,
),
false,
),
AccountMeta::new(
ShareMint::<'_, { AccountState::Uninitialized }>::key(
&ShareMintDerivationData { pool },
&program_id,
),
false,
),
AccountMeta::new(liquidity_token_account, false),
AccountMeta::new(lp_share_token_account, false),
AccountMeta::new_readonly(CustodySigner::key(None, &program_id), false),
AccountMeta::new_readonly(AuthoritySigner::key(None, &program_id), false),
// Dependencies
AccountMeta::new(solana_program::sysvar::rent::id(), false),
AccountMeta::new(solana_program::system_program::id(), false),
AccountMeta::new_readonly(spl_token::id(), false),
],
data: (
crate::instruction::Instruction::RemoveLiquidity,
RemoveLiquidityData { amount },
)
.try_to_vec()?,
})
}
pub fn claim_shares(
program_id: Pubkey,
from_mint: Pubkey,
@ -102,7 +155,6 @@ pub fn claim_shares(
program_id,
accounts: vec![
AccountMeta::new(pool, false),
AccountMeta::new_readonly(to_mint, false),
AccountMeta::new(
FromCustodyTokenAccount::<'_, { AccountState::Uninitialized }>::key(
&FromCustodyTokenAccountDerivationData { pool },

View File

@ -6,6 +6,7 @@ use api::{
claim_shares::*,
create_pool::*,
migrate_tokens::*,
remove_liquidity::*,
};
use solitaire::{
solitaire,
@ -39,6 +40,7 @@ impl From<MigrationError> for SolitaireError {
solitaire! {
AddLiquidity(AddLiquidityData) => add_liquidity,
RemoveLiquidity(RemoveLiquidityData) => remove_liquidity,
ClaimShares(ClaimSharesData) => claim_shares,
CreatePool(CreatePoolData) => create_pool,
MigrateTokens(MigrateTokensData) => migrate_tokens,

View File

@ -50,6 +50,34 @@ pub fn add_liquidity(
JsValue::from_serde(&ix).unwrap()
}
#[wasm_bindgen]
pub fn remove_liquidity(
program_id: String,
from_mint: String,
to_mint: String,
liquidity_token_account: String,
lp_share_token_account: String,
amount: u64,
) -> JsValue {
let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
let from_mint = Pubkey::from_str(from_mint.as_str()).unwrap();
let to_mint = Pubkey::from_str(to_mint.as_str()).unwrap();
let liquidity_token_account = Pubkey::from_str(liquidity_token_account.as_str()).unwrap();
let lp_share_token_account = Pubkey::from_str(lp_share_token_account.as_str()).unwrap();
let ix = instructions::remove_liquidity(
program_id,
from_mint,
to_mint,
liquidity_token_account,
lp_share_token_account,
amount,
)
.unwrap();
JsValue::from_serde(&ix).unwrap()
}
#[wasm_bindgen]
pub fn claim_shares(
program_id: String,