From 868c55fef19037cc303da9ced5aac8c0191484b8 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 1 Sep 2022 12:26:50 +0200 Subject: [PATCH] Serum index reservation: use a real account Makes it easier and more future-proof --- .../instructions/serum3_deregister_market.rs | 24 +---- .../instructions/serum3_register_market.rs | 12 ++- programs/mango-v4/src/state/serum3_market.rs | 10 ++ ts/client/src/mango_v4.ts | 92 +++++++++++-------- 4 files changed, 76 insertions(+), 62 deletions(-) diff --git a/programs/mango-v4/src/instructions/serum3_deregister_market.rs b/programs/mango-v4/src/instructions/serum3_deregister_market.rs index 8897cf0e0..c0481d85a 100644 --- a/programs/mango-v4/src/instructions/serum3_deregister_market.rs +++ b/programs/mango-v4/src/instructions/serum3_deregister_market.rs @@ -20,13 +20,13 @@ pub struct Serum3DeregisterMarket<'info> { )] pub serum_market: AccountLoader<'info, Serum3Market>, - /// CHECK: Unused account #[account( mut, - seeds = [b"Serum3Index".as_ref(), group.key().as_ref(), &serum_market.load()?.market_index.to_le_bytes()], - bump + has_one = group, + constraint = serum_market.load()?.market_index == index_reservation.load()?.market_index, + close = sol_destination )] - pub index_reservation: UncheckedAccount<'info>, + pub index_reservation: AccountLoader<'info, Serum3MarketIndexReservation>, #[account(mut)] /// CHECK: target for account rent needs no checks @@ -35,20 +35,6 @@ pub struct Serum3DeregisterMarket<'info> { pub token_program: Program<'info, Token>, } -pub fn serum3_deregister_market(ctx: Context) -> Result<()> { - close_unsafe( - ctx.accounts.index_reservation.to_account_info(), - ctx.accounts.sol_destination.to_account_info(), - ); +pub fn serum3_deregister_market(_ctx: Context) -> Result<()> { Ok(()) } - -fn close_unsafe<'info>(info: AccountInfo<'info>, sol_destination: AccountInfo<'info>) { - // Transfer tokens from the account to the sol_destination. - let dest_starting_lamports = sol_destination.lamports(); - **sol_destination.lamports.borrow_mut() = - dest_starting_lamports.checked_add(info.lamports()).unwrap(); - **info.lamports.borrow_mut() = 0; - - // Does NOT prevent reinit attacks in any way -} diff --git a/programs/mango-v4/src/instructions/serum3_register_market.rs b/programs/mango-v4/src/instructions/serum3_register_market.rs index e5e1b7abf..2d58cbc46 100644 --- a/programs/mango-v4/src/instructions/serum3_register_market.rs +++ b/programs/mango-v4/src/instructions/serum3_register_market.rs @@ -31,16 +31,15 @@ pub struct Serum3RegisterMarket<'info> { )] pub serum_market: AccountLoader<'info, Serum3Market>, - /// CHECK: Unused account #[account( init, // block using the same market index twice seeds = [b"Serum3Index".as_ref(), group.key().as_ref(), &market_index.to_le_bytes()], bump, payer = payer, - space = 8, // like an anchor account with only a discriminator + space = 8 + std::mem::size_of::(), )] - pub index_reservation: UncheckedAccount<'info>, + pub index_reservation: AccountLoader<'info, Serum3MarketIndexReservation>, #[account(has_one = group)] pub quote_bank: AccountLoader<'info, Bank>, @@ -91,5 +90,12 @@ pub fn serum3_register_market( reserved: [0; 128], }; + let mut serum_index_reservation = ctx.accounts.index_reservation.load_init()?; + *serum_index_reservation = Serum3MarketIndexReservation { + group: ctx.accounts.group.key(), + market_index, + reserved: [0; 38], + }; + Ok(()) } diff --git a/programs/mango-v4/src/state/serum3_market.rs b/programs/mango-v4/src/state/serum3_market.rs index 1f97aaf4f..306ba52ff 100644 --- a/programs/mango-v4/src/state/serum3_market.rs +++ b/programs/mango-v4/src/state/serum3_market.rs @@ -44,6 +44,16 @@ impl Serum3Market { } } +#[account(zero_copy)] +#[derive(Debug)] +pub struct Serum3MarketIndexReservation { + pub group: Pubkey, + pub market_index: Serum3MarketIndex, + pub reserved: [u8; 38], +} +const_assert_eq!(size_of::(), 32 + 2 + 38); +const_assert_eq!(size_of::() % 8, 0); + #[macro_export] macro_rules! serum_market_seeds { ( $acc:expr ) => { diff --git a/ts/client/src/mango_v4.ts b/ts/client/src/mango_v4.ts index 8e1431468..c53f1ee96 100644 --- a/ts/client/src/mango_v4.ts +++ b/ts/client/src/mango_v4.ts @@ -1397,26 +1397,7 @@ export type MangoV4 = { { "name": "indexReservation", "isMut": true, - "isSigner": false, - "pda": { - "seeds": [ - { - "kind": "const", - "type": "string", - "value": "Serum3Index" - }, - { - "kind": "account", - "type": "publicKey", - "path": "group" - }, - { - "kind": "account", - "type": "publicKey", - "path": "serum_market" - } - ] - } + "isSigner": false }, { "name": "solDestination", @@ -3681,6 +3662,31 @@ export type MangoV4 = { } ] } + }, + { + "name": "serum3MarketIndexReservation", + "type": { + "kind": "struct", + "fields": [ + { + "name": "group", + "type": "publicKey" + }, + { + "name": "marketIndex", + "type": "u16" + }, + { + "name": "reserved", + "type": { + "array": [ + "u8", + 38 + ] + } + } + ] + } } ], "types": [ @@ -6705,26 +6711,7 @@ export const IDL: MangoV4 = { { "name": "indexReservation", "isMut": true, - "isSigner": false, - "pda": { - "seeds": [ - { - "kind": "const", - "type": "string", - "value": "Serum3Index" - }, - { - "kind": "account", - "type": "publicKey", - "path": "group" - }, - { - "kind": "account", - "type": "publicKey", - "path": "serum_market" - } - ] - } + "isSigner": false }, { "name": "solDestination", @@ -8989,6 +8976,31 @@ export const IDL: MangoV4 = { } ] } + }, + { + "name": "serum3MarketIndexReservation", + "type": { + "kind": "struct", + "fields": [ + { + "name": "group", + "type": "publicKey" + }, + { + "name": "marketIndex", + "type": "u16" + }, + { + "name": "reserved", + "type": { + "array": [ + "u8", + 38 + ] + } + } + ] + } } ], "types": [