Skip to content

FeePool

Description

FeePools primary purpose is the distribution of synthetix.exchange fees in sUSD and SNX staking rewards to SNX minters aka stakers via the claimFees() function.

closeCurrentFeePeriod is an external public function anyone can call to close the current feeperiod after the `feePeriodDuration has passed. There is no incentive behind this function call as it is incentive enough that SNX Stakers want to be able to claim their fees and rewards. There is also a Fee Period Closing service that synthetix contributors opperate that will automatically call closeCurrentFeePeriod when the fee period duration has passed.

The FeePool currently maintains 2 feeperiod structs where the current open period for accumulating fees and rewards is recentFeePeriods[0] and the previos period which has been cloased and now available for SNX Stakers to claim their fees and rewards being recentFeePeriods[1]

Since SIP 56: Differential Fees it now supports the API for storing and reading the Synth Exchange Fee Rates per synth which are defined via SCCP's. The current eschange fee rates implemented in sccp-24

Source: contracts/FeePool.sol

Architecture

FeePool architecture graph

Details
  • Proxy: The fee pool, being Proxyable, sits behind a CALL-style proxy for upgradeability.
  • Synthetix: The fee pool needs the Synthetix address for a onlySynthetix modifer for storing a minters issue and burn events to track their debt % of the system.
  • SynthetixState: The fee pool retrieves the global issuance ratio, and queries the debt ledger directly from the Synthetix state contract.
  • Synth: The fee pool, retrieving their addresses from the Synthetix contract, directly burns and issues sUSD when transferring fees. Fees are denominated and paid out in sUSD. Synths themselves do not know the fee pool address directly, but ask the fee pool's proxy for its target.
  • FeePoolState: The fee pool state contract holds the details of each user's most recent issuance events: when they issued and burnt synths, and their value.
  • FeePoolEternalStorage: A storage contact that holds the last fee withdrawal time for each account.
  • DelegateApprovals: A storage contract containing addresses to which the right to withdraw fees has been delegated by another account, for example to allow hot wallets to withdraw fees.
  • RewardEscrow: The contract into which inflationary SNX rewards are paid by the fee pool so that they can be escrowed for a year after being claimed.
  • RewardsDistribution: This contract, in the guise of the rewardsAuthority, distributes allocations from the inflationary supply to various recipients.
  • Depot: Allows users to exchange between Synths, SNX, and Ether. The Depot uses the fee pool to know what transfer fees were being incurred on its transfers, although the transfer fee has been nil since before SIP-19.

Structs

FeePeriod

Source

A record for a fee period, when it was opened, and the fees and rewards accrued within it. This information is maintained for the last several fee periods in recentFeePeriods.

Field Type Description
feePeriodId uint64 A serial id for fee periods which is incremented for each new fee period.
startTime uint64 The current timestamp when this fee period began.
allNetworksSnxBackedDebt uint256 TBA
allNetworksDebtSharesSupply uint256 TBA
feesToDistribute uint256 The total of fees to be distributed in this period, in sUSD. This increases when fees are collected in the current period or when unclaimed fees roll over from the oldest period to the second oldest. See feePaid and closeCurrentPeriod.
feesClaimed uint256 The number of fees that have already been claimed during this period.
rewardsToDistribute uint256 The total of inflationary rewards to be distributed in this period, in SNX. This increases when new rewards are minted by Synthetix.mint/rewardsMinted, or when unclaimed rewards roll over from the oldest period to the second oldest (closeCurrentPeriod).
rewardsClaimed uint256 The quantity of inflationary rewards that have already been claimed during this period.

Variables

CONTRACT_NAME

Source

Type: bytes32

FEE_ADDRESS

Source

The address where fees are pooled as sUSD.

Value: 0xfeEFEEfeefEeFeefEEFEEfEeFeefEEFeeFEEFEeF

Type: address

FEE_PERIOD_LENGTH

Source

This is the number of weekly fee periods that are tracked by the smart contracts, hence the length of the recentFeePeriods array.

This was reduced from 6 to 3 as part of SIP-4 and now 2 periods 0 and 1, but note the inconsistency with the corresponding constant in FeePoolState, which cannot be altered.

Value: 2

Type: uint8

Constructor

constructor

Source

Details

Signature

constructor(address payable _proxy, address _owner, address _resolver)

Visibility

public

State Mutability

``

Views

allNetworksDebtSharesSupply

Source

Details

Signature

allNetworksDebtSharesSupply() view returns (uint256 sharesSupply, uint256 updatedAt)

Visibility

public

State Mutability

view

allNetworksSnxBackedDebt

Source

Details

Signature

allNetworksSnxBackedDebt() view returns (uint256 debt, uint256 updatedAt)

Visibility

public

State Mutability

view

effectiveDebtRatioForPeriod

Source

Given an account and an index into recentFeePeriods, this function computes the percentage of total debt ownership of the account at the end of that period.

This uses _effectiveDebtRatioForPeriod, where the start index and ownership percentage are computed with FeePoolState.applicableIssuanceData, and the end index is one before the beginnging of the next period. Hence this function disallows querying the debt for the current period.

In principle a future version could support the current fee period by using the last debt ledger entry as the end index.

Details

Signature

effectiveDebtRatioForPeriod(address account, uint256 period) view returns (uint256)

Visibility

external

State Mutability

view

feePeriodDuration

Source

This is the minimum duration of a single fee period in seconds. In practice they may be slightly longer if closeCurrentFeePeriod is not called immediately at the earliest valid moment.

Its value is one week, but it may be between MIN_FEE_PERIOD_DURATION and MAX_FEE_PERIOD_DURATION (1 to 60 days).

Type: uint256

Details

Signature

feePeriodDuration() view returns (uint256)

Visibility

external

State Mutability

view

feesAvailable

Source

Return the total of fees and rewards available to be withdrawn by this account. The result is reported as a [fees, rewards] pair denominated in the requested Synth flavour and SNX, respectively.

This is the total of fees accrued in completed periods, so is simply the the sum over an account's feesByPeriod not including the current period.

Details

Signature

feesAvailable(address account) view returns (uint256, uint256)

Visibility

public

State Mutability

view

feesBurned

Source

Details

Signature

feesBurned(address account) view returns (uint256)

Visibility

public

State Mutability

view

feesByPeriod

Source

Returns an array of FEE_PERIOD_LENGTH [fees, rewards] pairs owed to an account for each recent fee period (including the current one). Fees are denominated in sUSD and rewards in SNX.

To compute this, for each period from oldest to newest, find the latest issuance event this account performed before the close of this period, and use it to derive the owed fees and rewards for that period.

Note that a single issuance event can result in fees accruing for several fee periods, if the issuer does not claim their fees in one or more periods.

Periods where the user has already withdrawn since that period closed are skipped, producing [0,0] entries.

Details

Signature

feesByPeriod(address account) view returns (uint256[2][2] results)

Visibility

public

State Mutability

view

feesToBurn

Source

Details

Signature

feesToBurn(address account) view returns (uint256 feesFromPeriod)

Visibility

public

State Mutability

view

getLastFeeWithdrawal

Source

Returns from FeePoolEternalStorage the id of the fee period during which the given address last withdrew fees.

Details

Signature

getLastFeeWithdrawal(address _claimingAddress) view returns (uint256)

Visibility

public

State Mutability

view

getPenaltyThresholdRatio

Source

Returns the collateralisation level a user can reach before they cannot claim fees. This is simply SynthetixState.issuanceRatio * (1 + TARGET_THRESHOLD). The result is returned as a 18-decimal fixed point number.

Details

Signature

getPenaltyThresholdRatio() view returns (uint256)

Visibility

public

State Mutability

view

isFeesClaimable

Source

Details

Signature

isFeesClaimable(address account) view returns (bool feesClaimable)

Visibility

external

State Mutability

view

issuanceRatio

Source

Details

Signature

issuanceRatio() view returns (uint256)

Visibility

external

State Mutability

view

recentFeePeriods

Source

Stores fee period information for the last three weeks, from newest to olders.

recentFeePeriods[0] is always the current fee period, which is modified by ongoing issuance and fee activity. Fees cannot be claimed from the current period, only from the closed period at index 1 which is all the fees and rewards accrued in the previous fee period (week).

Type: FeePeriod[FEE_PERIOD_LENGTH] public

Details

Signature

recentFeePeriods(uint256 index) view returns (uint64 feePeriodId, uint64 unused, uint64 startTime, uint256 feesToDistribute, uint256 feesClaimed, uint256 rewardsToDistribute, uint256 rewardsClaimed)

Visibility

external

State Mutability

view

resolverAddressesRequired

Source

Details

Signature

resolverAddressesRequired() view returns (bytes32[] addresses)

Visibility

public

State Mutability

view

targetThreshold

Source

Type: uint256

Details

Signature

targetThreshold() view returns (uint256)

Visibility

external

State Mutability

view

totalFeesAvailable

Source

Computes the total fees available to be withdrawn, valued in terms of currencyKey. This simply sums the unclaimed fees over recentFeePeriods except those from the current period, because they cannot yet be claimed.

Details

Signature

totalFeesAvailable() view returns (uint256)

Visibility

external

State Mutability

view

totalFeesBurned

Source

Details

Signature

totalFeesBurned() view returns (uint256)

Visibility

external

State Mutability

view

totalRewardsAvailable

Source

Computes the total SNX rewards available to be withdrawn. This simply sums the unclaimed rewards over recentFeePeriods except those from the current period, because they cannot yet be claimed.

Details

Signature

totalRewardsAvailable() view returns (uint256)

Visibility

external

State Mutability

view

Restricted Functions

closeSecondary

Source

Details

Signature

closeSecondary(uint256 allNetworksSnxBackedDebt, uint256 allNetworksDebtSharesSupply)

Visibility

external

State Mutability

``

Modifiers

importFeePeriod

Source

During the setup period, allowed the contract owner to set a particular fee period entry in recentFeePeriods in order to migrate from a previous contract version.

Details

Signature

importFeePeriod(uint256 feePeriodIndex, uint256 feePeriodId, uint256 startTime, uint256 feesToDistribute, uint256 feesClaimed, uint256 rewardsToDistribute, uint256 rewardsClaimed)

Visibility

external

State Mutability

``

Requires

Modifiers

recordFeePaid

Source

Allows the Synthetix._internalExchange function to record that a fee was paid whenever an exchange between Synth flavours occurs.

Adds the value in sUSD to the current fee period's pool of fees to be distributed.

Details

Signature

recordFeePaid(uint256 amount)

Visibility

external

State Mutability

``

Modifiers

Internal Functions

_claimFees

Source

Claims fees and rewards owed to the specified address.

The account's collateralisation ratio must be less than the issuance ratio, plus the target threshold, as specified by the feesClaimable function. The quantity of fees and rewards owed is computed by feesAvailable.

Upon invocation, this function updates the account's last fee withdrawal time, and removes the claimed fees and rewards from the pool. Fees are paid into the claiming address in the specified currency, while the rewards are escrowed on behalf of the claiming address in the RewardEscrow contract for one year.

The return value is always true if the transaction was not reverted.

Details

Signature

_claimFees(address claimingAddress) returns (bool)

Visibility

internal

State Mutability

``

Requires

_closeSecondary

Source

Details

Signature

_closeSecondary(uint256 allNetworksSnxBackedDebt, uint256 allNetworksDebtSharesSupply)

Visibility

internal

State Mutability

``

_feesAndRewardsFromPeriod

Source

Computes the fees (in sUSD) and rewards (in SNX) owed at the end of a recent fee period given an entry index and the percentage of total system debt owned.

  • period is an index into the recentFeePeriods array, thus 0 corresponds with the current period.
  • debtEntryIndex should be an index into the debt ledger which was added before the close of the specified fee period.
  • ownershipPercentage should be the percentage of the account's debt ownership at that debtEntryIndex. This is a 27-decimal fixed point number.
Details

Signature

_feesAndRewardsFromPeriod(uint256 period, uint256 ownershipPercentage) view returns (uint256, uint256)

Visibility

internal

State Mutability

view

_isFeesClaimableAndAnyRatesInvalid

Source

Details

Signature

_isFeesClaimableAndAnyRatesInvalid(address account) view returns (bool, bool)

Visibility

internal

State Mutability

view

_isInternalContract

Source

Details

Signature

_isInternalContract(address account) view returns (bool)

Visibility

internal

State Mutability

view

_payRewards

Source

Pays a quantity of rewards to a specified address, escrowing it for one year with RewardEscrow.appendVestingEntry.

Details

Signature

_payRewards(address account, uint256 snxAmount)

Visibility

internal

State Mutability

``

Modifiers

_recentFeePeriodsStorage

Source

Details

Signature

_recentFeePeriodsStorage(uint256 index) view returns (struct FeePool.FeePeriod)

Visibility

internal

State Mutability

view

_recordRewardPayment

Source

Claims a quantity of SNX rewards from the recent fee periods. This is only called in _claimFees.

Its logic is identical to _recordFeePayment, except that the relevant quantities are in SNX, and are claimed from rewardsClaimed.

Details

Signature

_recordRewardPayment(uint256 snxAmount) returns (uint256)

Visibility

internal

State Mutability

``

_setLastFeeWithdrawal

Source

Stores into FeePoolEternalStorage the id of the fee period during which this address last withdrew fees.

Details

Signature

_setLastFeeWithdrawal(address _claimingAddress, uint256 _feePeriodID)

Visibility

internal

State Mutability

``

collateralManager

Source

Details

Signature

collateralManager() view returns (contract ICollateralManager)

Visibility

internal

State Mutability

view

delegateApprovals

Source

Details

Signature

delegateApprovals() view returns (contract IDelegateApprovals)

Visibility

internal

State Mutability

view

emitFeePeriodClosed

Source

Details

Signature

emitFeePeriodClosed(uint256 feePeriodId)

Visibility

internal

State Mutability

``

emitFeesClaimed

Source

Details

Signature

emitFeesClaimed(address account, uint256 sUSDAmount, uint256 snxRewards)

Visibility

internal

State Mutability

``

etherWrapper

Source

Details

Signature

etherWrapper() view returns (contract IEtherWrapper)

Visibility

internal

State Mutability

view

exchanger

Source

Details

Signature

exchanger() view returns (contract IExchanger)

Visibility

internal

State Mutability

view

feePoolEternalStorage

Source

The FeePoolEternalStorage key-value store that holds account last withdrawal times.

Type: FeePoolEternalStorage public

Details

Signature

feePoolEternalStorage() view returns (contract FeePoolEternalStorage)

Visibility

internal

State Mutability

view

futuresMarketManager

Source

Details

Signature

futuresMarketManager() view returns (contract IFuturesMarketManager)

Visibility

internal

State Mutability

view

issuer

Source

Details

Signature

issuer() view returns (contract IIssuer)

Visibility

internal

State Mutability

view

rewardEscrowV2

Source

Details

Signature

rewardEscrowV2() view returns (contract IRewardEscrowV2)

Visibility

internal

State Mutability

view

rewardsDistribution

Source

Details

Signature

rewardsDistribution() view returns (contract IRewardsDistribution)

Visibility

internal

State Mutability

view

synthetixDebtShare

Source

Details

Signature

synthetixDebtShare() view returns (contract ISynthetixDebtShare)

Visibility

internal

State Mutability

view

systemStatus

Source

Details

Signature

systemStatus() view returns (contract ISystemStatus)

Visibility

internal

State Mutability

view

wrapperFactory

Source

Details

Signature

wrapperFactory() view returns (contract IWrapperFactory)

Visibility

internal

State Mutability

view

External Functions

claimFees

Source

The message sender claims their fees in sUSD.

This is equivalent to _claimFees(messageSender).

Details

Signature

claimFees() returns (bool)

Visibility

external

State Mutability

``

Modifiers

claimOnBehalf

Source

The message sender claims fees in sUSD for a specified address; the funds are remitted to that address, and not to the sender.

This function first checks with the DelegateApprovals contract that the sender is approved to claim fees on behalf of the specified address, but is otherwise equivalent to _claimFees(claimingForAddress).

Details

Signature

claimOnBehalf(address claimingForAddress) returns (bool)

Visibility

external

State Mutability

``

Requires

Modifiers

closeCurrentFeePeriod

Source

If the current fee period has been open for longer than feePeriodDuration, then anyone may call this function to close it and open a new one.

The new fee period is added to the beginning of the recentFeePeriods list, and the last one is discarded. Any unclaimed fees from the last fee period roll over into the penultimate fee period.

The new fee period's feePeriodId is the previous id incremented by 1, and its startingDebtIndex is the length of SynthetixState.debtLedger at the time the fee period rolls over. Note that before a new minting event occurs this index will be one past the end of the ledger.

Details

Signature

closeCurrentFeePeriod()

Visibility

external

State Mutability

``

Requires

Modifiers

setRewardsToDistribute

Source

Adds a quantity of SNX to the current fee period's total of rewards to be distributed.

Details

Signature

setRewardsToDistribute(uint256 amount)

Visibility

external

State Mutability

``

Requires

Modifiers

Modifiers

issuanceActive

Source

notFeeAddress

Source

Reverts the transaction if account is the fee address.

Signature: notFeeAddress(address account)

onlyInternalContracts

Source

onlyRelayer

Source

Events

FeePeriodClosed

Source

Signature: FeePeriodClosed(uint256 feePeriodId)

FeesClaimed

Source

Records that an account claimed the fees and rewards owed to them.

This event is emitted from the FeePool's proxy with the emitFeesClaimed function.

Signature: FeesClaimed(address account, uint256 sUSDAmount, uint256 snxRewards)