IxGate: Fix check for re-enabling instructions (#540)

The bug allowed the security admin to enable instructions. This was
supposed to require the group admin.
This commit is contained in:
Christian Kamm 2023-04-14 16:12:17 +02:00 committed by GitHub
parent 98a79505e1
commit 0e831db687
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 165 additions and 66 deletions

View File

@ -11,7 +11,7 @@ pub fn ix_gate_set(ctx: Context<IxGateSet>, ix_gate: u128) -> Result<()> {
let mut require_group_admin = false;
for i in 0..128 {
// only admin can re-enable
if group.ix_gate & (1 << i) == 1 && ix_gate & (1 << i) == 0 {
if group.ix_gate & (1 << i) != 0 && ix_gate & (1 << i) == 0 {
require_group_admin = true;
}
}

View File

@ -24,6 +24,20 @@ async fn test_ix_gate_set() -> Result<(), TransportError> {
.create(solana)
.await;
send_tx(
solana,
GroupEdit {
group,
admin,
options: mango_v4::instruction::GroupEdit {
security_admin_opt: Some(payer.pubkey()),
..group_edit_instruction_default()
},
},
)
.await
.unwrap();
let account = create_funded_account(
&solana,
group,
@ -89,6 +103,61 @@ async fn test_ix_gate_set() -> Result<(), TransportError> {
.await
.unwrap();
//
// TEST: re-enabling is not allowed for security admin
//
let result = send_tx(
solana,
IxGateSetInstruction {
group,
admin: payer,
ix_gate: 0,
},
)
.await;
assert!(result.is_err());
let group_data: Group = solana.get_account(group).await;
assert!(!group_data.is_ix_enabled(IxGate::TokenDeposit));
//
// TEST: security admin can disable
//
send_tx(
solana,
IxGateSetInstruction {
group,
admin: payer,
ix_gate: {
let mut ix_gate = 0u128;
ix_gate |= 1 << IxGate::TokenDeposit as u128;
ix_gate |= 1 << IxGate::TokenWithdraw as u128;
ix_gate
},
},
)
.await
.unwrap();
let group_data: Group = solana.get_account(group).await;
assert!(!group_data.is_ix_enabled(IxGate::TokenDeposit));
assert!(!group_data.is_ix_enabled(IxGate::TokenWithdraw));
//
// TEST: admin can re-enable
//
send_tx(
solana,
IxGateSetInstruction {
group,
admin,
ix_gate: 0,
},
)
.await
.unwrap();
let group_data: Group = solana.get_account(group).await;
assert!(group_data.is_ix_enabled(IxGate::TokenDeposit));
assert!(group_data.is_ix_enabled(IxGate::TokenWithdraw));
//
// test cu budget, ix has a lot of logging
// e.g. Program 4MangoMjqJ2firMokCjjGgoK8d4MXcrgL7XJaL3w6fVg consumed 66986 of 75000 compute units

View File

@ -108,12 +108,12 @@ pub trait ClientInstruction {
fn make_instruction(
program_id: Pubkey,
accounts: &impl anchor_lang::ToAccountMetas,
data: impl anchor_lang::InstructionData,
data: &impl anchor_lang::InstructionData,
) -> instruction::Instruction {
instruction::Instruction {
program_id,
accounts: anchor_lang::ToAccountMetas::to_account_metas(accounts, None),
data: anchor_lang::InstructionData::data(&data),
data: anchor_lang::InstructionData::data(data),
}
}
@ -458,7 +458,7 @@ impl ClientInstruction for FlashLoanBeginInstruction {
loan_amounts: vec![self.withdraw_amount],
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.push(AccountMeta {
pubkey: self.mango_token_bank,
is_writable: true,
@ -530,7 +530,7 @@ impl ClientInstruction for FlashLoanEndInstruction {
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
instruction.accounts.push(AccountMeta {
pubkey: self.mango_token_vault,
@ -616,7 +616,7 @@ impl ClientInstruction for TokenWithdrawInstruction {
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -688,7 +688,7 @@ impl ClientInstruction for TokenDepositInstruction {
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -758,7 +758,7 @@ impl ClientInstruction for TokenDepositIntoExistingInstruction {
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -889,7 +889,7 @@ impl ClientInstruction for TokenRegisterInstruction {
rent: sysvar::rent::Rent::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -974,7 +974,7 @@ impl ClientInstruction for TokenAddBankInstruction {
rent: sysvar::rent::Rent::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1015,7 +1015,7 @@ impl ClientInstruction for TokenDeregisterInstruction {
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
let mut ams = self
.banks
@ -1124,7 +1124,7 @@ impl ClientInstruction for TokenEditWeights {
oracle: mint_info.oracle,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction
.accounts
.extend(mint_info.banks().iter().map(|&k| AccountMeta {
@ -1180,7 +1180,7 @@ impl ClientInstruction for TokenResetStablePriceModel {
oracle: mint_info.oracle,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction
.accounts
.extend(mint_info.banks().iter().map(|&k| AccountMeta {
@ -1241,7 +1241,7 @@ impl ClientInstruction for TokenResetNetBorrows {
oracle: mint_info.oracle,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction
.accounts
.extend(mint_info.banks().iter().map(|&k| AccountMeta {
@ -1299,7 +1299,7 @@ impl ClientInstruction for TokenMakeReduceOnly {
oracle: mint_info.oracle,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction
.accounts
.extend(mint_info.banks().iter().map(|&k| AccountMeta {
@ -1351,7 +1351,7 @@ impl ClientInstruction for StubOracleSetInstruction {
admin: self.admin.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1399,7 +1399,7 @@ impl ClientInstruction for StubOracleCreate {
system_program: System::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1444,7 +1444,7 @@ impl ClientInstruction for StubOracleCloseInstruction {
token_program: Token::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1500,7 +1500,7 @@ impl ClientInstruction for GroupCreateInstruction {
rent: sysvar::rent::Rent::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1509,7 +1509,7 @@ impl ClientInstruction for GroupCreateInstruction {
}
}
fn group_edit_instruction_default() -> mango_v4::instruction::GroupEdit {
pub fn group_edit_instruction_default() -> mango_v4::instruction::GroupEdit {
mango_v4::instruction::GroupEdit {
admin_opt: None,
fast_listing_admin_opt: None,
@ -1554,6 +1554,36 @@ impl ClientInstruction for GroupEditFeeParameters {
admin: self.admin.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
fn signers(&self) -> Vec<TestKeypair> {
vec![self.admin]
}
}
pub struct GroupEdit {
pub group: Pubkey,
pub admin: TestKeypair,
pub options: mango_v4::instruction::GroupEdit,
}
#[async_trait::async_trait(?Send)]
impl ClientInstruction for GroupEdit {
type Accounts = mango_v4::accounts::GroupEdit;
type Instruction = mango_v4::instruction::GroupEdit;
async fn to_instruction(
&self,
_account_loader: impl ClientAccountLoader + 'async_trait,
) -> (Self::Accounts, instruction::Instruction) {
let program_id = mango_v4::id();
let instruction = &self.options;
let accounts = Self::Accounts {
group: self.group,
admin: self.admin.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
(accounts, instruction)
}
@ -1586,7 +1616,7 @@ impl ClientInstruction for IxGateSetInstruction {
admin: self.admin.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1625,7 +1655,7 @@ impl ClientInstruction for GroupCloseInstruction {
token_program: Token::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1681,7 +1711,7 @@ impl ClientInstruction for AccountCreateInstruction {
system_program: System::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1735,7 +1765,7 @@ impl ClientInstruction for AccountExpandInstruction {
system_program: System::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1782,7 +1812,7 @@ impl ClientInstruction for AccountEditInstruction {
owner: self.owner.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1816,7 +1846,7 @@ impl ClientInstruction for AccountCloseInstruction {
token_program: Token::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1865,7 +1895,7 @@ impl ClientInstruction for AccountBuybackFeesWithMngo {
fees_oracle: fees_bank.oracle,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1934,7 +1964,7 @@ impl ClientInstruction for Serum3RegisterMarketInstruction {
system_program: System::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -1990,7 +2020,7 @@ impl ClientInstruction for Serum3DeregisterMarketInstruction {
token_program: Token::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -2041,7 +2071,7 @@ impl ClientInstruction for Serum3CreateOpenOrdersInstruction {
rent: sysvar::rent::Rent::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -2090,7 +2120,7 @@ impl ClientInstruction for Serum3CloseOpenOrdersInstruction {
sol_destination: self.sol_destination,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -2206,7 +2236,7 @@ impl ClientInstruction for Serum3PlaceOrderInstruction {
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -2275,7 +2305,7 @@ impl ClientInstruction for Serum3CancelOrderInstruction {
owner: self.owner.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -2336,7 +2366,7 @@ impl ClientInstruction for Serum3CancelAllOrdersInstruction {
owner: self.owner.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -2413,7 +2443,7 @@ impl ClientInstruction for Serum3SettleFundsInstruction {
token_program: Token::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -2499,7 +2529,7 @@ impl ClientInstruction for Serum3SettleFundsV2Instruction {
},
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -2589,7 +2619,7 @@ impl ClientInstruction for Serum3LiqForceCancelOrdersInstruction {
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -2652,7 +2682,7 @@ impl ClientInstruction for TokenForceCloseBorrowsWithTokenInstruction {
liqor_owner: self.liqor_owner.pubkey(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -2715,7 +2745,7 @@ impl ClientInstruction for TokenLiqWithTokenInstruction {
liqor_owner: self.liqor_owner.pubkey(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -2798,7 +2828,7 @@ impl ClientInstruction for TokenLiqBankruptcyInstruction {
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
let mut bank_ams = liab_mint_info
.banks()
.iter()
@ -2936,7 +2966,7 @@ impl ClientInstruction for PerpCreateMarketInstruction {
system_program: System::id(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3009,7 +3039,7 @@ impl ClientInstruction for PerpResetStablePriceModel {
oracle: perp_market.oracle,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3049,7 +3079,7 @@ impl ClientInstruction for PerpSetSettleLimitWindow {
oracle: perp_market.oracle,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3088,7 +3118,7 @@ impl ClientInstruction for PerpMakeReduceOnly {
oracle: perp_market.oracle,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3130,7 +3160,7 @@ impl ClientInstruction for PerpChangeWeights {
oracle: perp_market.oracle,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3167,7 +3197,7 @@ impl ClientInstruction for PerpCloseMarketInstruction {
sol_destination: self.sol_destination,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3200,7 +3230,7 @@ impl ClientInstruction for PerpDeactivatePositionInstruction {
owner: self.owner.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3265,7 +3295,7 @@ impl ClientInstruction for PerpPlaceOrderInstruction {
oracle: perp_market.oracle,
owner: self.owner.pubkey(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas);
(accounts, instruction)
@ -3334,7 +3364,7 @@ impl ClientInstruction for PerpPlaceOrderPeggedInstruction {
oracle: perp_market.oracle,
owner: self.owner.pubkey(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas);
(accounts, instruction)
@ -3373,7 +3403,7 @@ impl ClientInstruction for PerpCancelOrderInstruction {
owner: self.owner.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3410,7 +3440,7 @@ impl ClientInstruction for PerpCancelOrderByClientOrderIdInstruction {
owner: self.owner.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3444,7 +3474,7 @@ impl ClientInstruction for PerpCancelAllOrdersInstruction {
owner: self.owner.pubkey(),
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3475,7 +3505,7 @@ impl ClientInstruction for PerpConsumeEventsInstruction {
event_queue: perp_market.event_queue,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction
.accounts
.extend(self.mango_accounts.iter().map(|ma| AccountMeta {
@ -3515,7 +3545,7 @@ impl ClientInstruction for PerpUpdateFundingInstruction {
oracle: self.oracle,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3576,7 +3606,7 @@ impl ClientInstruction for PerpSettlePnlInstruction {
settle_oracle: settle_bank.oracle,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas);
(accounts, instruction)
@ -3629,7 +3659,7 @@ impl ClientInstruction for PerpSettleFeesInstruction {
settle_bank: self.settle_bank,
settle_oracle: settle_bank.oracle,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas);
(accounts, instruction)
@ -3676,7 +3706,7 @@ impl ClientInstruction for PerpLiqForceCancelOrdersInstruction {
bids: perp_market.bids,
asks: perp_market.asks,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas);
(accounts, instruction)
@ -3753,7 +3783,7 @@ impl ClientInstruction for PerpLiqBaseOrPositivePnlInstruction {
settle_vault: quote_mint_info.first_vault(),
settle_oracle: quote_mint_info.oracle,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas);
(accounts, instruction)
@ -3830,7 +3860,7 @@ impl ClientInstruction for PerpLiqNegativePnlOrBankruptcyInstruction {
insurance_vault: group.insurance_vault,
token_program: Token::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas);
(accounts, instruction)
@ -3854,7 +3884,7 @@ impl ClientInstruction for BenchmarkInstruction {
let instruction = Self::Instruction {};
let accounts = Self::Accounts {};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -3885,7 +3915,7 @@ impl ClientInstruction for TokenUpdateIndexAndRateInstruction {
instructions: solana_program::sysvar::instructions::id(),
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
let mut bank_ams = mint_info
.banks()
.iter()
@ -3938,7 +3968,7 @@ impl ClientInstruction for ComputeAccountDataInstruction {
account: self.account,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -3983,7 +4013,7 @@ impl ClientInstruction for HealthRegionBeginInstruction {
account: self.account,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -4027,7 +4057,7 @@ impl ClientInstruction for HealthRegionEndInstruction {
account: self.account,
};
let mut instruction = make_instruction(program_id, &accounts, instruction);
let mut instruction = make_instruction(program_id, &accounts, &instruction);
instruction.accounts.extend(health_check_metas.into_iter());
(accounts, instruction)
@ -4061,7 +4091,7 @@ impl ClientInstruction for AltSetInstruction {
address_lookup_table: self.address_lookup_table,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}
@ -4099,7 +4129,7 @@ impl ClientInstruction for AltExtendInstruction {
address_lookup_table: self.address_lookup_table,
};
let instruction = make_instruction(program_id, &accounts, instruction);
let instruction = make_instruction(program_id, &accounts, &instruction);
(accounts, instruction)
}