Skip to content

Commit 28b2315

Browse files
authored
Merge pull request #1745 from drift-labs/jordy/mm-oracle
updates
2 parents b25f215 + af129f8 commit 28b2315

File tree

5 files changed

+98
-30
lines changed

5 files changed

+98
-30
lines changed

programs/drift/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ no-entrypoint = []
1414
cpi = ["no-entrypoint"]
1515
mainnet-beta=[]
1616
anchor-test= []
17-
default=["mainnet-beta"]
17+
default=["mainnet-beta", "no-entrypoint"]
1818
drift-rs=[]
1919

2020
[dependencies]

programs/drift/src/instructions/admin.rs

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
use std::convert::identity;
22
use std::mem::size_of;
33

4-
use crate::math::amm::calculate_amm_available_liquidity;
5-
use crate::{compute_fn, msg};
4+
use crate::msg;
65
use anchor_lang::prelude::*;
7-
use anchor_spl::token::Token;
86
use anchor_spl::token_2022::Token2022;
97
use anchor_spl::token_interface::{Mint, TokenAccount, TokenInterface};
108
use phoenix::quantities::WrapperU64;
@@ -19,13 +17,12 @@ use crate::instructions::constraints::*;
1917
use crate::instructions::optional_accounts::{load_maps, AccountMaps};
2018
use crate::math::casting::Cast;
2119
use crate::math::constants::{
22-
AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO, AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO_I128,
23-
DEFAULT_LIQUIDATION_MARGIN_BUFFER_RATIO, FEE_POOL_TO_REVENUE_POOL_THRESHOLD,
24-
IF_FACTOR_PRECISION, INSURANCE_A_MAX, INSURANCE_B_MAX, INSURANCE_C_MAX,
25-
INSURANCE_SPECULATIVE_MAX, LIQUIDATION_FEE_PRECISION, MAX_CONCENTRATION_COEFFICIENT,
26-
MAX_SQRT_K, MAX_UPDATE_K_PRICE_CHANGE, PERCENTAGE_PRECISION, PERCENTAGE_PRECISION_I64,
27-
QUOTE_SPOT_MARKET_INDEX, SPOT_CUMULATIVE_INTEREST_PRECISION, SPOT_IMF_PRECISION,
28-
SPOT_WEIGHT_PRECISION, THIRTEEN_DAY, TWENTY_FOUR_HOUR,
20+
AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO, DEFAULT_LIQUIDATION_MARGIN_BUFFER_RATIO,
21+
FEE_POOL_TO_REVENUE_POOL_THRESHOLD, IF_FACTOR_PRECISION, INSURANCE_A_MAX, INSURANCE_B_MAX,
22+
INSURANCE_C_MAX, INSURANCE_SPECULATIVE_MAX, LIQUIDATION_FEE_PRECISION,
23+
MAX_CONCENTRATION_COEFFICIENT, MAX_SQRT_K, MAX_UPDATE_K_PRICE_CHANGE, PERCENTAGE_PRECISION,
24+
PERCENTAGE_PRECISION_I64, QUOTE_SPOT_MARKET_INDEX, SPOT_CUMULATIVE_INTEREST_PRECISION,
25+
SPOT_IMF_PRECISION, SPOT_WEIGHT_PRECISION, THIRTEEN_DAY, TWENTY_FOUR_HOUR,
2926
};
3027
use crate::math::cp_curve::get_update_k_result;
3128
use crate::math::helpers::get_proportion_u128;
@@ -4860,27 +4857,18 @@ pub fn handle_update_mm_oracle(ctx: Context<Empty>, oracle_price: i64) -> Result
48604857
Ok(())
48614858
}
48624859

