Skip to content

Commit

Permalink
program: add deposit_into_spot_market_revenue_pool (#520)
Browse files Browse the repository at this point in the history
* deposit_into_spot_market_revenue_pool

* add typescript test/sdk

* add max deposit check, fix handle_deposit state variable label

* instructions/user.rs: fix context use of market_index, add validate vault amounts

* tweaks

* CHANGELOG

* fix build

---------

Co-authored-by: Chris Heaney <[email protected]>
  • Loading branch information
0xbigz and crispheaney committed Aug 1, 2023
1 parent 16c93c4 commit ad53944
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- program: add deposit_into_spot_market_revenue_pool ([#520](https://github.com/drift-labs/protocol-v2/pull/520))
- program: make users w excessive withdraws pay fees ([#547](https://github.com/drift-labs/protocol-v2/pull/547))
- program: allow settle pnl and spot fills via match when utilization is 100% ([#525](https://github.com/drift-labs/protocol-v2/pull/525))
- program: new update_perp_bid_ask_twap ix ([#548](https://github.com/drift-labs/protocol-v2/pull/548))
Expand Down
67 changes: 67 additions & 0 deletions programs/drift/src/instructions/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ use crate::state::perp_market::MarketStatus;
use crate::state::perp_market_map::{get_writable_perp_market_set, MarketSet};
use crate::state::spot_fulfillment_params::SpotFulfillmentParams;
use crate::state::spot_market::SpotBalanceType;
use crate::state::spot_market::SpotMarket;
use crate::state::spot_market_map::{
get_writable_spot_market_set, get_writable_spot_market_set_from_many,
};
Expand Down Expand Up @@ -1875,6 +1876,50 @@ pub fn handle_delete_user(ctx: Context<DeleteUser>) -> Result<()> {
Ok(())
}

#[access_control(
deposit_not_paused(&ctx.accounts.state)
)]
pub fn handle_deposit_into_spot_market_revenue_pool(
ctx: Context<RevenuePoolDeposit>,
amount: u64,
) -> Result<()> {
if amount == 0 {
return Err(ErrorCode::InsufficientDeposit.into());
}

let mut spot_market = load_mut!(ctx.accounts.spot_market)?;

validate!(
spot_market.is_active(Clock::get()?.unix_timestamp)?,
ErrorCode::DefaultError,
"spot market {} not active",
spot_market.market_index
)?;

controller::spot_balance::update_revenue_pool_balances(
amount.cast::<u128>()?,
&SpotBalanceType::Deposit,
&mut spot_market,
)?;

controller::token::receive(
&ctx.accounts.token_program,
&ctx.accounts.user_token_account,
&ctx.accounts.spot_market_vault,
&ctx.accounts.authority,
amount,
)?;

spot_market.validate_max_token_deposits()?;
ctx.accounts.spot_market_vault.reload()?;
math::spot_withdraw::validate_spot_market_vault_amount(
&spot_market,
ctx.accounts.spot_market_vault.amount,
)?;

Ok(())
}

#[derive(Accounts)]
#[instruction(
sub_account_id: u16,
Expand Down Expand Up @@ -1981,6 +2026,28 @@ pub struct Deposit<'info> {
pub token_program: Program<'info, Token>,
}

#[derive(Accounts)]
pub struct RevenuePoolDeposit<'info> {
#[account(mut)]
pub spot_market: AccountLoader<'info, SpotMarket>,
pub state: Box<Account<'info, State>>,
#[account(mut)]
pub authority: Signer<'info>,
#[account(
mut,
seeds = [b"spot_market_vault".as_ref(), spot_market.load()?.market_index.to_le_bytes().as_ref()],
bump,
)]
pub spot_market_vault: Box<Account<'info, TokenAccount>>,
#[account(
mut,
constraint = &spot_market_vault.mint.eq(&user_token_account.mint),
token::authority = authority
)]
pub user_token_account: Box<Account<'info, TokenAccount>>,
pub token_program: Program<'info, Token>,
}

#[derive(Accounts)]
#[instruction(market_index: u16,)]
pub struct Withdraw<'info> {
Expand Down
7 changes: 7 additions & 0 deletions programs/drift/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,13 @@ pub mod drift {
handle_deposit_into_perp_market_fee_pool(ctx, amount)
}

pub fn deposit_into_spot_market_revenue_pool(
ctx: Context<RevenuePoolDeposit>,
amount: u64,
) -> Result<()> {
handle_deposit_into_spot_market_revenue_pool(ctx, amount)
}

pub fn repeg_amm_curve(ctx: Context<RepegCurve>, new_peg_candidate: u128) -> Result<()> {
handle_repeg_amm_curve(ctx, new_peg_candidate)
}
Expand Down
24 changes: 24 additions & 0 deletions sdk/src/driftClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5587,6 +5587,30 @@ export class DriftClient {
);
}

