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

Commit 81f5fe9

Browse files
authored
Close position protocol_fee accounting (#22)
* account for protocol_fee * nit * also modify liquidate ix * nit * handle fees when maxpayoff is reached * close_position/liquidate: only pay protocol_fee if possible * close_position/liquidate: only pay protocol_fee if possible
1 parent 4f0fa30 commit 81f5fe9

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

programs/perpetuals/src/instructions/close_position.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,15 @@ pub fn close_position(ctx: Context<ClosePosition>, params: &ClosePositionParams)
233233
)?;
234234

235235
let protocol_fee = Pool::get_fee_amount(custody.fees.protocol_share, fee_amount)?;
236-
collateral_custody.assets.protocol_fees =
237-
math::checked_add(collateral_custody.assets.protocol_fees, protocol_fee)?;
236+
237+
// Pay protocol_fee from custody if possible, otherwise no protocol_fee
238+
if pool.check_available_amount(protocol_fee, collateral_custody)? {
239+
collateral_custody.assets.protocol_fees =
240+
math::checked_add(collateral_custody.assets.protocol_fees, protocol_fee)?;
241+
242+
collateral_custody.assets.owned =
243+
math::checked_sub(collateral_custody.assets.owned, protocol_fee)?;
244+
}
238245

239246
// if custody and collateral_custody accounts are the same, ensure that data is in sync
240247
if position.side == Side::Long && !custody.is_virtual {

programs/perpetuals/src/instructions/liquidate.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,15 @@ pub fn liquidate(ctx: Context<Liquidate>, _params: &LiquidateParams) -> Result<(
254254
)?;
255255

256256
let protocol_fee = Pool::get_fee_amount(custody.fees.protocol_share, fee_amount)?;
257-
collateral_custody.assets.protocol_fees =
258-
math::checked_add(collateral_custody.assets.protocol_fees, protocol_fee)?;
257+
258+
// Pay protocol_fee from custody if possible, otherwise no protocol_fee
259+
if pool.check_available_amount(protocol_fee, collateral_custody)? {
260+
collateral_custody.assets.protocol_fees =
261+
math::checked_add(collateral_custody.assets.protocol_fees, protocol_fee)?;
262+
263+
collateral_custody.assets.owned =
264+
math::checked_sub(collateral_custody.assets.owned, protocol_fee)?;
265+
}
259266

260267
// if custody and collateral_custody accounts are the same, ensure that data is in sync
261268
if position.side == Side::Long && !custody.is_virtual {

programs/perpetuals/src/state/pool.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,10 @@ impl Pool {
243243
};
244244
let close_amount = max_collateral_price
245245
.get_token_amount(available_amount_usd, collateral_custody.decimals)?;
246-
let max_amount = math::checked_add(position.locked_amount, position.collateral_amount)?;
246+
let max_amount = math::checked_add(
247+
position.locked_amount.saturating_sub(fee_amount),
248+
position.collateral_amount,
249+
)?;
247250

248251
Ok((
249252
std::cmp::min(max_amount, close_amount),

0 commit comments

Comments
 (0)