From 6d8e90ff5ec2dce7032eaab1f51855a14eecac4f Mon Sep 17 00:00:00 2001 From: Alvin Philips Date: Tue, 15 Nov 2022 05:00:26 +0530 Subject: [PATCH 1/7] feat: Added Lido program --- Cargo.lock | 8 ++++++++ programs/adapter-lido/Cargo.toml | 19 ++++++++++++++++++ programs/adapter-lido/Xargo.toml | 2 ++ programs/adapter-lido/src/lib.rs | 34 ++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 programs/adapter-lido/Cargo.toml create mode 100644 programs/adapter-lido/Xargo.toml create mode 100644 programs/adapter-lido/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index c643f19..15fc658 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,6 +34,14 @@ dependencies = [ "anchor-spl", ] +[[package]] +name = "adapter-lido" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "anchor-spl", +] + [[package]] name = "adapter-lifinity" version = "0.1.0" diff --git a/programs/adapter-lido/Cargo.toml b/programs/adapter-lido/Cargo.toml new file mode 100644 index 0000000..eaa3996 --- /dev/null +++ b/programs/adapter-lido/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "adapter-lido" +version = "0.1.0" +description = "Created with Anchor" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] +name = "adapter_lido" + +[features] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] + +[dependencies] +anchor-lang = "0.24.2" +anchor-spl = "0.24.2" diff --git a/programs/adapter-lido/Xargo.toml b/programs/adapter-lido/Xargo.toml new file mode 100644 index 0000000..475fb71 --- /dev/null +++ b/programs/adapter-lido/Xargo.toml @@ -0,0 +1,2 @@ +[target.bpfel-unknown-unknown.dependencies.std] +features = [] diff --git a/programs/adapter-lido/src/lib.rs b/programs/adapter-lido/src/lib.rs new file mode 100644 index 0000000..8a7c60c --- /dev/null +++ b/programs/adapter-lido/src/lib.rs @@ -0,0 +1,34 @@ +use anchor_lang::prelude::*; +use anchor_lang::solana_program::{ + hash::hash, + instruction::{AccountMeta, Instruction}, + program::invoke, + pubkey::Pubkey, +}; +use anchor_spl::token::{Mint, TokenAccount}; + +declare_id!("ADPTPxbHbEBo9A8E53P2PZnmw3ZYJuwc8ArQQkbJtqhx"); + +#[program] +pub mod adapter_lido { + use super::*; + + pub fn deposit<'a, 'b, 'c, 'info>( + ctx: Context<'a, 'b, 'c, 'info, Action<'info>>, + input: Vec, + ) -> Result<()> { + // Get Input + let mut input_bytes = &input[..]; + let input_struct = DepositInputWrapper::deserialize(&mut input_bytes)?; + + msg!("Input: {:?}", input_struct); + + // Deriving keys + Ok(()) + } +} + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, Default)] +pub struct DepositInputWrapper { + pub amount: u64, +} From 2d93ec9a2a9f81ca788207a6cd6cbeb5d29a2213 Mon Sep 17 00:00:00 2001 From: Alvin Philips Date: Mon, 21 Nov 2022 20:18:16 +0530 Subject: [PATCH 2/7] Deployed Lido Adapter --- Anchor.toml | 1 + programs/adapter-lido/src/lib.rs | 94 ++++++++++++++- target/idl/adapter_lido.json | 99 ++++++++++++++++ target/types/adapter_lido.ts | 193 +++++++++++++++++++++++++++++++ 4 files changed, 385 insertions(+), 2 deletions(-) create mode 100644 target/idl/adapter_lido.json create mode 100644 target/types/adapter_lido.ts diff --git a/Anchor.toml b/Anchor.toml index f397419..54a4ce1 100644 --- a/Anchor.toml +++ b/Anchor.toml @@ -10,6 +10,7 @@ adapter_katana = "ADPTwDKJTizC3V8gZXDxt5uLjJv4pBnh1nTTf9dZJnS2" adapter_tulip = "ADPT9nhC1asRcEB13FKymLTatqWGCuZHDznGgnakWKxW" adapter_friktion = "ADPTzbsaBdXA3FqXoPHjaTjPfh9kadxxFKxonZihP1Ji" adapter_nft_finance = "ADPTyBr92sBCE1hdYBRvXbMpF4hKs17xyDjFPxopcsrh" +adapter_lido = "ADPTPxbHbEBo9A8E53P2PZnmw3ZYJuwc8ArQQkbJtqhx" [registry] url = "https://anchor.projectserum.com" diff --git a/programs/adapter-lido/src/lib.rs b/programs/adapter-lido/src/lib.rs index 8a7c60c..c9ed631 100644 --- a/programs/adapter-lido/src/lib.rs +++ b/programs/adapter-lido/src/lib.rs @@ -1,6 +1,5 @@ use anchor_lang::prelude::*; use anchor_lang::solana_program::{ - hash::hash, instruction::{AccountMeta, Instruction}, program::invoke, pubkey::Pubkey, @@ -11,6 +10,8 @@ declare_id!("ADPTPxbHbEBo9A8E53P2PZnmw3ZYJuwc8ArQQkbJtqhx"); #[program] pub mod adapter_lido { + use anchor_lang::solana_program::{account_info::next_account_infos, stake}; + use super::*; pub fn deposit<'a, 'b, 'c, 'info>( @@ -22,13 +23,102 @@ pub mod adapter_lido { let input_struct = DepositInputWrapper::deserialize(&mut input_bytes)?; msg!("Input: {:?}", input_struct); + + let deposit_accounts = vec![ + AccountMeta::new(ctx.remaining_accounts[0].key(), false), + AccountMeta::new(ctx.remaining_accounts[1].key(), true), + AccountMeta::new(ctx.remaining_accounts[2].key(), false), + AccountMeta::new(ctx.remaining_accounts[3].key(), false), + AccountMeta::new(ctx.remaining_accounts[4].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[5].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[6].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), + ]; + + let ix = Instruction { program_id: ctx.accounts.base_program_id.key(), accounts: deposit_accounts, data: input }; + + invoke(&ix, ctx.remaining_accounts)?; + + Ok(()) + } + + pub fn withdraw<'a, 'b, 'c, 'info>( + ctx: Context<'a, 'b, 'c, 'info, Action<'info>>, + input: Vec, + ) -> Result<()> { + // Get Input + let mut input_bytes = &input[..]; + let input_struct = WithdrawInputWrapper::deserialize(&mut input_bytes)?; + + msg!("Input: {:?}", input_struct); + + let withdraw_accounts = if input_struct.instruction == 23 { + vec![ + AccountMeta::new(ctx.remaining_accounts[0].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[1].key(), true), + AccountMeta::new(ctx.remaining_accounts[2].key(), false), + AccountMeta::new(ctx.remaining_accounts[3].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[4].key(), false), + AccountMeta::new(ctx.remaining_accounts[5].key(), false), + AccountMeta::new(ctx.remaining_accounts[6].key(), true), + AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), + AccountMeta::new(ctx.remaining_accounts[8].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[9].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[10].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[11].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[12].key(), false), + ] + } else { + vec![ + AccountMeta::new(ctx.remaining_accounts[0].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[1].key(), true), + AccountMeta::new(ctx.remaining_accounts[2].key(), false), + AccountMeta::new(ctx.remaining_accounts[3].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[4].key(), false), + AccountMeta::new(ctx.remaining_accounts[5].key(), false), + AccountMeta::new(ctx.remaining_accounts[6].key(), true), + AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[8].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[9].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[10].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[11].key(), false), + ] + }; + + let withdraw_ix = Instruction { program_id: ctx.accounts.base_program_id.key(), accounts: withdraw_accounts, data: input }; + + invoke(&withdraw_ix, ctx.remaining_accounts)?; + + let deactivate_ix = stake::instruction::deactivate_stake(&ctx.remaining_accounts[1].key(), &ctx.remaining_accounts[6].key()); + invoke(&deactivate_ix, &vec![ctx.remaining_accounts[1].clone()])?; - // Deriving keys Ok(()) } } +#[derive(Accounts)] +pub struct Action<'info> { + pub gateway_authority: Signer<'info>, + /// CHECK: Safe + pub gateway_state_info: AccountInfo<'info>, + /// CHECK: Safe + pub base_program_id: AccountInfo<'info>, +} + #[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, Default)] pub struct DepositInputWrapper { + /// The instruction to deposit. Should always be 1. + pub instruction: u8, + /// Amount to deposit. pub amount: u64, } + +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, Default)] +pub struct WithdrawInputWrapper { + /// The instuction to withdraw. This is either a 2 (for v1) or 23 (v2). + pub instruction: u8, + /// Amount to withdraw. + pub amount: u64, + /// Index of the Heaviest Validator. Unused in Lido v1. + pub validator_index: u32, +} \ No newline at end of file diff --git a/target/idl/adapter_lido.json b/target/idl/adapter_lido.json new file mode 100644 index 0000000..d0b11e6 --- /dev/null +++ b/target/idl/adapter_lido.json @@ -0,0 +1,99 @@ +{ + "version": "0.1.0", + "name": "adapter_lido", + "instructions": [ + { + "name": "deposit", + "accounts": [ + { + "name": "gatewayAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "gatewayStateInfo", + "isMut": false, + "isSigner": false + }, + { + "name": "baseProgramId", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "input", + "type": "bytes" + } + ] + }, + { + "name": "withdraw", + "accounts": [ + { + "name": "gatewayAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "gatewayStateInfo", + "isMut": false, + "isSigner": false + }, + { + "name": "baseProgramId", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "input", + "type": "bytes" + } + ] + } + ], + "types": [ + { + "name": "DepositInputWrapper", + "type": { + "kind": "struct", + "fields": [ + { + "name": "instruction", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + } + }, + { + "name": "WithdrawInputWrapper", + "type": { + "kind": "struct", + "fields": [ + { + "name": "instruction", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "validatorIndex", + "type": "u32" + } + ] + } + } + ], + "metadata": { + "address": "4XnyVwkN5dR7Rinnys59qMqLjhxytpv4JbFLJuXe5mKk" + } +} \ No newline at end of file diff --git a/target/types/adapter_lido.ts b/target/types/adapter_lido.ts new file mode 100644 index 0000000..0e423c9 --- /dev/null +++ b/target/types/adapter_lido.ts @@ -0,0 +1,193 @@ +export type AdapterLido = { + "version": "0.1.0", + "name": "adapter_lido", + "instructions": [ + { + "name": "deposit", + "accounts": [ + { + "name": "gatewayAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "gatewayStateInfo", + "isMut": false, + "isSigner": false + }, + { + "name": "baseProgramId", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "input", + "type": "bytes" + } + ] + }, + { + "name": "withdraw", + "accounts": [ + { + "name": "gatewayAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "gatewayStateInfo", + "isMut": false, + "isSigner": false + }, + { + "name": "baseProgramId", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "input", + "type": "bytes" + } + ] + } + ], + "types": [ + { + "name": "DepositInputWrapper", + "type": { + "kind": "struct", + "fields": [ + { + "name": "instruction", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + } + }, + { + "name": "WithdrawInputWrapper", + "type": { + "kind": "struct", + "fields": [ + { + "name": "instruction", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "validatorIndex", + "type": "u32" + } + ] + } + } + ] +}; + +export const IDL: AdapterLido = { + "version": "0.1.0", + "name": "adapter_lido", + "instructions": [ + { + "name": "deposit", + "accounts": [ + { + "name": "gatewayAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "gatewayStateInfo", + "isMut": false, + "isSigner": false + }, + { + "name": "baseProgramId", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "input", + "type": "bytes" + } + ] + }, + { + "name": "withdraw", + "accounts": [ + { + "name": "gatewayAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "gatewayStateInfo", + "isMut": false, + "isSigner": false + }, + { + "name": "baseProgramId", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "input", + "type": "bytes" + } + ] + } + ], + "types": [ + { + "name": "DepositInputWrapper", + "type": { + "kind": "struct", + "fields": [ + { + "name": "instruction", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + } + }, + { + "name": "WithdrawInputWrapper", + "type": { + "kind": "struct", + "fields": [ + { + "name": "instruction", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + }, + { + "name": "validatorIndex", + "type": "u32" + } + ] + } + } + ] +}; From 2265f7f0f219ed3734ebd28a630831a153fca4ed Mon Sep 17 00:00:00 2001 From: Alvin Philips Date: Tue, 29 Nov 2022 04:16:34 +0530 Subject: [PATCH 3/7] Added Output Wrappers and cleaned up Deposit --- programs/adapter-lido/src/lib.rs | 86 +++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 8 deletions(-) diff --git a/programs/adapter-lido/src/lib.rs b/programs/adapter-lido/src/lib.rs index c9ed631..11b006f 100644 --- a/programs/adapter-lido/src/lib.rs +++ b/programs/adapter-lido/src/lib.rs @@ -1,17 +1,16 @@ use anchor_lang::prelude::*; use anchor_lang::solana_program::{ + stake, instruction::{AccountMeta, Instruction}, program::invoke, pubkey::Pubkey, }; -use anchor_spl::token::{Mint, TokenAccount}; +use anchor_spl::token::TokenAccount; declare_id!("ADPTPxbHbEBo9A8E53P2PZnmw3ZYJuwc8ArQQkbJtqhx"); #[program] pub mod adapter_lido { - use anchor_lang::solana_program::{account_info::next_account_infos, stake}; - use super::*; pub fn deposit<'a, 'b, 'c, 'info>( @@ -23,11 +22,16 @@ pub mod adapter_lido { let input_struct = DepositInputWrapper::deserialize(&mut input_bytes)?; msg!("Input: {:?}", input_struct); - + + let mut recipient_st_sol_account = + Account::::try_from(&ctx.remaining_accounts[2])?; + + let token_amount = recipient_st_sol_account.amount; + let deposit_accounts = vec![ AccountMeta::new(ctx.remaining_accounts[0].key(), false), AccountMeta::new(ctx.remaining_accounts[1].key(), true), - AccountMeta::new(ctx.remaining_accounts[2].key(), false), + AccountMeta::new(recipient_st_sol_account.key(), false), AccountMeta::new(ctx.remaining_accounts[3].key(), false), AccountMeta::new(ctx.remaining_accounts[4].key(), false), AccountMeta::new_readonly(ctx.remaining_accounts[5].key(), false), @@ -35,10 +39,30 @@ pub mod adapter_lido { AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), ]; - let ix = Instruction { program_id: ctx.accounts.base_program_id.key(), accounts: deposit_accounts, data: input }; + // Prepend instruction byte to Solido Input + let mut data = vec![1u8]; + data.extend(input); + + let ix = Instruction { program_id: ctx.accounts.base_program_id.key(), accounts: deposit_accounts, data}; invoke(&ix, ctx.remaining_accounts)?; + recipient_st_sol_account.reload()?; + + let share_amount = recipient_st_sol_account.amount.checked_sub(token_amount).unwrap(); + + // Wrap Output + let output_struct = DepositOutputWrapper { + share_amount, + ..Default::default() + }; + let mut output: Vec = Vec::new(); + output_struct.serialize(&mut output).unwrap(); + + anchor_lang::solana_program::program::set_return_data(&output); + + msg!("Output: {:?}", output_struct); + Ok(()) } @@ -46,6 +70,7 @@ pub mod adapter_lido { ctx: Context<'a, 'b, 'c, 'info, Action<'info>>, input: Vec, ) -> Result<()> { + msg!("Entered Withdraw function"); // Get Input let mut input_bytes = &input[..]; let input_struct = WithdrawInputWrapper::deserialize(&mut input_bytes)?; @@ -107,8 +132,6 @@ pub struct Action<'info> { #[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, Default)] pub struct DepositInputWrapper { - /// The instruction to deposit. Should always be 1. - pub instruction: u8, /// Amount to deposit. pub amount: u64, } @@ -121,4 +144,51 @@ pub struct WithdrawInputWrapper { pub amount: u64, /// Index of the Heaviest Validator. Unused in Lido v1. pub validator_index: u32, +} + +// OutputWrapper needs to take up all the space of 32 bytes +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, Default)] +pub struct DepositOutputWrapper { + pub share_amount: u64, + pub dummy_2: u64, + pub dummy_3: u64, + pub dummy_4: u64, +} + +// OutputWrapper needs to take up all the space of 32 bytes +#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, Default)] +pub struct WithdrawOutputWrapper { + pub lp_amount: u64, + pub dummy_2: u64, + pub dummy_3: u64, + pub dummy_4: u64, +} + +pub type DepositOutputTuple = (u64, u64, u64, u64); +pub type WithdrawOutputTuple = (u64, u64, u64, u64); +pub type SupplyOutputTuple = (u64, u64, u64, u64); +pub type UnsupplyOutputTuple = (u64, u64, u64, u64); + +impl From for DepositOutputTuple { + fn from(result: DepositOutputWrapper) -> DepositOutputTuple { + let DepositOutputWrapper { + share_amount, + dummy_2, + dummy_3, + dummy_4, + } = result; + (share_amount, dummy_2, dummy_3, dummy_4) + } +} + +impl From for WithdrawOutputTuple { + fn from(result: WithdrawOutputWrapper) -> WithdrawOutputTuple { + let WithdrawOutputWrapper { + lp_amount, + dummy_2, + dummy_3, + dummy_4, + } = result; + (lp_amount, dummy_2, dummy_3, dummy_4) + } } \ No newline at end of file From ea19cb4eaaf71ba99bc29bf412cad1ec61805d90 Mon Sep 17 00:00:00 2001 From: Alvin Philips Date: Wed, 30 Nov 2022 14:41:28 +0530 Subject: [PATCH 4/7] Updated Withdraw method with output struct --- programs/adapter-lido/src/lib.rs | 42 +++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/programs/adapter-lido/src/lib.rs b/programs/adapter-lido/src/lib.rs index 11b006f..c930282 100644 --- a/programs/adapter-lido/src/lib.rs +++ b/programs/adapter-lido/src/lib.rs @@ -70,17 +70,21 @@ pub mod adapter_lido { ctx: Context<'a, 'b, 'c, 'info, Action<'info>>, input: Vec, ) -> Result<()> { - msg!("Entered Withdraw function"); // Get Input let mut input_bytes = &input[..]; let input_struct = WithdrawInputWrapper::deserialize(&mut input_bytes)?; + let is_lido_v2 = ctx.remaining_accounts.len() == 13; + msg!("Input: {:?}", input_struct); + + let user_account = ctx.remaining_accounts[1].clone(); + let account_balance = user_account.lamports(); - let withdraw_accounts = if input_struct.instruction == 23 { + let withdraw_accounts = if is_lido_v2 { vec![ AccountMeta::new(ctx.remaining_accounts[0].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[1].key(), true), + AccountMeta::new_readonly(user_account.key(), true), AccountMeta::new(ctx.remaining_accounts[2].key(), false), AccountMeta::new(ctx.remaining_accounts[3].key(), false), AccountMeta::new_readonly(ctx.remaining_accounts[4].key(), false), @@ -96,7 +100,7 @@ pub mod adapter_lido { } else { vec![ AccountMeta::new(ctx.remaining_accounts[0].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[1].key(), true), + AccountMeta::new_readonly(user_account.key(), true), AccountMeta::new(ctx.remaining_accounts[2].key(), false), AccountMeta::new(ctx.remaining_accounts[3].key(), false), AccountMeta::new_readonly(ctx.remaining_accounts[4].key(), false), @@ -110,12 +114,32 @@ pub mod adapter_lido { ] }; - let withdraw_ix = Instruction { program_id: ctx.accounts.base_program_id.key(), accounts: withdraw_accounts, data: input }; + let first_byte: u8 = match is_lido_v2 { + true => 23, + false => 2 + }; + + let mut data = vec![first_byte]; + data.extend(input); + + let withdraw_ix = Instruction { program_id: ctx.accounts.base_program_id.key(), accounts: withdraw_accounts, data }; invoke(&withdraw_ix, ctx.remaining_accounts)?; - let deactivate_ix = stake::instruction::deactivate_stake(&ctx.remaining_accounts[1].key(), &ctx.remaining_accounts[6].key()); - invoke(&deactivate_ix, &vec![ctx.remaining_accounts[1].clone()])?; + let deactivate_ix = stake::instruction::deactivate_stake(&user_account.key(), &ctx.remaining_accounts[6].key()); + invoke(&deactivate_ix, &vec![user_account.clone()])?; + + let lp_amount = user_account.lamports().checked_sub(account_balance).unwrap(); + + // Wrap Output + let output_struct = WithdrawOutputWrapper { + lp_amount, + ..Default::default() + }; + let mut output: Vec = Vec::new(); + output_struct.serialize(&mut output).unwrap(); + + anchor_lang::solana_program::program::set_return_data(&output); Ok(()) } @@ -138,8 +162,6 @@ pub struct DepositInputWrapper { #[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, Default)] pub struct WithdrawInputWrapper { - /// The instuction to withdraw. This is either a 2 (for v1) or 23 (v2). - pub instruction: u8, /// Amount to withdraw. pub amount: u64, /// Index of the Heaviest Validator. Unused in Lido v1. @@ -166,8 +188,6 @@ pub struct WithdrawOutputWrapper { pub type DepositOutputTuple = (u64, u64, u64, u64); pub type WithdrawOutputTuple = (u64, u64, u64, u64); -pub type SupplyOutputTuple = (u64, u64, u64, u64); -pub type UnsupplyOutputTuple = (u64, u64, u64, u64); impl From for DepositOutputTuple { fn from(result: DepositOutputWrapper) -> DepositOutputTuple { From f0ee016c65d37975698dcb6638f590c8e141045c Mon Sep 17 00:00:00 2001 From: Alvin Philips Date: Sun, 4 Dec 2022 09:39:48 +0530 Subject: [PATCH 5/7] Removed v1 code --- programs/adapter-lido/src/lib.rs | 103 ++++++++++++++----------------- 1 file changed, 48 insertions(+), 55 deletions(-) diff --git a/programs/adapter-lido/src/lib.rs b/programs/adapter-lido/src/lib.rs index c930282..d214c64 100644 --- a/programs/adapter-lido/src/lib.rs +++ b/programs/adapter-lido/src/lib.rs @@ -1,9 +1,9 @@ use anchor_lang::prelude::*; use anchor_lang::solana_program::{ - stake, instruction::{AccountMeta, Instruction}, program::invoke, pubkey::Pubkey, + stake, }; use anchor_spl::token::TokenAccount; @@ -20,7 +20,7 @@ pub mod adapter_lido { // Get Input let mut input_bytes = &input[..]; let input_struct = DepositInputWrapper::deserialize(&mut input_bytes)?; - + msg!("Input: {:?}", input_struct); let mut recipient_st_sol_account = @@ -36,20 +36,27 @@ pub mod adapter_lido { AccountMeta::new(ctx.remaining_accounts[4].key(), false), AccountMeta::new_readonly(ctx.remaining_accounts[5].key(), false), AccountMeta::new_readonly(ctx.remaining_accounts[6].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), ]; // Prepend instruction byte to Solido Input let mut data = vec![1u8]; data.extend(input); - let ix = Instruction { program_id: ctx.accounts.base_program_id.key(), accounts: deposit_accounts, data}; - + let ix = Instruction { + program_id: ctx.accounts.base_program_id.key(), + accounts: deposit_accounts, + data, + }; + invoke(&ix, ctx.remaining_accounts)?; recipient_st_sol_account.reload()?; - let share_amount = recipient_st_sol_account.amount.checked_sub(token_amount).unwrap(); + let share_amount = recipient_st_sol_account + .amount + .checked_sub(token_amount) + .unwrap(); // Wrap Output let output_struct = DepositOutputWrapper { @@ -74,62 +81,48 @@ pub mod adapter_lido { let mut input_bytes = &input[..]; let input_struct = WithdrawInputWrapper::deserialize(&mut input_bytes)?; - let is_lido_v2 = ctx.remaining_accounts.len() == 13; - msg!("Input: {:?}", input_struct); let user_account = ctx.remaining_accounts[1].clone(); let account_balance = user_account.lamports(); - - let withdraw_accounts = if is_lido_v2 { - vec![ - AccountMeta::new(ctx.remaining_accounts[0].key(), false), - AccountMeta::new_readonly(user_account.key(), true), - AccountMeta::new(ctx.remaining_accounts[2].key(), false), - AccountMeta::new(ctx.remaining_accounts[3].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[4].key(), false), - AccountMeta::new(ctx.remaining_accounts[5].key(), false), - AccountMeta::new(ctx.remaining_accounts[6].key(), true), - AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), - AccountMeta::new(ctx.remaining_accounts[8].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[9].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[10].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[11].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[12].key(), false), - ] - } else { - vec![ - AccountMeta::new(ctx.remaining_accounts[0].key(), false), - AccountMeta::new_readonly(user_account.key(), true), - AccountMeta::new(ctx.remaining_accounts[2].key(), false), - AccountMeta::new(ctx.remaining_accounts[3].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[4].key(), false), - AccountMeta::new(ctx.remaining_accounts[5].key(), false), - AccountMeta::new(ctx.remaining_accounts[6].key(), true), - AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[8].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[9].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[10].key(), false), - AccountMeta::new_readonly(ctx.remaining_accounts[11].key(), false), - ] - }; - let first_byte: u8 = match is_lido_v2 { - true => 23, - false => 2 - }; + let withdraw_accounts = vec![ + AccountMeta::new(ctx.remaining_accounts[0].key(), false), + AccountMeta::new_readonly(user_account.key(), true), + AccountMeta::new(ctx.remaining_accounts[2].key(), false), + AccountMeta::new(ctx.remaining_accounts[3].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[4].key(), false), + AccountMeta::new(ctx.remaining_accounts[5].key(), false), + AccountMeta::new(ctx.remaining_accounts[6].key(), true), + AccountMeta::new_readonly(ctx.remaining_accounts[7].key(), false), + AccountMeta::new(ctx.remaining_accounts[8].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[9].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[10].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[11].key(), false), + AccountMeta::new_readonly(ctx.remaining_accounts[12].key(), false), + ]; - let mut data = vec![first_byte]; + let mut data = vec![23u8]; data.extend(input); - let withdraw_ix = Instruction { program_id: ctx.accounts.base_program_id.key(), accounts: withdraw_accounts, data }; - - invoke(&withdraw_ix, ctx.remaining_accounts)?; - - let deactivate_ix = stake::instruction::deactivate_stake(&user_account.key(), &ctx.remaining_accounts[6].key()); - invoke(&deactivate_ix, &vec![user_account.clone()])?; + let withdraw_ix = Instruction { + program_id: ctx.accounts.base_program_id.key(), + accounts: withdraw_accounts, + data, + }; - let lp_amount = user_account.lamports().checked_sub(account_balance).unwrap(); + invoke(&withdraw_ix, ctx.remaining_accounts)?; + + let deactivate_ix = stake::instruction::deactivate_stake( + &user_account.key(), + &ctx.remaining_accounts[6].key(), + ); + invoke(&deactivate_ix, &vec![user_account.clone()])?; + + let lp_amount = user_account + .lamports() + .checked_sub(account_balance) + .unwrap(); // Wrap Output let output_struct = WithdrawOutputWrapper { @@ -164,7 +157,7 @@ pub struct DepositInputWrapper { pub struct WithdrawInputWrapper { /// Amount to withdraw. pub amount: u64, - /// Index of the Heaviest Validator. Unused in Lido v1. + /// Index of the Heaviest Validator. pub validator_index: u32, } @@ -211,4 +204,4 @@ impl From for WithdrawOutputTuple { } = result; (lp_amount, dummy_2, dummy_3, dummy_4) } -} \ No newline at end of file +} From ece53de113e421c73a2747c4bd2f8d7c958006ea Mon Sep 17 00:00:00 2001 From: Alvin Philips Date: Tue, 6 Dec 2022 10:39:40 +0530 Subject: [PATCH 6/7] Removed gateway state from Action --- programs/adapter-lido/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/programs/adapter-lido/src/lib.rs b/programs/adapter-lido/src/lib.rs index d214c64..e72af6e 100644 --- a/programs/adapter-lido/src/lib.rs +++ b/programs/adapter-lido/src/lib.rs @@ -142,8 +142,6 @@ pub mod adapter_lido { pub struct Action<'info> { pub gateway_authority: Signer<'info>, /// CHECK: Safe - pub gateway_state_info: AccountInfo<'info>, - /// CHECK: Safe pub base_program_id: AccountInfo<'info>, } From 44dd3a6b70d46671e331fff6ca892e33ef97a14a Mon Sep 17 00:00:00 2001 From: Alvin Philips Date: Fri, 30 Dec 2022 09:12:21 +0530 Subject: [PATCH 7/7] Added gateway key and switched to PDA --- programs/adapter-lido/src/lib.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/programs/adapter-lido/src/lib.rs b/programs/adapter-lido/src/lib.rs index e72af6e..b319333 100644 --- a/programs/adapter-lido/src/lib.rs +++ b/programs/adapter-lido/src/lib.rs @@ -7,10 +7,12 @@ use anchor_lang::solana_program::{ }; use anchor_spl::token::TokenAccount; -declare_id!("ADPTPxbHbEBo9A8E53P2PZnmw3ZYJuwc8ArQQkbJtqhx"); +declare_id!("4XnyVwkN5dR7Rinnys59qMqLjhxytpv4JbFLJuXe5mKk"); #[program] pub mod adapter_lido { + use anchor_lang::solana_program::program::invoke_signed; + use super::*; pub fn deposit<'a, 'b, 'c, 'info>( @@ -117,7 +119,7 @@ pub mod adapter_lido { &user_account.key(), &ctx.remaining_accounts[6].key(), ); - invoke(&deactivate_ix, &vec![user_account.clone()])?; + invoke_signed(&deactivate_ix, &vec![user_account.clone()], &[&[&user_account.key().to_bytes(), &input_struct.gateway_key.to_bytes()]])?; let lp_amount = user_account .lamports() @@ -157,6 +159,7 @@ pub struct WithdrawInputWrapper { pub amount: u64, /// Index of the Heaviest Validator. pub validator_index: u32, + pub gateway_key: Pubkey, } // OutputWrapper needs to take up all the space of 32 bytes