Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 1b7bddd

Browse files
authored
Convert fees to collateral custody token (#15)
1 parent 30b9f8c commit 1b7bddd

File tree

7 files changed

+76
-27
lines changed

7 files changed

+76
-27
lines changed

Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@
22
members = [
33
"programs/*"
44
]
5+
6+
[profile.release]
7+
overflow-checks = true
8+
lto = "fat"
9+
codegen-units = 1
10+
[profile.release.build-override]
11+
opt-level = 3
12+
incremental = false
13+
codegen-units = 1

programs/perpetuals/Cargo.toml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,6 @@ cpi = ["no-entrypoint"]
2222
test = []
2323
default = []
2424

25-
[profile.release]
26-
lto = true
27-
codegen-units = 1
28-
overflow-checks = true
29-
3025
[dependencies]
3126
anchor-lang = {version = "0.26.0", features = ["init-if-needed"]}
3227
anchor-spl = "0.26.0"

programs/perpetuals/src/instructions/close_position.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ pub fn close_position(ctx: Context<ClosePosition>, params: &ClosePositionParams)
167167
}
168168

169169
msg!("Settle position");
170-
let (transfer_amount, fee_amount, profit_usd, loss_usd) = pool.get_close_amount(
170+
let (transfer_amount, mut fee_amount, profit_usd, loss_usd) = pool.get_close_amount(
171171
position,
172172
&token_price,
173173
&token_ema_price,
@@ -179,7 +179,11 @@ pub fn close_position(ctx: Context<ClosePosition>, params: &ClosePositionParams)
179179
false,
180180
)?;
181181

182-
let protocol_fee = Pool::get_fee_amount(custody.fees.protocol_share, fee_amount)?;
182+
let fee_amount_usd = token_ema_price.get_asset_amount_usd(fee_amount, custody.decimals)?;
183+
if position.side == Side::Short || custody.is_virtual {
184+
fee_amount = collateral_token_ema_price
185+
.get_token_amount(fee_amount_usd, collateral_custody.decimals)?;
186+
}
183187

184188
msg!("Net profit: {}, loss: {}", profit_usd, loss_usd);
185189
msg!("Collected fee: {}", fee_amount);
@@ -212,10 +216,7 @@ pub fn close_position(ctx: Context<ClosePosition>, params: &ClosePositionParams)
212216
collateral_custody.collected_fees.close_position_usd = collateral_custody
213217
.collected_fees
214218
.close_position_usd
215-
.wrapping_add(
216-
collateral_token_ema_price
217-
.get_asset_amount_usd(fee_amount, collateral_custody.decimals)?,
218-
);
219+
.wrapping_add(fee_amount_usd);
219220

220221
if transfer_amount > position.collateral_amount {
221222
let amount_lost = transfer_amount.saturating_sub(position.collateral_amount);
@@ -230,6 +231,8 @@ pub fn close_position(ctx: Context<ClosePosition>, params: &ClosePositionParams)
230231
collateral_custody.assets.collateral,
231232
position.collateral_amount,
232233
)?;
234+
235+
let protocol_fee = Pool::get_fee_amount(custody.fees.protocol_share, fee_amount)?;
233236
collateral_custody.assets.protocol_fees =
234237
math::checked_add(collateral_custody.assets.protocol_fees, protocol_fee)?;
235238

programs/perpetuals/src/instructions/get_entry_price_and_fee.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,19 @@ pub fn get_entry_price_and_fee(
149149
curtime,
150150
)?;
151151

152-
let fee = pool.get_entry_fee(
152+
let mut fee = pool.get_entry_fee(
153153
custody.fees.open_position,
154154
params.size,
155155
locked_amount,
156156
collateral_custody,
157157
)?;
158158

159+
if params.side == Side::Short || custody.is_virtual {
160+
let fee_amount_usd = token_ema_price.get_asset_amount_usd(fee, custody.decimals)?;
161+
fee = collateral_token_ema_price
162+
.get_token_amount(fee_amount_usd, collateral_custody.decimals)?;
163+
}
164+
159165
Ok(NewPositionPricesAndFee {
160166
entry_price,
161167
liquidation_price,

programs/perpetuals/src/instructions/get_exit_price_and_fee.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use {
66
oracle::OraclePrice,
77
perpetuals::{Perpetuals, PriceAndFee},
88
pool::Pool,
9-
position::Position,
9+
position::{Position, Side},
1010
},
1111
anchor_lang::prelude::*,
1212
};
@@ -49,6 +49,20 @@ pub struct GetExitPriceAndFee<'info> {
4949
constraint = custody_oracle_account.key() == custody.oracle.oracle_account
5050
)]
5151
pub custody_oracle_account: AccountInfo<'info>,
52+
53+
#[account(
54+
seeds = [b"custody",
55+
pool.key().as_ref(),
56+
collateral_custody.mint.as_ref()],
57+
bump = collateral_custody.bump
58+
)]
59+
pub collateral_custody: Box<Account<'info, Custody>>,
60+
61+
/// CHECK: oracle account for the collateral token
62+
#[account(
63+
constraint = collateral_custody_oracle_account.key() == collateral_custody.oracle.oracle_account
64+
)]
65+
pub collateral_custody_oracle_account: AccountInfo<'info>,
5266
}
5367

