Add oracleProvider to Bank and PerpMarket (#491)
* Add oracleProvider to Bank and PerpMarket
This commit is contained in:
parent
fc1341f731
commit
da473b00b1
|
@ -3,6 +3,7 @@ import { utf8 } from '@coral-xyz/anchor/dist/cjs/utils/bytes';
|
|||
import { PublicKey } from '@solana/web3.js';
|
||||
import { I80F48, I80F48Dto, ZERO_I80F48 } from '../numbers/I80F48';
|
||||
import { As, toUiDecimals } from '../utils';
|
||||
import { OracleProvider } from './oracle';
|
||||
|
||||
export type TokenIndex = number & As<'token-index'>;
|
||||
|
||||
|
@ -58,6 +59,7 @@ export class Bank implements BankForHealth {
|
|||
public _price: I80F48 | undefined;
|
||||
public _uiPrice: number | undefined;
|
||||
public _oracleLastUpdatedSlot: number | undefined;
|
||||
public _oracleProvider: OracleProvider | undefined;
|
||||
public collectedFeesNative: I80F48;
|
||||
public loanFeeRate: I80F48;
|
||||
public loanOriginationFeeRate: I80F48;
|
||||
|
@ -235,6 +237,7 @@ export class Bank implements BankForHealth {
|
|||
this._price = undefined;
|
||||
this._uiPrice = undefined;
|
||||
this._oracleLastUpdatedSlot = undefined;
|
||||
this._oracleProvider = undefined;
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
|
@ -360,6 +363,15 @@ export class Bank implements BankForHealth {
|
|||
return this._oracleLastUpdatedSlot;
|
||||
}
|
||||
|
||||
get oracleProvider(): OracleProvider {
|
||||
if (!this._oracleProvider) {
|
||||
throw new Error(
|
||||
`Undefined oracleProvider for bank ${this.publicKey} with tokenIndex ${this.tokenIndex}!`,
|
||||
);
|
||||
}
|
||||
return this._oracleProvider;
|
||||
}
|
||||
|
||||
nativeDeposits(): I80F48 {
|
||||
return this.indexedDeposits.mul(this.depositIndex);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { Bank, MintInfo, TokenIndex } from './bank';
|
|||
import {
|
||||
isPythOracle,
|
||||
isSwitchboardOracle,
|
||||
OracleProvider,
|
||||
parseSwitchboardOracle,
|
||||
} from './oracle';
|
||||
import { BookSide, PerpMarket, PerpMarketIndex } from './perp';
|
||||
|
@ -331,7 +332,7 @@ export class Group {
|
|||
throw new Error(
|
||||
`Undefined accountInfo object in reloadBankOraclePrices for ${bank.oracle}!`,
|
||||
);
|
||||
const { price, uiPrice, lastUpdatedSlot } =
|
||||
const { price, uiPrice, lastUpdatedSlot, provider } =
|
||||
await this.decodePriceFromOracleAi(
|
||||
coder,
|
||||
bank.oracle,
|
||||
|
@ -342,6 +343,7 @@ export class Group {
|
|||
bank._price = price;
|
||||
bank._uiPrice = uiPrice;
|
||||
bank._oracleLastUpdatedSlot = lastUpdatedSlot;
|
||||
bank._oracleProvider = provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -366,7 +368,7 @@ export class Group {
|
|||
`Undefined ai object in reloadPerpMarketOraclePrices for ${perpMarket.oracle}!`,
|
||||
);
|
||||
|
||||
const { price, uiPrice, lastUpdatedSlot } =
|
||||
const { price, uiPrice, lastUpdatedSlot, provider } =
|
||||
await this.decodePriceFromOracleAi(
|
||||
coder,
|
||||
perpMarket.oracle,
|
||||
|
@ -377,6 +379,7 @@ export class Group {
|
|||
perpMarket._price = price;
|
||||
perpMarket._uiPrice = uiPrice;
|
||||
perpMarket._oracleLastUpdatedSlot = lastUpdatedSlot;
|
||||
perpMarket._oracleProvider = provider;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
@ -387,8 +390,13 @@ export class Group {
|
|||
ai: AccountInfo<Buffer>,
|
||||
baseDecimals: number,
|
||||
client: MangoClient,
|
||||
): Promise<{ price: I80F48; uiPrice: number; lastUpdatedSlot: number }> {
|
||||
let price, uiPrice, lastUpdatedSlot;
|
||||
): Promise<{
|
||||
price: I80F48;
|
||||
uiPrice: number;
|
||||
lastUpdatedSlot: number;
|
||||
provider: OracleProvider;
|
||||
}> {
|
||||
let price, uiPrice, lastUpdatedSlot, provider;
|
||||
if (
|
||||
!BorshAccountsCoder.accountDiscriminator('stubOracle').compare(
|
||||
ai.data.slice(0, 8),
|
||||
|
@ -398,11 +406,13 @@ export class Group {
|
|||
price = new I80F48(stubOracle.price.val);
|
||||
uiPrice = this.toUiPrice(price, baseDecimals);
|
||||
lastUpdatedSlot = stubOracle.lastUpdated.val;
|
||||
provider = OracleProvider.Stub;
|
||||
} else if (isPythOracle(ai)) {
|
||||
const priceData = parsePriceData(ai.data);
|
||||
uiPrice = priceData.previousPrice;
|
||||
price = this.toNativePrice(uiPrice, baseDecimals);
|
||||
lastUpdatedSlot = parseInt(priceData.lastSlot.toString());
|
||||
provider = OracleProvider.Pyth;
|
||||
} else if (isSwitchboardOracle(ai)) {
|
||||
const priceData = await parseSwitchboardOracle(
|
||||
ai,
|
||||
|
@ -411,12 +421,13 @@ export class Group {
|
|||
uiPrice = priceData.price;
|
||||
price = this.toNativePrice(uiPrice, baseDecimals);
|
||||
lastUpdatedSlot = priceData.lastUpdatedSlot;
|
||||
provider = OracleProvider.Switchboard;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Unknown oracle provider (parsing not implemented) for oracle ${oracle}, with owner ${ai.owner}!`,
|
||||
);
|
||||
}
|
||||
return { price, uiPrice, lastUpdatedSlot };
|
||||
return { price, uiPrice, lastUpdatedSlot, provider };
|
||||
}
|
||||
|
||||
public async reloadVaults(client: MangoClient): Promise<void> {
|
||||
|
|
|
@ -13,6 +13,12 @@ const SBV1_MAINNET_PID = new PublicKey(
|
|||
let sbv2DevnetProgram;
|
||||
let sbv2MainnetProgram;
|
||||
|
||||
export enum OracleProvider {
|
||||
Pyth,
|
||||
Switchboard,
|
||||
Stub,
|
||||
}
|
||||
|
||||
export class StubOracle {
|
||||
public price: I80F48;
|
||||
public lastUpdated: BN;
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
} from './bank';
|
||||
import { Group } from './group';
|
||||
import { MangoAccount } from './mangoAccount';
|
||||
import { OracleProvider } from './oracle';
|
||||
|
||||
export type PerpMarketIndex = number & As<'perp-market-index'>;
|
||||
|
||||
|
@ -55,6 +56,8 @@ export class PerpMarket {
|
|||
public _price: I80F48;
|
||||
public _uiPrice: number;
|
||||
public _oracleLastUpdatedSlot: number;
|
||||
public _oracleProvider: OracleProvider;
|
||||
|
||||
public _bids: BookSide;
|
||||
public _asks: BookSide;
|
||||
|
||||
|
@ -265,6 +268,15 @@ export class PerpMarket {
|
|||
return this._oracleLastUpdatedSlot;
|
||||
}
|
||||
|
||||
get oracleProvider(): OracleProvider {
|
||||
if (!this._oracleProvider) {
|
||||
throw new Error(
|
||||
`Undefined oracleProvider for perpMarket ${this.publicKey} with marketIndex ${this.perpMarketIndex}!`,
|
||||
);
|
||||
}
|
||||
return this._oracleProvider;
|
||||
}
|
||||
|
||||
get minOrderSize(): number {
|
||||
return this.baseLotsToUiConverter;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue