Protocol System Fees

Apollon generates revenue from various operations within its protocol. Jelly Token (JLY) holders can stake their tokens to earn a share of these fees proportionate to their stake in the total JLY staked.

Revenue Generation

  1. Redemption Fee

    The redemption fee is deducted from the total collateral withdrawn during a redemption, based on the current redemption rate. When a redemption occurs through RedemptionManager.redeemCollateral, the fee is transferred to the staking contract in all used collateral tokens.

  2. Issuance Fee

    The issuance fee, charged in aUSD, is based on the amount of debt drawn by the user and added to their Trove's aUSD debt. For aUSD, the fee varies with the current borrowing rate, which is dynamic. Other Apollon have a static borrowing rate of 0.5%.

    When new Apollon are drawn via functions like BorrowerOperations.openTrove, SwapOperations.addLiquidity, SwapOperations.openLongPosition, or SwapOperations.openShortPosition, extra aUSD is minted, and an equivalent amount of debt is added to the user’s Trove. The fee is transferred to the Reserve Pool. Once the Reserve Pool reaches its maximum capacity, subsequent fees are directed to the staking contract.

  3. Balance Fee

    The balance fee is paid in the incoming token of a pool swap. It consists of a static portion of 0.3% (swap fee) and a dynamic portion that can reach up to 5.0%. The dynamic component is calculated based on the deviation of the pool price from the Oracle price. A higher deviation results in a higher fee. 50% of this fee is allocated to the swap pool as a reward for liquidity providers, while the remaining 50% goes to the staking contract.

Fee Schedule

  • Redemption Fee: Calculated based on baseRate in TroveManager. The baseRate adjusts with each redemption, and decays over time since the last fee event.

  • Issuance Fee: Also based on baseRate, adjusting with each aUSD issuance and decaying over time.

  • Fee Limits: REDEMPTION_FEE_FLOOR and BORROWING_FEE_FLOOR are set at 0.5%. The maximum borrowing fee (MAX_BORROWING_FEE) is capped at 5%, ensuring fees do not drop below this threshold during redemptions to prevent front-running.

Fee Decay Implementation

Time is measured in minutes (block.timestamp). The baseRate decay rate ensures fees reduce gradually over time. The decay parameter is set to reduce the fee by approximately 1% per hour, ensuring that after one week, the baseRate decays significantly from its initial value. This decay mechanism prevents the baseRate from being artificially maintained at high levels through frequent small transactions, safeguarding against manipulation.

Governance

The protocol includes several critical management functions essential for integrating future collateral and Apollon tokens. These functions leverage the foundational Ownable concept, which transfers ownership to the governance contract upon deployment.

Contract
Function

TokenManager

setEnableMinting(bool _enable)

addDebtToken(address _debtTokenAddress, bytes32 _oracleId)

addCollToken(address _tokenAddress, uint _supportedCollateralRatio, bytes32 _oracleId, bool _isGovToken)

setCollTokenSupportedCollateralRatio(address _collTokenAddress, uint _supportedCollateralRatio)

setStockExchange(address _debtTokenAddress, address _exchangeForStock, int _exchangeRate)

setNextStockSplitRelative(address _debtTokenAddress, int32 _relativeSplit)

setSymbolAndName(address _debtTokenAddress, string memory _symbol, string memory _name)

ReservePool

setRelativeStableCap(uint _relativeStableCap)

setGovReserveCap(uint _govReserveCap)

TroveManager

setEnableLiquidationAndRedeeming(bool _enable)

setBorrowingFeeFloor(uint _borrowingFeeFloor)

setBorrowingInterestRate(uint _borrowingInterestRate)

SwapOperations

createPair(address _plainSwapPair, address tokenA, address tokenB)

setSwapBaseFee(uint _swapBaseFee)

setGovSwapFee(uint _govSwapFee)

Additionally, the PriceFeed incorporates a fallback price storage mechanism to handle situations where the Pyth network becomes unavailable. These fallback prices can be updated using the PriceFeed.setFallbackPrices() function.

Last updated