diff --git a/programs/openbook-v2/src/accounts_ix/init_open_orders.rs b/programs/openbook-v2/src/accounts_ix/init_open_orders.rs index c595d6af..80d4a49b 100644 --- a/programs/openbook-v2/src/accounts_ix/init_open_orders.rs +++ b/programs/openbook-v2/src/accounts_ix/init_open_orders.rs @@ -17,7 +17,7 @@ pub struct InitOpenOrders<'info> { pub owner: Signer<'info>, #[account(mut)] pub payer: Signer<'info>, - #[account()] + /// CHECK: pub delegate_account: Option>, #[account(mut)] pub market: AccountLoader<'info, Market>, diff --git a/programs/openbook-v2/src/accounts_ix/mod.rs b/programs/openbook-v2/src/accounts_ix/mod.rs index a88814c9..4b314fc7 100644 --- a/programs/openbook-v2/src/accounts_ix/mod.rs +++ b/programs/openbook-v2/src/accounts_ix/mod.rs @@ -10,6 +10,7 @@ pub use init_open_orders::*; pub use place_order::*; pub use place_take_order::*; pub use prune_orders::*; +pub use set_delegate::*; pub use set_market_expired::*; pub use settle_funds::*; pub use stub_oracle_close::*; @@ -29,6 +30,7 @@ mod init_open_orders; mod place_order; mod place_take_order; mod prune_orders; +mod set_delegate; mod set_market_expired; mod settle_funds; mod stub_oracle_close; diff --git a/programs/openbook-v2/src/accounts_ix/set_delegate.rs b/programs/openbook-v2/src/accounts_ix/set_delegate.rs index 00319cf2..0bd8251e 100644 --- a/programs/openbook-v2/src/accounts_ix/set_delegate.rs +++ b/programs/openbook-v2/src/accounts_ix/set_delegate.rs @@ -1,18 +1,16 @@ use anchor_lang::prelude::*; -use crate::state::{Market, OpenOrdersAccount, OpenOrdersAccountFixed}; +use crate::state::OpenOrdersAccountFixed; #[derive(Accounts)] pub struct SetDelegate<'info> { #[account( mut, - has_one = market, + has_one = owner, )] pub open_orders_account: AccountLoader<'info, OpenOrdersAccountFixed>, #[account(mut)] pub owner: Signer<'info>, - #[account()] + /// CHECK: pub delegate_account: Option>, - #[account(mut)] - pub market: AccountLoader<'info, Market>, } diff --git a/programs/openbook-v2/src/instructions/init_open_orders.rs b/programs/openbook-v2/src/instructions/init_open_orders.rs index eff30739..4f9cdc7b 100644 --- a/programs/openbook-v2/src/instructions/init_open_orders.rs +++ b/programs/openbook-v2/src/instructions/init_open_orders.rs @@ -1,4 +1,5 @@ use crate::accounts_ix::InitOpenOrders; +use crate::pod_option::PodOption; use crate::state::*; use anchor_lang::prelude::*; @@ -9,15 +10,18 @@ pub fn init_open_orders( ) -> Result<()> { let mut account = ctx.accounts.open_orders_account.load_full_init()?; + let delegate_account: PodOption = ctx + .accounts + .delegate_account + .as_ref() + .map(|account| account.key()) + .into(); + account.fixed.account_num = account_num; account.fixed.market = ctx.accounts.market.key(); account.fixed.bump = *ctx.bumps.get("open_orders_account").unwrap(); account.fixed.owner = ctx.accounts.owner.key(); - if let Some(delegate) = &ctx.accounts.delegate_account { - account.fixed.delegate = delegate.key(); - } else { - account.fixed.delegate = ctx.accounts.owner.key() - }; + account.fixed.delegate = delegate_account; account.expand_dynamic_content(open_orders_count)?; diff --git a/programs/openbook-v2/src/instructions/mod.rs b/programs/openbook-v2/src/instructions/mod.rs index a88814c9..4b314fc7 100644 --- a/programs/openbook-v2/src/instructions/mod.rs +++ b/programs/openbook-v2/src/instructions/mod.rs @@ -10,6 +10,7 @@ pub use init_open_orders::*; pub use place_order::*; pub use place_take_order::*; pub use prune_orders::*; +pub use set_delegate::*; pub use set_market_expired::*; pub use settle_funds::*; pub use stub_oracle_close::*; @@ -29,6 +30,7 @@ mod init_open_orders; mod place_order; mod place_take_order; mod prune_orders; +mod set_delegate; mod set_market_expired; mod settle_funds; mod stub_oracle_close; diff --git a/programs/openbook-v2/src/instructions/set_delegate.rs b/programs/openbook-v2/src/instructions/set_delegate.rs index 766541d8..d868fc7d 100644 --- a/programs/openbook-v2/src/instructions/set_delegate.rs +++ b/programs/openbook-v2/src/instructions/set_delegate.rs @@ -1,17 +1,20 @@ use anchor_lang::prelude::*; use crate::accounts_ix::*; -use crate::error::*; +use crate::pod_option::PodOption; use crate::state::*; -pub fn set_delegate(ctx: Context, limit: u8) -> Result<()> { +pub fn set_delegate(ctx: Context) -> Result<()> { let mut account = ctx.accounts.open_orders_account.load_full_mut()?; - account.delegate = if let Some(delegate) = ctx.accounts.delegate_account { - delegate; + let delegate_account: PodOption = ctx + .accounts + .delegate_account + .as_ref() + .map(|account| account.key()) + .into(); + + account.fixed.delegate = delegate_account; - } else { - ctx.accounts.owner.key() - }; Ok(()) } diff --git a/programs/openbook-v2/src/lib.rs b/programs/openbook-v2/src/lib.rs index 3b8348b5..acacba06 100644 --- a/programs/openbook-v2/src/lib.rs +++ b/programs/openbook-v2/src/lib.rs @@ -359,6 +359,12 @@ pub mod openbook_v2 { Ok(()) } + pub fn set_delegate(ctx: Context) -> Result<()> { + #[cfg(feature = "enable-gpl")] + instructions::set_delegate(ctx)?; + Ok(()) + } + /// Set market to expired before pruning orders and closing the market pub fn set_market_expired(ctx: Context) -> Result<()> { #[cfg(feature = "enable-gpl")] diff --git a/programs/openbook-v2/src/state/open_orders_account.rs b/programs/openbook-v2/src/state/open_orders_account.rs index 020b86c5..8ab27dd2 100644 --- a/programs/openbook-v2/src/state/open_orders_account.rs +++ b/programs/openbook-v2/src/state/open_orders_account.rs @@ -8,6 +8,7 @@ use std::mem::size_of; use crate::error::*; use crate::logs::FillLog; +use crate::pod_option::PodOption; use super::FillEvent; use super::LeafNode; @@ -35,7 +36,7 @@ pub struct OpenOrdersAccount { pub name: [u8; 32], // Alternative authority/signer of transactions for a openbook account - pub delegate: Pubkey, + pub delegate: PodOption, pub account_num: u32, @@ -59,7 +60,7 @@ impl OpenOrdersAccount { name: Default::default(), owner: Pubkey::default(), market: Pubkey::default(), - delegate: Pubkey::default(), + delegate: PodOption::default(), account_num: 0, bump: 0, @@ -99,7 +100,7 @@ pub struct OpenOrdersAccountFixed { pub owner: Pubkey, pub market: Pubkey, pub name: [u8; 32], - pub delegate: Pubkey, + pub delegate: PodOption, pub account_num: u32, pub bump: u8, pub padding: [u8; 3], @@ -110,13 +111,14 @@ pub struct OpenOrdersAccountFixed { const_assert_eq!( size_of::(), size_of::() - - size_of::() * 4 + - size_of::() * 3 + - 40 - size_of::() - size_of::() - size_of::<[u8; 3]>() - size_of::<[u8; 208]>() ); -const_assert_eq!(size_of::(), 496); +const_assert_eq!(size_of::(), 504); const_assert_eq!(size_of::() % 8, 0); impl OpenOrdersAccountFixed { @@ -127,7 +129,11 @@ impl OpenOrdersAccountFixed { } pub fn is_owner_or_delegate(&self, ix_signer: Pubkey) -> bool { - self.delegate == ix_signer + let delegate_option: Option = Option::from(self.delegate); + if let Some(delegate) = delegate_option { + return self.owner == ix_signer || delegate == ix_signer; + } + self.owner == ix_signer } }