Skip to content

Commit

Permalink
sdk: add fuel-if-test (#1144)
Browse files Browse the repository at this point in the history
* sdk: add fuel-if-test

* add FUEL_START_TS logic to last_fuel_if_bonus_update_ts
  • Loading branch information
0xbigz authored Jul 16, 2024
1 parent 870f57b commit 64ab59a
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 21 deletions.
10 changes: 7 additions & 3 deletions programs/drift/src/controller/insurance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use crate::state::perp_market::PerpMarket;
use crate::state::spot_market::{SpotBalanceType, SpotMarket};
use crate::state::state::State;
use crate::state::user::UserStats;
use crate::{emit, validate, GOV_SPOT_MARKET_INDEX, QUOTE_SPOT_MARKET_INDEX};
use crate::{emit, validate, FUEL_START_TS, GOV_SPOT_MARKET_INDEX, QUOTE_SPOT_MARKET_INDEX};

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -71,9 +71,13 @@ pub fn update_user_stats_if_stake_amount(
user_stats.if_staked_gov_token_amount = if_stake_amount;
}

if spot_market.fuel_boost_insurance != 0 {
if spot_market.fuel_boost_insurance != 0 && now >= FUEL_START_TS {
let now_u32: u32 = now.cast()?;
let since_last = now_u32.safe_sub(user_stats.last_fuel_if_bonus_update_ts)?;
let since_last = now_u32.safe_sub(
user_stats
.last_fuel_if_bonus_update_ts
.max(FUEL_START_TS.cast()?),
)?;

// calculate their stake amount prior to update
let fuel_bonus_insurance = if_stake_amount
Expand Down
20 changes: 10 additions & 10 deletions programs/drift/src/instructions/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3531,57 +3531,57 @@ pub fn handle_update_spot_market_fuel(

if let Some(fuel_boost_taker) = fuel_boost_taker {
msg!(
"perp_market.fuel_boost_taker: {:?} -> {:?}",
"spot_market.fuel_boost_taker: {:?} -> {:?}",
spot_market.fuel_boost_taker,
fuel_boost_taker
);
spot_market.fuel_boost_taker = fuel_boost_taker;
} else {
msg!("perp_market.fuel_boost_taker: unchanged");
msg!("spot_market.fuel_boost_taker: unchanged");
}

if let Some(fuel_boost_maker) = fuel_boost_maker {
msg!(
"perp_market.fuel_boost_maker: {:?} -> {:?}",
"spot_market.fuel_boost_maker: {:?} -> {:?}",
spot_market.fuel_boost_maker,
fuel_boost_maker
);
spot_market.fuel_boost_maker = fuel_boost_maker;
} else {
msg!("perp_market.fuel_boost_maker: unchanged");
msg!("spot_market.fuel_boost_maker: unchanged");
}

if let Some(fuel_boost_deposits) = fuel_boost_deposits {
msg!(
"perp_market.fuel_boost_deposits: {:?} -> {:?}",
"spot_market.fuel_boost_deposits: {:?} -> {:?}",
spot_market.fuel_boost_deposits,
fuel_boost_deposits
);
spot_market.fuel_boost_deposits = fuel_boost_deposits;
} else {
msg!("perp_market.fuel_boost_deposits: unchanged");
msg!("spot_market.fuel_boost_deposits: unchanged");
}

if let Some(fuel_boost_borrows) = fuel_boost_borrows {
msg!(
"perp_market.fuel_boost_borrows: {:?} -> {:?}",
"spot_market.fuel_boost_borrows: {:?} -> {:?}",
spot_market.fuel_boost_borrows,
fuel_boost_borrows
);
spot_market.fuel_boost_borrows = fuel_boost_borrows;
} else {
msg!("perp_market.fuel_boost_borrows: unchanged");
msg!("spot_market.fuel_boost_borrows: unchanged");
}

if let Some(fuel_boost_insurance) = fuel_boost_insurance {
msg!(
"perp_market.fuel_boost_insurance: {:?} -> {:?}",
"spot_market.fuel_boost_insurance: {:?} -> {:?}",
spot_market.fuel_boost_insurance,
fuel_boost_insurance
);
spot_market.fuel_boost_insurance = fuel_boost_insurance;
} else {
msg!("perp_market.fuel_boost_insurance: unchanged");
msg!("spot_market.fuel_boost_insurance: unchanged");
}

Ok(())
Expand Down
3 changes: 0 additions & 3 deletions programs/drift/src/math/amm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -848,9 +848,6 @@ pub fn calculate_expiry_price(
return Ok(target_price);
}

// use crate::dlog!(amm
// .quote_asset_amount, pnl_pool_amount, amm.base_asset_amount_with_amm);

// net_baa * price + net_quote <= 0
// net_quote/net_baa <= -price

Expand Down
2 changes: 1 addition & 1 deletion sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -887,7 +887,7 @@ export type UserStatsAccount = {
authority: PublicKey;
ifStakedQuoteAssetAmount: BN;

lastFuelBonusUpdateTs: number; // u32 onchain
lastFuelIfBonusUpdateTs: number; // u32 onchain

fuelInsurance: number;
fuelDeposits: number;
Expand Down
19 changes: 18 additions & 1 deletion sdk/src/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,7 @@ export class User {
this.driftClient.getSpotMarketAccount(GOV_SPOT_MARKET_INDEX);

const fuelBonusNumeratorUserStats = now.sub(
new BN(userStats.lastFuelBonusUpdateTs)
BN.max(new BN(userStats.lastFuelIfBonusUpdateTs), FUEL_START_TS)
);

result.insuranceFuel = result.insuranceFuel.add(
Expand All @@ -1022,6 +1022,23 @@ export class User {
)
);
}

if (userStats.ifStakedQuoteAssetAmount.gt(ZERO)) {
const spotMarketAccount: SpotMarketAccount =
this.driftClient.getSpotMarketAccount(QUOTE_SPOT_MARKET_INDEX);

const fuelBonusNumeratorUserStats = now.sub(
BN.max(new BN(userStats.lastFuelIfBonusUpdateTs), FUEL_START_TS)
);

result.insuranceFuel = result.insuranceFuel.add(
calculateInsuranceFuelBonus(
spotMarketAccount,
userStats.ifStakedQuoteAssetAmount,
fuelBonusNumeratorUserStats
)
);
}
}

return result;
Expand Down
133 changes: 130 additions & 3 deletions tests/fuel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
User,
Wallet,
BASE_PRECISION,
UserStatsAccount,
getLimitOrderParams,
OracleSource,
ONE,
Expand All @@ -34,7 +35,7 @@ import { startAnchor } from 'solana-bankrun';
import { TestBulkAccountLoader } from '../sdk/src/accounts/testBulkAccountLoader';
import { BankrunContextWrapper } from '../sdk/src/bankrun/bankrunConnection';

describe('place and fill spot order', () => {
describe("fuelin'", () => {
const chProgram = anchor.workspace.Drift as Program;

let fillerDriftClient: TestClient;
Expand Down Expand Up @@ -63,7 +64,7 @@ describe('place and fill spot order', () => {
const wallet = new Wallet(keypair);
const userUSDCAccount = await mockUserUSDCAccount(
usdcMint,
usdcAmount,
usdcAmount.muln(100),
bankrunContextWrapper,
keypair.publicKey
);
Expand Down Expand Up @@ -115,7 +116,7 @@ describe('place and fill spot order', () => {
usdcMint = await mockUSDCMint(bankrunContextWrapper);
userUSDCAccount = await mockUserUSDCAccount(
usdcMint,
usdcAmount,
usdcAmount.muln(10),
bankrunContextWrapper
);

Expand Down Expand Up @@ -211,6 +212,132 @@ describe('place and fill spot order', () => {
await fillerDriftClientUser.unsubscribe();
});

it('fuel for staking', async () => {
const [takerDriftClient, _takerUSDCAccount] = await createTestClient({
referrer: fillerDriftClientUser.getUserAccount().authority,
referrerStats: fillerDriftClient.getUserStatsAccountPublicKey(),
});
const takerDriftClientUser = new User({
driftClient: takerDriftClient,
userAccountPublicKey: await takerDriftClient.getUserAccountPublicKey(),
accountSubscription: {
type: 'polling',
accountLoader: bulkAccountLoader,
},
});
await takerDriftClientUser.subscribe();

const marketIndex = 0;

const txSig = await takerDriftClient.addInsuranceFundStake({
marketIndex: marketIndex,
amount: usdcAmount,
collateralAccountPublicKey: _takerUSDCAccount.publicKey,
initializeStakeAccount: true,
});
bankrunContextWrapper.connection.printTxLogs(txSig);
await takerDriftClient.fetchAccounts();

const takerUserStats: UserStatsAccount = takerDriftClient
.getUserStats()
.getAccount();

console.log(takerUserStats);
assert(takerUserStats.ifStakedQuoteAssetAmount.gt(ZERO));

await fillerDriftClient.updateSpotMarketFuel(0, 100, 200, 200, 0, 250);
const currentClockInit =
await bankrunContextWrapper.context.banksClient.getClock();

await takerDriftClient.fetchAccounts();
assert(takerDriftClient.getSpotMarketAccount(0).fuelBoostInsurance > 0);

const fuelDictInit = takerDriftClientUser.getFuelBonus(
new BN(currentClockInit.unixTimestamp.toString()).addn(36000),
true,
true
);

console.log(fuelDictInit);
assert(fuelDictInit['insuranceFuel'].gt(ZERO));

const timeProgress = 36000; // 30 days in seconds

await bankrunContextWrapper.moveTimeForward(timeProgress);

const _ = await takerDriftClient.requestRemoveInsuranceFundStake(
marketIndex,
usdcAmount.divn(3)
);

const currentClockInit2 =
await bankrunContextWrapper.context.banksClient.getClock();

const fuelDictInit2 = takerDriftClientUser.getFuelBonus(
new BN(currentClockInit2.unixTimestamp.toString()),
true,
true
);

console.log(fuelDictInit2);
assert(fuelDictInit2['insuranceFuel'].gt(ZERO));
console.log(
'insurance before/after:',
fuelDictInit['insuranceFuel'].toNumber(),
'->',
fuelDictInit2['insuranceFuel'].toNumber()
);

assert(
Math.abs(
fuelDictInit['insuranceFuel'].toNumber() -
fuelDictInit2['insuranceFuel'].toNumber()
) <= 1
);

await bankrunContextWrapper.moveTimeForward(
takerDriftClient
.getSpotMarketAccount(0)
.insuranceFund.unstakingPeriod.toNumber()
);

const _again = await takerDriftClient.removeInsuranceFundStake(
marketIndex,
_takerUSDCAccount.publicKey
);

const currentClockRm =
await bankrunContextWrapper.context.banksClient.getClock();

const fuelDictRmStake = takerDriftClientUser.getFuelBonus(
new BN(currentClockRm.unixTimestamp.toString()),
true,
true
);

console.log(fuelDictRmStake);
const totalFuelIfNoUnstake = 119791;
const expectedFuel =
(totalFuelIfNoUnstake - fuelDictInit2['insuranceFuel'].toNumber()) / 3 +
fuelDictInit2['insuranceFuel'].toNumber();
console.log(
expectedFuel,
'vs',
fuelDictRmStake['insuranceFuel'].toNumber()
);
assert(
Math.abs(fuelDictRmStake['insuranceFuel'].toNumber() - expectedFuel) < 1
);

assert(fuelDictRmStake['insuranceFuel'].gt(ZERO));
console.log(
'insurance before/after remove:',
fuelDictInit2['insuranceFuel'].toNumber(),
'->',
fuelDictRmStake['insuranceFuel'].toNumber()
);
});

it('fuel for perp taker/maker/position', async () => {
const [takerDriftClient, _takerUSDCAccount] = await createTestClient({
referrer: fillerDriftClientUser.getUserAccount().authority,
Expand Down

0 comments on commit 64ab59a

Please sign in to comment.