Skip to content

fix: fee cal error#13

Open
ZouBadCode wants to merge 5 commits intomainfrom
fix/some-calculation-error
Open

fix: fee cal error#13
ZouBadCode wants to merge 5 commits intomainfrom
fix/some-calculation-error

Conversation

@ZouBadCode
Copy link
Copy Markdown
Contributor

This pull request introduces major improvements to the fee structure and risk management in the WaterX perpetual protocol. The main changes are the addition of a configurable impact fee system for trading, a rework of liquidation and insurance fee logic, and updates to how trading fees are calculated and validated across the codebase. It also includes a fix for a position registration issue when opening new positions, as well as a variable naming correction for consistency. Together, these changes improve fee flexibility and accuracy, better reflect market risk, strengthen protocol safety, and fix an important accounting edge case.

Fee Structure and Risk Management Enhancements:

  • Added a new impact fee system to MarketConfig, including parameters for maximum impact fee, LP exposure allocation, curvature, and scale, with default values and validation to ensure safe configuration.
  • Updated trading fee calculations throughout trading.move to use calculate_total_trading_fee_bps, ensuring all trading, closing, and liquidation fees reflect both base and impact fees.

Liquidation and Insurance Fee Logic:

  • Refactored liquidation logic to make the insurance fee a configurable basis point (bps) percentage of liquidation notional, set keeper fee to 0 by default, and return remaining collateral to the WLP. Documentation and struct fields were updated for clarity and consistency.

Collateral and Position Safety Checks:

  • Changed position liquidatability checks to use the actual closing fee (in USD) rather than just the trading fee bps, improving accuracy in collateral safety validation.

Bug Fixes and Consistency Improvements:

  • Fixed an issue where newly opened positions were not registered into account_registry, ensuring account state stays consistent and positions can be tracked correctly after creation.
  • Corrected a variable naming error from colleteral to collateral for better clarity and consistency across the codebase.

Documentation Updates:

  • Updated ARCHITECTURE.md to reflect the new liquidation and insurance fee model, and clarified protocol fee and keeper fee handling.

@ZouBadCode ZouBadCode requested a review from JustaLiang April 5, 2026 13:54
Copy link
Copy Markdown
Contributor

@bucket-bot bucket-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review

Found 1 issue:

  1. Partial position decrease can hard-abort when accrued fees exceed remaining collateral, which blocks a risk-reducing action and creates inconsistent behavior vs full close. In full close you cap fee deduction with min(collateral.value()), but in partial decrease you withdraw exact total_fee and funding_fee from position collateral. If collateral is already stressed (e.g. after realized loss), withdraw_collateral aborts and user cannot partially de-risk.
  • Fee withdrawal path: trading.move#L1245-L1267
  • Full-close capped behavior reference: trading.move#L1150-L1174

Suggested fix: cap partial-close fee deductions the same way as full close (or pre-check and route to liquidation explicitly), so partial reduce remains executable and predictable under low-collateral states.

let total_fee = close_fee + borrow_fee + open_fee;
if (total_fee > 0) {
let mut fee_balance = {
let vault = global_config.balance_mut<C_TOKEN>();
pos.withdraw_collateral<C_TOKEN>(vault, total_fee)
};
let protocol_amount = (
(fee_balance.value() as u128) * (protocol_share_bps as u128) / 10000 as u64,
);
if (protocol_amount > 0) {
let protocol_fee = fee_balance.split(protocol_amount);
transfer::public_transfer(protocol_fee.into_coin(ctx), protocol_fee_addr);
events::emit_protocol_fee_collected(protocol_fee_addr, protocol_amount, market_id, now);
};
pool.put_collateral(fee_balance, collateral_price);
};
if (funding_fee > 0) {
if (funding_sign_pos) {
let funding_bal = {
let vault = global_config.balance_mut<C_TOKEN>();
pos.withdraw_collateral<C_TOKEN>(vault, funding_fee)
};

🤖 Generated with Rex (OpenClaw)

…rror

Brings simulate error surfacing, Pyth gRPC/JSON-RPC fallbacks, and
testnet OI assertions so CI matches PR #14; merges cleanly with fee/calc work.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants