token register trustless
Signed-off-by: microwavedcola1 <microwavedcola@gmail.com>
This commit is contained in:
parent
d3a634c709
commit
e31ad9ce34
|
@ -37,6 +37,7 @@ pub use token_deposit::*;
|
|||
pub use token_deregister::*;
|
||||
pub use token_edit::*;
|
||||
pub use token_register::*;
|
||||
pub use token_register_trustless::*;
|
||||
pub use token_update_index_and_rate::*;
|
||||
pub use token_withdraw::*;
|
||||
|
||||
|
@ -79,5 +80,6 @@ mod token_deposit;
|
|||
mod token_deregister;
|
||||
mod token_edit;
|
||||
mod token_register;
|
||||
mod token_register_trustless;
|
||||
mod token_update_index_and_rate;
|
||||
mod token_withdraw;
|
||||
|
|
|
@ -61,7 +61,7 @@ pub struct TokenRegister<'info> {
|
|||
pub rent: Sysvar<'info, Rent>,
|
||||
}
|
||||
|
||||
#[derive(AnchorSerialize, AnchorDeserialize, Default)]
|
||||
#[derive(AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct InterestRateParams {
|
||||
pub util0: f32,
|
||||
pub rate0: f32,
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
use anchor_lang::prelude::*;
|
||||
use anchor_spl::token::{Mint, Token, TokenAccount};
|
||||
use fixed::types::I80F48;
|
||||
use fixed_macro::types::I80F48;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::instructions::{InterestRateParams, INDEX_START};
|
||||
use crate::state::*;
|
||||
use crate::util::fill16_from_str;
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(token_index: TokenIndex, bank_num: u32)]
|
||||
pub struct TokenRegisterTrustless<'info> {
|
||||
#[account(
|
||||
has_one = fast_listing_admin,
|
||||
)]
|
||||
pub group: AccountLoader<'info, Group>,
|
||||
pub fast_listing_admin: Signer<'info>,
|
||||
|
||||
pub mint: Account<'info, Mint>,
|
||||
|
||||
#[account(
|
||||
init,
|
||||
// using the token_index in this seed guards against reusing it
|
||||
seeds = [group.key().as_ref(), b"Bank".as_ref(), &token_index.to_le_bytes(), &bank_num.to_le_bytes()],
|
||||
bump,
|
||||
payer = payer,
|
||||
space = 8 + std::mem::size_of::<Bank>(),
|
||||
)]
|
||||
pub bank: AccountLoader<'info, Bank>,
|
||||
|
||||
#[account(
|
||||
init,
|
||||
seeds = [group.key().as_ref(), b"Vault".as_ref(), &token_index.to_le_bytes(), &bank_num.to_le_bytes()],
|
||||
bump,
|
||||
token::authority = group,
|
||||
token::mint = mint,
|
||||
payer = payer
|
||||
)]
|
||||
pub vault: Account<'info, TokenAccount>,
|
||||
|
||||
#[account(
|
||||
init,
|
||||
// using the mint in this seed guards against registering the same mint twice
|
||||
seeds = [group.key().as_ref(), b"MintInfo".as_ref(), mint.key().as_ref()],
|
||||
bump,
|
||||
payer = payer,
|
||||
space = 8 + std::mem::size_of::<MintInfo>(),
|
||||
)]
|
||||
pub mint_info: AccountLoader<'info, MintInfo>,
|
||||
|
||||
/// CHECK: The oracle can be one of several different account types
|
||||
pub oracle: UncheckedAccount<'info>,
|
||||
|
||||
#[account(mut)]
|
||||
pub payer: Signer<'info>,
|
||||
|
||||
pub token_program: Program<'info, Token>,
|
||||
pub system_program: Program<'info, System>,
|
||||
pub rent: Sysvar<'info, Rent>,
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn token_register_trustless(
|
||||
ctx: Context<TokenRegisterTrustless>,
|
||||
token_index: TokenIndex,
|
||||
bank_num: u32,
|
||||
name: String,
|
||||
) -> Result<()> {
|
||||
require_eq!(bank_num, 0);
|
||||
require_neq!(token_index, 0);
|
||||
|
||||
let mut bank = ctx.accounts.bank.load_init()?;
|
||||
*bank = Bank {
|
||||
group: ctx.accounts.group.key(),
|
||||
name: fill16_from_str(name)?,
|
||||
mint: ctx.accounts.mint.key(),
|
||||
vault: ctx.accounts.vault.key(),
|
||||
oracle: ctx.accounts.oracle.key(),
|
||||
oracle_config: OracleConfig {
|
||||
conf_filter: I80F48::from_num(0.10),
|
||||
},
|
||||
deposit_index: INDEX_START,
|
||||
borrow_index: INDEX_START,
|
||||
cached_indexed_total_deposits: I80F48::ZERO,
|
||||
cached_indexed_total_borrows: I80F48::ZERO,
|
||||
indexed_deposits: I80F48::ZERO,
|
||||
indexed_borrows: I80F48::ZERO,
|
||||
index_last_updated: Clock::get()?.unix_timestamp,
|
||||
bank_rate_last_updated: Clock::get()?.unix_timestamp,
|
||||
avg_utilization: I80F48::ZERO,
|
||||
adjustment_factor: I80F48::from_num(0.001),
|
||||
util0: I80F48::from_num(0.6),
|
||||
rate0: I80F48::from_num(0.15),
|
||||
util1: I80F48::from_num(0.8),
|
||||
rate1: I80F48::from_num(0.95),
|
||||
max_rate: I80F48::from_num(3.0),
|
||||
collected_fees_native: I80F48::ZERO,
|
||||
loan_origination_fee_rate: I80F48::from_num(0.005),
|
||||
loan_fee_rate: I80F48::from_num(0.005),
|
||||
maint_asset_weight: I80F48::from_num(0),
|
||||
init_asset_weight: I80F48::from_num(0),
|
||||
maint_liab_weight: I80F48::from_num(1.4),
|
||||
init_liab_weight: I80F48::from_num(1.5),
|
||||
liquidation_fee: I80F48::from_num(0.2),
|
||||
dust: I80F48::ZERO,
|
||||
flash_loan_vault_initial: u64::MAX,
|
||||
flash_loan_approved_amount: 0,
|
||||
token_index,
|
||||
bump: *ctx.bumps.get("bank").ok_or(MangoError::SomeError)?,
|
||||
mint_decimals: ctx.accounts.mint.decimals,
|
||||
bank_num: 0,
|
||||
reserved: [0; 256],
|
||||
};
|
||||
|
||||
let mut mint_info = ctx.accounts.mint_info.load_init()?;
|
||||
*mint_info = MintInfo {
|
||||
group: ctx.accounts.group.key(),
|
||||
token_index,
|
||||
padding1: Default::default(),
|
||||
mint: ctx.accounts.mint.key(),
|
||||
banks: Default::default(),
|
||||
vaults: Default::default(),
|
||||
oracle: ctx.accounts.oracle.key(),
|
||||
registration_time: Clock::get()?.unix_timestamp,
|
||||
reserved: [0; 256],
|
||||
};
|
||||
|
||||
mint_info.banks[0] = ctx.accounts.bank.key();
|
||||
mint_info.vaults[0] = ctx.accounts.vault.key();
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -86,6 +86,15 @@ pub mod mango_v4 {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn token_register_trustless(
|
||||
ctx: Context<TokenRegisterTrustless>,
|
||||
token_index: TokenIndex,
|
||||
bank_num: u32,
|
||||
name: String,
|
||||
) -> Result<()> {
|
||||
instructions::token_register_trustless(ctx, token_index, bank_num, name)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn token_edit(
|
||||
ctx: Context<TokenEdit>,
|
||||
|
|
|
@ -88,6 +88,20 @@ export class MangoClient {
|
|||
.rpc();
|
||||
}
|
||||
|
||||
public async groupEdit(
|
||||
group: Group,
|
||||
newAdmin: PublicKey,
|
||||
newFastListingAdmin: PublicKey,
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.program.methods
|
||||
.groupEdit(newAdmin, newFastListingAdmin)
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
admin: (this.program.provider as AnchorProvider).wallet.publicKey,
|
||||
})
|
||||
.rpc();
|
||||
}
|
||||
|
||||
public async groupClose(group: Group): Promise<TransactionSignature> {
|
||||
const adminPk = (this.program.provider as AnchorProvider).wallet.publicKey;
|
||||
return await this.program.methods
|
||||
|
@ -193,6 +207,27 @@ export class MangoClient {
|
|||
.rpc();
|
||||
}
|
||||
|
||||
public async tokenRegisterTrustless(
|
||||
group: Group,
|
||||
mintPk: PublicKey,
|
||||
oraclePk: PublicKey,
|
||||
tokenIndex: number,
|
||||
name: string,
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.program.methods
|
||||
.tokenRegisterTrustless(tokenIndex, 0, name)
|
||||
.accounts({
|
||||
group: group.publicKey,
|
||||
fastListingAdmin: (this.program.provider as AnchorProvider).wallet
|
||||
.publicKey,
|
||||
mint: mintPk,
|
||||
oracle: oraclePk,
|
||||
payer: (this.program.provider as AnchorProvider).wallet.publicKey,
|
||||
rent: SYSVAR_RENT_PUBKEY,
|
||||
})
|
||||
.rpc();
|
||||
}
|
||||
|
||||
public async tokenEdit(
|
||||
group: Group,
|
||||
tokenName: string,
|
||||
|
|
|
@ -332,6 +332,148 @@ export type MangoV4 = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tokenRegisterTrustless",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "fastListingAdmin",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "bank",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"type": "publicKey",
|
||||
"path": "group"
|
||||
},
|
||||
{
|
||||
"kind": "const",
|
||||
"type": "string",
|
||||
"value": "Bank"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"type": "u16",
|
||||
"path": "token_index"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"type": "u32",
|
||||
"path": "bank_num"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vault",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"type": "publicKey",
|
||||
"path": "group"
|
||||
},
|
||||
{
|
||||
"kind": "const",
|
||||
"type": "string",
|
||||
"value": "Vault"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"type": "u16",
|
||||
"path": "token_index"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"type": "u32",
|
||||
"path": "bank_num"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "mintInfo",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"type": "publicKey",
|
||||
"path": "group"
|
||||
},
|
||||
{
|
||||
"kind": "const",
|
||||
"type": "string",
|
||||
"value": "MintInfo"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"type": "publicKey",
|
||||
"account": "Mint",
|
||||
"path": "mint"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "oracle",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"isMut": true,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "rent",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "tokenIndex",
|
||||
"type": "u16"
|
||||
},
|
||||
{
|
||||
"name": "bankNum",
|
||||
"type": "u32"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tokenEdit",
|
||||
"accounts": [
|
||||
|
@ -5198,6 +5340,148 @@ export const IDL: MangoV4 = {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tokenRegisterTrustless",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "group",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "fastListingAdmin",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "bank",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"type": "publicKey",
|
||||
"path": "group"
|
||||
},
|
||||
{
|
||||
"kind": "const",
|
||||
"type": "string",
|
||||
"value": "Bank"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"type": "u16",
|
||||
"path": "token_index"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"type": "u32",
|
||||
"path": "bank_num"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "vault",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"type": "publicKey",
|
||||
"path": "group"
|
||||
},
|
||||
{
|
||||
"kind": "const",
|
||||
"type": "string",
|
||||
"value": "Vault"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"type": "u16",
|
||||
"path": "token_index"
|
||||
},
|
||||
{
|
||||
"kind": "arg",
|
||||
"type": "u32",
|
||||
"path": "bank_num"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "mintInfo",
|
||||
"isMut": true,
|
||||
"isSigner": false,
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "account",
|
||||
"type": "publicKey",
|
||||
"path": "group"
|
||||
},
|
||||
{
|
||||
"kind": "const",
|
||||
"type": "string",
|
||||
"value": "MintInfo"
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"type": "publicKey",
|
||||
"account": "Mint",
|
||||
"path": "mint"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "oracle",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"isMut": true,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "rent",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "tokenIndex",
|
||||
"type": "u16"
|
||||
},
|
||||
{
|
||||
"name": "bankNum",
|
||||
"type": "u32"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "tokenEdit",
|
||||
"accounts": [
|
||||
|
|
|
@ -23,11 +23,13 @@ const DEVNET_MINTS = new Map([
|
|||
['BTC', '3UNBZ6o52WTWwjac2kPUb4FyodhU1vFkRJheu1Sh2TvU'],
|
||||
['SOL', 'So11111111111111111111111111111111111111112'],
|
||||
['ORCA', 'orcarKHSqC5CDDsGbho8GKvwExejWHxTqGzXgcewB9L'],
|
||||
['MNGO', 'Bb9bsTQa1bGEtQ5KagGkvSHyuLqDWumFUcRqFusFNJWC'],
|
||||
]);
|
||||
const DEVNET_ORACLES = new Map([
|
||||
['BTC', 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J'],
|
||||
['SOL', 'J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix'],
|
||||
['ORCA', 'A1WttWF7X3Rg6ZRpB2YQUFHCRh1kiXV8sKKLV3S9neJV'],
|
||||
['MNGO', '8k7F9Xb36oFJsjpCKpsXvg4cgBRoZtwNTc3EzG5Ttd2o'],
|
||||
]);
|
||||
|
||||
const GROUP_NUM = Number(process.env.GROUP_NUM || 0);
|
||||
|
@ -64,37 +66,6 @@ async function main() {
|
|||
const group = await client.getGroupForAdmin(admin.publicKey, GROUP_NUM);
|
||||
console.log(`...registered group ${group.publicKey}`);
|
||||
|
||||
// register token 1
|
||||
console.log(`Registering BTC...`);
|
||||
const btcDevnetMint = new PublicKey(DEVNET_MINTS.get('BTC')!);
|
||||
const btcDevnetOracle = new PublicKey(DEVNET_ORACLES.get('BTC')!);
|
||||
try {
|
||||
await client.tokenRegister(
|
||||
group,
|
||||
btcDevnetMint,
|
||||
btcDevnetOracle,
|
||||
0.1,
|
||||
1, // tokenIndex
|
||||
'BTC',
|
||||
0.01,
|
||||
0.4,
|
||||
0.07,
|
||||
0.8,
|
||||
0.9,
|
||||
0.88,
|
||||
0.0005,
|
||||
0.0005,
|
||||
0.8,
|
||||
0.6,
|
||||
1.2,
|
||||
1.4,
|
||||
0.02,
|
||||
);
|
||||
await group.reloadAll(client);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
// stub oracle + register token 0
|
||||
console.log(`Registering USDC...`);
|
||||
const usdcDevnetMint = new PublicKey(DEVNET_MINTS.get('USDC')!);
|
||||
|
@ -132,6 +103,37 @@ async function main() {
|
|||
await group.reloadAll(client);
|
||||
} catch (error) {}
|
||||
|
||||
// register token 1
|
||||
console.log(`Registering BTC...`);
|
||||
const btcDevnetMint = new PublicKey(DEVNET_MINTS.get('BTC')!);
|
||||
const btcDevnetOracle = new PublicKey(DEVNET_ORACLES.get('BTC')!);
|
||||
try {
|
||||
await client.tokenRegister(
|
||||
group,
|
||||
btcDevnetMint,
|
||||
btcDevnetOracle,
|
||||
0.1,
|
||||
1, // tokenIndex
|
||||
'BTC',
|
||||
0.01,
|
||||
0.4,
|
||||
0.07,
|
||||
0.8,
|
||||
0.9,
|
||||
0.88,
|
||||
0.0005,
|
||||
0.0005,
|
||||
0.8,
|
||||
0.6,
|
||||
1.2,
|
||||
1.4,
|
||||
0.02,
|
||||
);
|
||||
await group.reloadAll(client);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
// register token 2
|
||||
console.log(`Registering SOL...`);
|
||||
const solDevnetMint = new PublicKey(DEVNET_MINTS.get('SOL')!);
|
||||
|
@ -194,11 +196,33 @@ async function main() {
|
|||
console.log(error);
|
||||
}
|
||||
|
||||
// register token 4
|
||||
console.log(
|
||||
`Editing group, setting existing admin as fastListingAdmin to be able to add MNGO truslessly...`,
|
||||
);
|
||||
await client.groupEdit(group, group.admin, group.admin);
|
||||
console.log(`Registering MNGO...`);
|
||||
const mngoDevnetMint = new PublicKey(DEVNET_MINTS.get('MNGO')!);
|
||||
const mngoDevnetOracle = new PublicKey(DEVNET_ORACLES.get('MNGO')!);
|
||||
try {
|
||||
await client.tokenRegisterTrustless(
|
||||
group,
|
||||
mngoDevnetMint,
|
||||
mngoDevnetOracle,
|
||||
4,
|
||||
'MNGO',
|
||||
);
|
||||
await group.reloadAll(client);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
// log tokens/banks
|
||||
for (const bank of await group.banksMap.values()) {
|
||||
console.log(
|
||||
`...registered Bank ${bank.tokenIndex} ${bank.publicKey}, mint ${bank.mint}, oracle ${bank.oracle}`,
|
||||
);
|
||||
console.log(bank.toString());
|
||||
}
|
||||
|
||||
// register serum market
|
||||
|
|
Loading…
Reference in New Issue