Perp: Borrowing Fees
此内容尚不支持你的语言。
The borrowing logic in the Sai perpetual futures contract has three main responsibilities:
- Calculating and accumulating borrowing fees for leveraged positions.
- Tracking open interest (OI) for trading pairs and borrowing groups.
- Enforcing exposure limits to ensure trading activity remains within defined thresholds.
This document explains how borrowing groups are structured, how their state is updated, and how borrowing fees are calculated from trade open through close or liquidation.
Key Components
Section titled “Key Components”Data Structures
Section titled “Data Structures”-
BorrowingData
- Purpose: Stores fee rates and the accumulated fees for both pairs and groups.
- Fields:
fee_per_block: Base fee rate per block.acc_fee_long: Accumulated fee for long positions.acc_fee_short: Accumulated fee for short positions.acc_last_updated_block: Block number of the most recent fee update.fee_exponent: Adjusts sensitivity for fee calculation based on open interest imbalances.
-
BorrowingPairGroup
- Purpose: Captures the historical group associations for borrowing pairs.
- Fields:
group_index: Identifier for the borrowing group.block: Block number at which the group association was set.initial_acc_fee_long: Initial accumulated fee for long positions.initial_acc_fee_short: Initial accumulated fee for short positions.prev_group_acc_fee_long: Previous group’s accumulated fee for long positions.prev_group_acc_fee_short: Previous group’s accumulated fee for short positions.pair_acc_fee_long: Accumulated fee for the pair’s long positions at the time of group change.pair_acc_fee_short: Accumulated fee for the pair’s short positions at the time of group change.
-
OpenInterest
- Purpose: Tracks open interest (total position sizes) for both pairs and groups.
- Fields:
long: Total open interest for long positions.short: Total open interest for short positions.max: Maximum allowable open interest.
-
BorrowingInitialAccFees
- Purpose: Records initial accumulated fees for a trade at the moment it opens.
- Fields:
acc_pair_fee: Pair’s accumulated fee when the trade opened.acc_group_fee: Group’s accumulated fee when the trade opened.block: Block number when the trade was opened.
Storage Maps
Section titled “Storage Maps”PAIRS: StoresBorrowingDatafor each trading pair.PAIR_GROUPS: Stores a list ofBorrowingPairGrouprecords for each pair (capturing historical group changes).PAIR_OIS: StoresOpenInterestfor each pair.GROUPS: StoresBorrowingDatafor each borrowing group.GROUP_OIS: StoresOpenInterestfor each borrowing group.INITIAL_ACC_FEES: StoresBorrowingInitialAccFeesfor each trade.
Borrowing Groups
Section titled “Borrowing Groups”What is a Borrowing Group?
Section titled “What is a Borrowing Group?”A Borrowing Group is a set of trading pairs that share common borrowing parameters. It simplifies fee management and exposure control by allowing:
- Collective fee adjustments: Update borrowing fees for multiple pairs simultaneously.
- Shared exposure limits: Manage cumulative open interest across all pairs in the group.
Role of Borrowing Groups
Section titled “Role of Borrowing Groups”- Fee Adjustments: Updates borrowing fees in response to market conditions—affecting all pairs in the group at once.
- Exposure Control: Aggregates open interest to ensure the group’s overall risk remains within acceptable limits.
- Historical Fee Tracking: Logs when pairs change groups so that fee calculations remain accurate for open trades.
How Borrowing Groups Are Updated
Section titled “How Borrowing Groups Are Updated”Setting Borrowing Group Parameters
Section titled “Setting Borrowing Group Parameters”Use set_borrowing_group_params to create or update a borrowing group’s parameters:
-
Key Parameters:
fee_per_block: Base borrowing fee rate per block.fee_exponent: Exponent to scale fees based on open interest imbalances.max_oi: Maximum allowable open interest for the group.current_block: Current block number (for fee updates).
-
Process:
- Validation: Ensures
fee_exponentis within allowed bounds (1% to 300%). - Update Accumulated Fees: Calls
set_group_pending_acc_feesto synchronize the group’s fees up tocurrent_block. - Store New Data: Updates the group’s parameters in
GROUPS. - Adjust Open Interest Limit: Sets
max_oiinGROUP_OIS.
- Validation: Ensures
Changing a Pair’s Borrowing Group
Section titled “Changing a Pair’s Borrowing Group”When calling set_borrowing_pair_params to place a pair in a new borrowing group:
-
Key Parameters:
group_index: The new group index to assign to the pair.
-
Process:
- Fee Synchronization: Updates fees for both the old and new groups via
set_group_pending_acc_fees. - Open Interest Update: Removes the pair’s open interest from the old group and adds it to the new group using
update_group_oi. - Record Group Change: Appends a new
BorrowingPairGroupentry toPAIR_GROUPS, capturing relevant fee data and the block number. - Update Pair Data: Adjusts any pair-specific borrowing parameters in
PAIRS.
- Fee Synchronization: Updates fees for both the old and new groups via
Updating Open Interest
Section titled “Updating Open Interest”Open interest is recalculated whenever trades open or close:
-
Key Functions:
update_pair_oi: Updates pair-level open interest inPAIR_OIS.update_group_oi: Updates group-level open interest inGROUP_OIS.
-
Process:
- Opening a Trade: Increases the
longorshortOI depending on the trade’s direction. - Closing a Trade: Decreases the
longorshortOI accordingly.
- Opening a Trade: Increases the
Logic Behind Updates
Section titled “Logic Behind Updates”Accumulating Borrowing Fees
Section titled “Accumulating Borrowing Fees”Borrowing fees grow over time, affected by OI imbalances:
-
Fee Formula:
delta = fee_per_block * (current_block - acc_last_updated_block) * (net_oi / max_oi) ^ fee_exponentfee_per_block: Base fee rate per block.current_block - acc_last_updated_block: Blocks elapsed since the last fee update.net_oi: Absolute difference betweenlongandshortOI.max_oi: Maximum allowed open interest (for the pair or group).fee_exponent: Exponent that increases fees exponentially with larger OI imbalances.
-
Side-Specific Fee Accumulation:
- Fees accrue only on the side (long or short) that has the larger open interest, incentivizing a more balanced market.
Handling Trades
Section titled “Handling Trades”Opening a Trade
Section titled “Opening a Trade”When a new trade is opened:
- Function:
handle_trade_borrowing- Fee Synchronization: Calls
set_pair_pending_acc_feesandset_group_pending_acc_feesto update fees. - Open Interest: Updates pair and group OI via
update_pair_oiandupdate_group_oi. - Initial Fee Recording: Invokes
reset_trade_borrowing_feesto log the accumulated fees at the time the trade opens.
- Fee Synchronization: Calls
Closing a Trade
Section titled “Closing a Trade”When an existing trade closes:
- Function:
handle_trade_borrowing- Fee Synchronization: Updates fees up to the current block.
- Open Interest: Reduces the pair and group OI (long or short) accordingly.
- Borrowing Fee Calculation:
- Function:
get_trade_borrowing_fees- Computes the difference between the fees at closure vs. the
INITIAL_ACC_FEESfrom trade open. - Accounts for any group changes that happened during the trade.
- Computes the difference between the fees at closure vs. the
- Function:
Adjusting for Group Changes
Section titled “Adjusting for Group Changes”If a pair moves to a new group while a trade is open:
- Challenge: The position’s borrowing fees must reflect fees from both the old group and the new group.
- Solution:
- Use
get_borrowing_pair_group_acc_fees_deltasto determine the fee delta across group transitions. - Sum the larger of (pair delta, group delta) for each period to get total fees.
- Use
Calculating Liquidation Price with Fees
Section titled “Calculating Liquidation Price with Fees”To calculate liquidation prices, including borrowing fees:
- Function:
get_trade_liquidation_price_with_fees- Includes:
- Closing fees (e.g., close fee, trigger order fee)
- Borrowing fees from
get_trade_borrowing_fees
- Purpose: Computes the final liquidation price after deducting all fees.
- Includes:
Process Flow Summary
Section titled “Process Flow Summary”A high-level look at how trades use the borrowing logic:
-
Trade Opening
- User Action: Opens a new trade.
- System:
- Uses
handle_trade_borrowingto sync fees and update OI. - Stores initial accrued fees in
INITIAL_ACC_FEES.
- Uses
-
During Trade
- System:
- Continues to accumulate fees over time (not updated in storage unless an event triggers an update, like another trade).
- System:
-
Trade Closing
- User Action: Closes an existing trade.
- System:
- Calls
handle_trade_borrowingto update fees and OI. - Uses
get_trade_borrowing_feesto compute the total borrowing fees. - Finalizes the trade, deducting any closing fees and borrowing fees.
- Calls
-
Parameter Updates
- Admin Action: Updates group or pair parameters.
- System:
- Syncs fees up to the current block.
- Updates open interest if a pair’s group changes.
Detailed Function Explanations
Section titled “Detailed Function Explanations”handle_trade_borrowing
Section titled “handle_trade_borrowing”Purpose: Coordinates the borrowing logic whenever a trade opens or closes.
Workflow:
- Pending Fees Update: Invokes
set_pair_pending_acc_feesandset_group_pending_acc_fees. - Open Interest Update: Adjusts OI via
update_pair_oiandupdate_group_oi. - Reset Initial Fees (for new trades): Stores current fees in
INITIAL_ACC_FEES.
get_trade_borrowing_fees
Section titled “get_trade_borrowing_fees”Purpose: Calculates total borrowing fees for a trade upon closure.
Workflow:
- Load Initial Fees: Retrieves
INITIAL_ACC_FEESfor the trade. - Compute Current Fees: Uses
get_direction_borrowing_pair_pending_acc_feesandget_direction_borrowing_group_pending_acc_fees. - Group Transition Handling: Applies
get_borrowing_pair_group_acc_fees_deltasfor fee periods affected by group changes. - Final Fee Calculation:
(Current Acc Fees - Initial Acc Fees) * (Trade Collateral * Leverage).
get_borrowing_pending_acc_fees
Section titled “get_borrowing_pending_acc_fees”Purpose: Calculates the additional fees that accumulated between the last update and the current block.
Workflow:
- Identify OI Imbalance: Determines whether long or short positions exceed the other.
- Calculate Fee Delta: Uses the fee formula to calculate newly accrued fees.
- Add Fee Delta: Applies the calculated delta to either
acc_fee_longoracc_fee_short.
reset_trade_borrowing_fees
Section titled “reset_trade_borrowing_fees”Purpose: Logs the borrow-related fees at the moment a trade is opened.
Workflow:
- Saves the current
BorrowingDatafor both pair and group intoINITIAL_ACC_FEES, including the current block number.
Example: a pair changes borrowing groups
Section titled “Example: a pair changes borrowing groups”Consider a long position on Pair X while the pair moves from Group A to Group B:
| Block | Event | What the contract records |
|---|---|---|
| 100 | The trade opens while Pair X is in Group A. | It stores the current pair and Group A accumulated fees in INITIAL_ACC_FEES. |
| 150 | Pair X moves from Group A to Group B. | It updates Group A through block 150, moves the pair’s open interest to Group B, and records the transition in PAIR_GROUPS. |
| 200 | The trade closes while Pair X is in Group B. | It updates Pair X and Group B through block 200, then calculates the fee for the Group A period and the Group B period. |
The contract does not discard the first 50 blocks of the trade. When
get_trade_borrowing_fees runs, it uses the recorded group transition to apply
the correct pair and group fee deltas for each period.
Key Takeaways
Section titled “Key Takeaways”The borrowing logic connects fee accrual, open-interest tracking, and exposure management throughout a trade’s lifecycle.
- Borrowing Groups: Centralize exposure limits and streamline fee adjustments for multiple pairs.
- Accumulated Fees: Updated based on time, OI imbalances, and fee parameters.
- Open Interest: Tracked at both the pair and group level, essential for risk control.
- Trade Lifecycle:
- Opening a trade sets the initial fees.
- Closing a trade calculates total borrowing fees and updates open interest.
Together, these mechanisms account for changing open interest and borrowing groups while a leveraged trade remains open.