Skip to content

Commit

Permalink
Allow migration liquidity removal
Browse files Browse the repository at this point in the history
Change-Id: I9ec62ffa94b26ffd1776a2b76aa7586424a77b64
  • Loading branch information
chase-45 authored and hendrikhofstadt committed Sep 13, 2021
1 parent 9b106fb commit d8ad37d
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 12 deletions.
1 change: 1 addition & 0 deletions solana/migration/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod add_liquidity;
pub mod claim_shares;
pub mod create_pool;
pub mod migrate_tokens;
pub mod remove_liquidity;
3 changes: 2 additions & 1 deletion solana/migration/src/api/add_liquidity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 1 addition & 8 deletions solana/migration/src/api/claim_shares.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ use crate::{
ShareMintDerivationData,
ToCustodyTokenAccount,
},
types::{
SplAccount,
SplMint,
},
types::SplAccount,
MigrationError::WrongMint,
};
use borsh::{
Expand All @@ -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 }>>,

Expand All @@ -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());
}
Expand Down
1 change: 0 additions & 1 deletion solana/migration/src/api/create_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use borsh::{
};
use solana_program::program::invoke_signed;
use solitaire::{
processors::seeded::Seeded,
CreationLamports::Exempt,
*,
};
Expand Down
2 changes: 1 addition & 1 deletion solana/migration/src/api/migrate_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
117 changes: 117 additions & 0 deletions solana/migration/src/api/remove_liquidity.rs
Original file line number Diff line number Diff line change
@@ -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(())
}
54 changes: 53 additions & 1 deletion solana/migration/src/instructions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
claim_shares::ClaimSharesData,
create_pool::CreatePoolData,
migrate_tokens::MigrateTokensData,
remove_liquidity::RemoveLiquidityData,
},
};
use borsh::BorshSerialize;
Expand Down Expand Up @@ -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,
Expand All @@ -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 },
Expand Down
2 changes: 2 additions & 0 deletions solana/migration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use api::{
claim_shares::*,
create_pool::*,
migrate_tokens::*,
remove_liquidity::*,
};
use solitaire::{
solitaire,
Expand Down Expand Up @@ -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,
Expand Down
28 changes: 28 additions & 0 deletions solana/migration/src/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit d8ad37d

Please sign in to comment.