Set Documentation
Search…
Enabling Fees
​
​
SetToken managers can charge fees for their services by enabling modules which support it. The most commonly used fee collection modules are for streaming fees and issuance.
Streaming fees are time-based and similar to annual management fees. Issuance fees accrue when someone issues or redeems a SetToken. Both are paid in SetToken by inflating the token's total supply and apportioning the additional balance to designated fee recipients.
Typically the fee collection modules you'll require are added to your SetToken as part of the token creation process.
Fee setting and collection are managed using a separately deployed FeeSplitExtension contract which allows you to:
  • set initial fee structures in place
  • update fees as necessary,
  • split fees between beneficiaries
  • accrue any owed fees at will
The FeeExtension contract is also the temporary holder of any fees that accrue prior to distribution.
The set-v2-strategies-deployments repo provides an annotated script to execute and initialize this extension deploymentfrom the command line. The FeeExtension constructor allow you to to split fees with the manager contract's operator and set the magnitude of this split.
Below we'll look at FeeExtension's methods and how to use them via the Etherscan write UI

accrueFeesAndDistribute

ANYONE CALLABLE: Accrues and distributes fees from streaming fee module. Gets resulting balance after fee accrual, calculates fees for operator and methodologist, and sends to operator fee recipient and methodologist respectively. NOTE: mint/redeem fees will automatically be sent to the FeeExtension contract's address so reading the balance of the SetToken in the contract after accrual is sufficient for accounting for all collected fees.
This method takes no parameters and can be called by anyone.
Example of executing a call to accrue and distribute

updateStreamingFee

OPERATOR ONLY: Updates streaming fee on StreamingFeeModule. By default, this method is time-locked to protect token owners from sudden changes in fee structure which they would rather not bear. The delay gives them a chance to exit their positions without penalty. The time-lock requires that the method is called twice, once to set the lock (indicating a fee update is pending) and once to execute the update (after the waiting period has elapsed).
NOTE: Invoking this method accrues streaming fees without forwarding them to operator fee recipient and methodologist. To distribute the fees you should call accrueFeesAndDistribute()
Parameters
  • _newFee Percent of Set accruing to fee extension annually (1% = 1e16, 100% = 1e18)
Example of setting the streaming fee to 1%

updateIssueFee

OPERATOR ONLY: Updates the issuance fee on the Issuance module. By default, this method is timelocked to protect token owners from sudden changes in fee structure which they would rather not bear. The delay gives them a chance to exit their positions without penalty. The timelock requires that the method is called twice, once to set the lock (indicating a fee update is pending) and once to execute the update (after the waiting period has elapsed).
  • _newFee New issue fee percentage in precise units (1% = 1e16, 100% = 1e18)
Example of setting the issue fee to 1%

updateRedeemFee

OPERATOR ONLY: Updates the redeem fee on the Issuance module. By default, this method is timelocked to protect token owners from sudden changes in fee structure which they would rather not bear. The delay gives them a chance to exit their positions without penalty. The timelock requires that the method is called twice, once to set the lock (indicating a fee update is pending) and once to execute the update (after the waiting period has elapsed).
  • _newFee New redeem fee percentage in precise units (1% = 1e16, 100% = 1e18)
Example of setting the redeem fee to 1%

updateFeeSplit

OPERATOR ONLY: Updates the fee split between operator and methodologist.
  • _newFeeSplit: Percent of fees in precise units (10^16 = 1%) sent to operator, (rest go to the methodologist).
Example of setting the fee split to 1%

updateOperatorFeeRecipient

Updates the address that receives the operator's share of the fees
  • _newOperatorFeeRecipient Address to send operator's fees to.
Example of setting the fee recipient to an address

initializeStreamingFeeModule

OPERATOR ONLY: This method is called to configure the streaming fee module's initial fee settings. It accepts a FeeState struct with the following format:
struct FeeState {
address feeRecipient; // Address to accrue fees to
uint256 maxStreamingFeePercentage; // Max streaming fee maanager commits to using (1% = 1e16, 100% = 1e18)
uint256 streamingFeePercentage; // Percent of Set accruing to manager annually (1% = 1e16, 100% = 1e18)
uint256 lastStreamingFeeTimestamp; // Timestamp last streaming fee was accrued
}
It's convenient to execute this initialization as part of a command line deployment script. An example of an initializing streaming fees using Ethers in Typescript looks like:
// `ether()` converts a number to 1e18
const feeSettings = {
feeRecipient: feeExtensionInstance.address,
maxStreamingFeePercentage: ether(.01),
streamingFeePercentage: ether(.01),
lastStreamingFeeTimestamp: ZERO,
};
​
await feeExtensionInstance
.connect(caller.wallet)
.initializeStreamingFeeModule(subjectFeeSettings);

initializeIssuanceModule

OPERATOR ONLY: This method is called to configure the issuance module's initial fee settings.
Parameters
  • _maxManagerFee Max size of issuance and redeem fees in precise units (10^16 = 1%).
  • _managerIssueFee Manager issuance fees in precise units (10^16 = 1%)
  • _managerRedeemFee Manager redeem fees in precise units (10^16 = 1%)
  • _feeRecipient Address that receives all manager issue and redeem fees
  • _managerIssuanceHook Address of manager defined hook contract
It's convenient to execute this initialization as part of a command line deployment script. An example of an initializing issuance fees using Ethers in Typescript looks like:
// `ether()` converts a number to 1e18
await feeExtensionInstance.connect(operator.wallet).initializeIssuanceModule(
ether(.1), // Max manager fee = 10%
ether(.01), // Manager issue fee = 1%
ether(.005), // Manager redeem fee = .5%
feeExtensionInstance.address // Set this extension address as the pre-distribution recipient of all fees
ADDRESS_ZERO // Issuance hook contract, if applicable
);
Copy link
On this page
accrueFeesAndDistribute
updateStreamingFee
updateIssueFee
updateRedeemFee
updateFeeSplit
updateOperatorFeeRecipient
initializeIssuanceModule