4863-
pub fn handle_update_mm_oracle_native(accounts: &[AccountInfo], oracle_price: i64) -> Result<()> {
4864-
::solana_program::log::sol_log_compute_units();
4865-
4866-
let accounts_iter = &mut accounts.iter();
4867-
let perp_market_account = next_account_info(accounts_iter)?;
4868-
let signer_account = next_account_info(accounts_iter)?;
4869-
4870-
validate!(
4871-
*signer_account.key == admin_hot_wallet::id() && signer_account.is_signer,
4872-
ErrorCode::DefaultError,
4860+
pub fn handle_update_mm_oracle_native(accounts: &[AccountInfo], data: &[u8]) -> Result<()> {
4861+
let signer_account = &accounts[1];
4862+
#[cfg(not(feature = "anchor-test"))]
4863+
assert!(
4864+
signer_account.is_signer && *signer_account.key == admin_hot_wallet::id(),
48734865
"signer must be admin hot wallet, signer: {}, admin hot wallet: {}",
48744866
signer_account.key,
48754867
admin_hot_wallet::id()
4876-
)?;
4877-
4878-
let mut data = perp_market_account
4879-
.try_borrow_mut_data()
4880-
.or(Err(ErrorCode::DefaultError))?;
4881-
4882-
data[828..840].copy_from_slice(&Clock::get()?.slot.to_le_bytes());
4883-
data[912..920].copy_from_slice(oracle_price.to_le_bytes().as_ref());
4868+
);
4869+
let mut perp_market = accounts[0].data.borrow_mut();
4870+
perp_market[832..840].copy_from_slice(&data[5..5 + 8]);
4871+
perp_market[912..920].copy_from_slice(&data[13..13 + 8]);
48844872

48854873
Ok(())
48864874
}

programs/drift/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,23 @@ pub mod state;
3434
mod test_utils;
3535
mod validation;
3636

37+
// main program entrypoint
38+
// anchor `#[program]` entrypoint is compiled out by `no-entrypoint`
39+
solana_program::entrypoint!(program_entry);
40+
41+
pub fn program_entry<'info>(
42+
program_id: &Pubkey,
43+
accounts: &'info [AccountInfo<'info>],
44+
data: &[u8],
45+
) -> anchor_lang::solana_program::entrypoint::ProgramResult {
46+
if data.len() > 5 && data[..5] == [0xFF, 0xFF, 0xFF, 0xFF, 0] {
47+
// total ~509 CU without clock (-278)
48+
return handle_update_mm_oracle_native(accounts, &data).map_err(Into::into);
49+
}
50+
// hook into anchor generated entry
51+
entry(program_id, accounts, data)
52+
}
53+
3754
#[cfg(feature = "mainnet-beta")]
3855
declare_id!("dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH");
3956
#[cfg(not(feature = "mainnet-beta"))]

sdk/src/adminClient.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4567,6 +4567,55 @@ export class AdminClient extends DriftClient {
45674567
return txSig;
45684568
}
45694569

4570+
public async updateMmOracleNative(
4571+
marketIndex: number,
4572+
slot: BN,
4573+
oraclePrice: BN
4574+
): Promise<TransactionSignature> {
4575+
const updateMmOracleIx = await this.getUpdateMmOracleNativeIx(
4576+
marketIndex,
4577+
slot,
4578+
oraclePrice
4579+
);
4580+
4581+
const tx = await this.buildTransaction(updateMmOracleIx, {
4582+
computeUnits: 1024,
4583+
computeUnitsPrice: 0,
4584+
});
4585+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
4586+
4587+
return txSig;
4588+
}
4589+
4590+
public getUpdateMmOracleNativeIx(
4591+
marketIndex: number,
4592+
slot: BN,
4593+
oraclePrice: BN
4594+
): TransactionInstruction {
4595+
const data = Buffer.alloc(5 + 8 + 8);
4596+
data.set([0xff, 0xff, 0xff, 0xff, 0x00], 0); // 5 bytes
4597+
data.set(slot.toArrayLike(Buffer, 'le', 8), 5); // next 8 bytes
4598+
data.set(oraclePrice.toArrayLike(Buffer, 'le', 8), 13); // next 8 bytes
4599+
4600+
// Build the instruction manually
4601+
return new TransactionInstruction({
4602+
programId: this.program.programId,
4603+
keys: [
4604+
{
4605+
pubkey: this.getPerpMarketAccount(marketIndex).pubkey,
4606+
isWritable: true,
4607+
isSigner: false,
4608+
},
4609+
{
4610+
pubkey: this.wallet.publicKey,
4611+
isWritable: false,
4612+
isSigner: true,
4613+
},
4614+
],
4615+
data,
4616+
});
4617+
}
4618+
45704619
public async getUpdateMmOracleIx(
45714620
marketIndex: number,
45724621
oraclePrice: BN

tests/admin.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ import {
2020
mockOracleNoProgram,
2121
mockUSDCMint,
2222
} from './testHelpers';
23-
import { PublicKey } from '@solana/web3.js';
23+
import {
24+
PublicKey,
25+
Transaction,
26+
TransactionInstruction,
27+
} from '@solana/web3.js';
2428
import {
2529
BankrunContextWrapper,
2630
Connection,
@@ -415,6 +419,16 @@ describe('admin', () => {
415419
assert(perpMarket.amm.mmOraclePrice.eq(oraclePrice));
416420
});
417421

422+
it('update MM oracle native', async () => {
423+
const oraclePrice = new BN(100);
424+
const slot = new BN(123456);
425+
await driftClient.updateMmOracleNative(0, slot, oraclePrice);
426+
427+
const perpMarket = driftClient.getPerpMarketAccount(0);
428+
assert(perpMarket.amm.mmOraclePrice.eq(oraclePrice));
429+
assert(perpMarket.amm.mmOracleSlot.eq(slot));
430+
});
431+
418432
it('Update admin', async () => {
419433
const newAdminKey = PublicKey.default;
420434

0 commit comments

Comments
 (0)