5468
#[derive(AnchorSerialize, AnchorDeserialize)]
@@ -63,6 +77,7 @@ pub fn get_exit_price_and_fee(
6377
let pool = &ctx.accounts.pool;
6478
let curtime = ctx.accounts.perpetuals.get_time()?;
6579
let custody = &ctx.accounts.custody;
80+
let collateral_custody = &ctx.accounts.collateral_custody;
6681

6782
let token_price = OraclePrice::new_from_oracle(
6883
&ctx.accounts.custody_oracle_account.to_account_info(),
@@ -78,11 +93,26 @@ pub fn get_exit_price_and_fee(
7893
custody.pricing.use_ema,
7994
)?;
8095

96+
let collateral_token_ema_price = OraclePrice::new_from_oracle(
97+
&ctx.accounts
98+
.collateral_custody_oracle_account
99+
.to_account_info(),
100+
&collateral_custody.oracle,
101+
curtime,
102+
collateral_custody.pricing.use_ema,
103+
)?;
104+
81105
let price = pool.get_exit_price(&token_price, &token_ema_price, position.side, custody)?;
82106

83107
let size = token_ema_price.get_token_amount(position.size_usd, custody.decimals)?;
84108

85-
let fee = pool.get_exit_fee(size, custody)?;
109+
let mut fee = pool.get_exit_fee(size, custody)?;
110+
111+
if position.side == Side::Short || custody.is_virtual {
112+
let fee_amount_usd = token_ema_price.get_asset_amount_usd(fee, custody.decimals)?;
113+
fee = collateral_token_ema_price
114+
.get_token_amount(fee_amount_usd, collateral_custody.decimals)?;
115+
}
86116

87117
Ok(PriceAndFee { price, fee })
88118
}

programs/perpetuals/src/instructions/liquidate.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ pub fn liquidate(ctx: Context<Liquidate>, _params: &LiquidateParams) -> Result<(
173173
);
174174

175175
msg!("Settle position");
176-
let (total_amount_out, fee_amount, profit_usd, loss_usd) = pool.get_close_amount(
176+
let (total_amount_out, mut fee_amount, profit_usd, loss_usd) = pool.get_close_amount(
177177
position,
178178
&token_price,
179179
&token_ema_price,
@@ -185,7 +185,11 @@ pub fn liquidate(ctx: Context<Liquidate>, _params: &LiquidateParams) -> Result<(
185185
true,
186186
)?;
187187

188-
let protocol_fee = Pool::get_fee_amount(custody.fees.protocol_share, fee_amount)?;
188+
let fee_amount_usd = token_ema_price.get_asset_amount_usd(fee_amount, custody.decimals)?;
189+
if position.side == Side::Short || custody.is_virtual {
190+
fee_amount = collateral_token_ema_price
191+
.get_token_amount(fee_amount_usd, collateral_custody.decimals)?;
192+
}
189193

190194
msg!("Net profit: {}, loss: {}", profit_usd, loss_usd);
191195
msg!("Collected fee: {}", fee_amount);
@@ -233,10 +237,7 @@ pub fn liquidate(ctx: Context<Liquidate>, _params: &LiquidateParams) -> Result<(
233237
collateral_custody.collected_fees.liquidation_usd = collateral_custody
234238
.collected_fees
235239
.liquidation_usd
236-
.wrapping_add(
237-
collateral_token_ema_price
238-
.get_asset_amount_usd(fee_amount, collateral_custody.decimals)?,
239-
);
240+
.wrapping_add(fee_amount_usd);
240241

241242
if total_amount_out > position.collateral_amount {
242243
let amount_lost = total_amount_out.saturating_sub(position.collateral_amount);
@@ -251,6 +252,8 @@ pub fn liquidate(ctx: Context<Liquidate>, _params: &LiquidateParams) -> Result<(
251252
collateral_custody.assets.collateral,
252253
position.collateral_amount,
253254
)?;
255+
256+
let protocol_fee = Pool::get_fee_amount(custody.fees.protocol_share, fee_amount)?;
254257
collateral_custody.assets.protocol_fees =
255258
math::checked_add(collateral_custody.assets.protocol_fees, protocol_fee)?;
256259

programs/perpetuals/src/instructions/open_position.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ pub fn open_position(ctx: Context<OpenPosition>, params: &OpenPositionParams) ->
134134
{
135135
return Err(ProgramError::InvalidArgument.into());
136136
}
137-
if params.side == Side::Short || custody.is_virtual {
137+
let use_collateral_custody = params.side == Side::Short || custody.is_virtual;
138+
if use_collateral_custody {
138139
require_keys_neq!(custody.key(), collateral_custody.key());
139140
require!(
140141
collateral_custody.is_stable && !collateral_custody.is_virtual,
@@ -211,7 +212,7 @@ pub fn open_position(ctx: Context<OpenPosition>, params: &OpenPositionParams) ->
211212
let collateral_usd = min_collateral_price
212213
.get_asset_amount_usd(params.collateral, collateral_custody.decimals)?;
213214

214-
let locked_amount = if params.side == Side::Short || custody.is_virtual {
215+
let locked_amount = if use_collateral_custody {
215216
custody.get_locked_amount(
216217
min_collateral_price.get_token_amount(size_usd, collateral_custody.decimals)?,
217218
params.side,
@@ -221,12 +222,17 @@ pub fn open_position(ctx: Context<OpenPosition>, params: &OpenPositionParams) ->
221222
};
222223

223224
// compute fee
224-
let fee_amount = pool.get_entry_fee(
225+
let mut fee_amount = pool.get_entry_fee(
225226
custody.fees.open_position,
226227
params.size,
227228
locked_amount,
228229
collateral_custody,
229230
)?;
231+
let fee_amount_usd = token_ema_price.get_asset_amount_usd(fee_amount, custody.decimals)?;
232+
if use_collateral_custody {
233+
fee_amount = collateral_token_ema_price
234+
.get_token_amount(fee_amount_usd, collateral_custody.decimals)?;
235+
}
230236
msg!("Collected fee: {}", fee_amount);
231237

232238
// compute amount to transfer
@@ -296,10 +302,7 @@ pub fn open_position(ctx: Context<OpenPosition>, params: &OpenPositionParams) ->
296302
collateral_custody.collected_fees.open_position_usd = collateral_custody
297303
.collected_fees
298304
.open_position_usd
299-
.wrapping_add(
300-
collateral_token_ema_price
301-
.get_asset_amount_usd(fee_amount, collateral_custody.decimals)?,
302-
);
305+
.wrapping_add(fee_amount_usd);
303306

304307
collateral_custody.assets.collateral =
305308
math::checked_add(collateral_custody.assets.collateral, params.collateral)?;

0 commit comments

Comments
 (0)