public async depositIntoSpotMarketRevenuePool(
marketIndex: number,
amount: BN,
userTokenAccountPublicKey: PublicKey
): Promise<TransactionSignature> {
const spotMarket = await this.getSpotMarketAccount(marketIndex);
const tx = await this.program.transaction.depositIntoSpotMarketRevenuePool(
amount,
{
accounts: {
state: await this.getStatePublicKey(),
spotMarket: spotMarket.vault,
userTokenAccount: userTokenAccountPublicKey,
authority: this.wallet.publicKey,
spotMarketVault: spotMarket.vault,
tokenProgram: TOKEN_PROGRAM_ID,
},
}
);

const { txSig } = await this.sendTransaction(tx, [], this.opts);
return txSig;
}

public getPerpMarketExtendedInfo(
marketIndex: number
): PerpMarketExtendedInfo {
Expand Down
41 changes: 41 additions & 0 deletions sdk/src/idl/drift.json
Original file line number Diff line number Diff line change
Expand Up @@ -2964,6 +2964,47 @@
}
]
},
{
"name": "depositIntoSpotMarketRevenuePool",
"accounts": [
{
"name": "spotMarket",
"isMut": true,
"isSigner": false
},
{
"name": "state",
"isMut": false,
"isSigner": false
},
{
"name": "authority",
"isMut": true,
"isSigner": true
},
{
"name": "spotMarketVault",
"isMut": true,
"isSigner": false
},
{
"name": "userTokenAccount",
"isMut": true,
"isSigner": false
},
{
"name": "tokenProgram",
"isMut": false,
"isSigner": false
}
],
"args": [
{
"name": "amount",
"type": "u64"
}
]
},
{
"name": "repegAmmCurve",
"accounts": [
Expand Down
2 changes: 1 addition & 1 deletion test-scripts/single-anchor-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ if [ "$1" != "--skip-build" ]
fi

test_files=(liquidityProvider.ts)
# test_files=(tradingLP.ts)
test_files=(spotSwap.ts)

for test_file in ${test_files[@]}; do
ANCHOR_TEST_FILE=${test_file} anchor test --skip-build || exit 1;
Expand Down
42 changes: 35 additions & 7 deletions tests/spotSwap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ import {
EventSubscriber,
OracleSource,
OracleInfo,
getTokenAmount,
SpotBalanceType,
ZERO,
BulkAccountLoader,
fetchUserStatsAccount,
getSerumSignerPublicKey,
QUOTE_PRECISION,
} from '../sdk/src';

import {
Expand All @@ -31,13 +38,6 @@ import {
} from './testHelpers';
import { NATIVE_MINT } from '@solana/spl-token';
import { DexInstructions, Market, OpenOrders } from '@project-serum/serum';
import {
BulkAccountLoader,
fetchUserStatsAccount,
getSerumSignerPublicKey,
QUOTE_PRECISION,
} from '../sdk';

describe('spot swap', () => {
const provider = anchor.AnchorProvider.local(undefined, {
commitment: 'confirmed',
Expand Down Expand Up @@ -596,4 +596,32 @@ describe('spot swap', () => {
}
assert(failed);
});

it('donate to revenue pool for a great feature!', async () => {
const solSpotMarket = takerDriftClient.getSpotMarketAccount(1);

const solRevPool = getTokenAmount(
solSpotMarket.revenuePool.scaledBalance,
solSpotMarket,
SpotBalanceType.DEPOSIT
);
assert(solRevPool.eq(ZERO));

const charity = new BN(1);
await takerDriftClient.depositIntoSpotMarketRevenuePool(
1,
charity,
takerWSOL
);
await takerDriftClient.fetchAccounts();
const solSpotMarketAfter = takerDriftClient.getSpotMarketAccount(1);

const solRevPoolAfter = getTokenAmount(
solSpotMarketAfter.revenuePool.scaledBalance,
solSpotMarketAfter,
SpotBalanceType.DEPOSIT
);
assert(solRevPoolAfter.gt(solRevPool));
assert(solRevPoolAfter.eq(charity));
});
});

0 comments on commit ad53944

Please sign in to comment.