@@ -23,22 +23,21 @@ import { Address } from "@openzeppelin/contracts/utils/Address.sol";
2323import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol " ;
2424
2525import { BaseExtension } from "../lib/BaseExtension.sol " ;
26+ import { IIssuanceModule } from "../interfaces/IIssuanceModule.sol " ;
2627import { IBaseManager } from "../interfaces/IBaseManager.sol " ;
2728import { ISetToken } from "../interfaces/ISetToken.sol " ;
2829import { IStreamingFeeModule } from "../interfaces/IStreamingFeeModule.sol " ;
2930import { PreciseUnitMath } from "../lib/PreciseUnitMath.sol " ;
3031import { TimeLockUpgrade } from "../lib/TimeLockUpgrade.sol " ;
31- import { MutualUpgrade } from "../lib/MutualUpgrade.sol " ;
3232
3333
3434/**
35- * @title StreamingFeeSplitExtension
35+ * @title FeeSplitExtension
3636 * @author Set Protocol
3737 *
38- * Smart contract manager extension that allows for splitting and setting streaming fees. Fee splits are updated by operator.
39- * Any fee updates are timelocked.
38+ * Smart contract extension that allows for splitting and setting streaming and mint/redeem fees.
4039 */
41- contract StreamingFeeSplitExtension is BaseExtension , TimeLockUpgrade , MutualUpgrade {
40+ contract FeeSplitExtension is BaseExtension , TimeLockUpgrade {
4241 using Address for address ;
4342 using PreciseUnitMath for uint256 ;
4443 using SafeMath for uint256 ;
@@ -56,6 +55,7 @@ contract StreamingFeeSplitExtension is BaseExtension, TimeLockUpgrade, MutualUpg
5655
5756 ISetToken public setToken;
5857 IStreamingFeeModule public streamingFeeModule;
58+ IIssuanceModule public issuanceModule;
5959
6060 // Percent of fees in precise units (10^16 = 1%) sent to operator, rest to methodologist
6161 uint256 public operatorFeeSplit;
@@ -68,13 +68,15 @@ contract StreamingFeeSplitExtension is BaseExtension, TimeLockUpgrade, MutualUpg
6868 constructor (
6969 IBaseManager _manager ,
7070 IStreamingFeeModule _streamingFeeModule ,
71+ IIssuanceModule _issuanceModule ,
7172 uint256 _operatorFeeSplit ,
7273 address _operatorFeeRecipient
7374 )
7475 public
7576 BaseExtension (_manager)
7677 {
7778 streamingFeeModule = _streamingFeeModule;
79+ issuanceModule = _issuanceModule;
7880 operatorFeeSplit = _operatorFeeSplit;
7981 operatorFeeRecipient = _operatorFeeRecipient;
8082 setToken = manager.setToken ();
@@ -83,9 +85,10 @@ contract StreamingFeeSplitExtension is BaseExtension, TimeLockUpgrade, MutualUpg
8385 /* ============ External Functions ============ */
8486
8587 /**
86- * ANYONE CALLABLE: Accrues fees from streaming fee module. Gets resulting balance after fee accrual,
87- * calculates fees for operator and methodologist, and sends to operatorFeeRecipient and methodologist
88- * respectively.
88+ * ANYONE CALLABLE: Accrues fees from streaming fee module. Gets resulting balance after fee accrual, calculates fees for
89+ * operator and methodologist, and sends to operator fee recipient and methodologist respectively. NOTE: mint/redeem fees
90+ * will automatically be sent to this address so reading the balance of the SetToken in the contract after accrual is
91+ * sufficient for accounting for all collected fees.
8992 */
9093 function accrueFeesAndDistribute () public {
9194 // Emits a FeeActualized event
@@ -110,97 +113,91 @@ contract StreamingFeeSplitExtension is BaseExtension, TimeLockUpgrade, MutualUpg
110113 }
111114
112115 /**
113- * MUTUAL UPGRADE: Initializes the streaming fee module. Operator and Methodologist must each call
114- * this function to execute the update .
116+ * ONLY OPERATOR: Updates streaming fee on StreamingFeeModule.
117+ * Because the method is timelocked, each party must call it twice: once to set the lock and once to execute .
115118 *
116- * This method is called after invoking `replaceProtectedModule` or `emergencyReplaceProtectedModule`
117- * to configure the replacement streaming fee module's fee settings.
119+ * Method is timelocked to protect token owners from sudden changes in fee structure which
120+ * they would rather not bear. The delay gives them a chance to exit their positions without penalty.
121+ *
122+ * NOTE: This will accrue streaming fees though not send to operator fee recipient and methodologist.
118123 *
119- * @dev FeeState settings encode the following struct
120- * ```
121- * struct FeeState {
122- * address feeRecipient; // Address to accrue fees to
123- * uint256 maxStreamingFeePercentage; // Max streaming fee maanager commits to using (1% = 1e16, 100% = 1e18)
124- * uint256 streamingFeePercentage; // Percent of Set accruing to manager annually (1% = 1e16, 100% = 1e18)
125- * uint256 lastStreamingFeeTimestamp; // Timestamp last streaming fee was accrued
126- *}
127- *```
128- * @param _settings FeeModule.FeeState settings
124+ * @param _newFee Percent of Set accruing to fee extension annually (1% = 1e16, 100% = 1e18)
129125 */
130- function initializeModule (IStreamingFeeModule.FeeState memory _settings )
126+ function updateStreamingFee ( uint256 _newFee )
131127 external
132- mutualUpgrade (manager.operator (), manager.methodologist ())
128+ onlyOperator
129+ timeLockUpgrade
133130 {
134- bytes memory callData = abi.encodeWithSelector (
135- IStreamingFeeModule.initialize.selector ,
136- manager.setToken (),
137- _settings
138- );
139-
131+ bytes memory callData = abi.encodeWithSignature ("updateStreamingFee(address,uint256) " , manager.setToken (), _newFee);
140132 invokeManager (address (streamingFeeModule), callData);
141133 }
142134
143135 /**
144- * MUTUAL UPGRADE: Updates streaming fee on StreamingFeeModule. Operator and Methodologist must
145- * each call this function to execute the update. Because the method is timelocked, each party
146- * must call it twice: once to set the lock and once to execute.
136+ * ONLY OPERATOR: Updates issue fee on IssuanceModule. Only is executed once time lock has passed.
137+ * Because the method is timelocked, each party must call it twice: once to set the lock and once to execute.
147138 *
148139 * Method is timelocked to protect token owners from sudden changes in fee structure which
149140 * they would rather not bear. The delay gives them a chance to exit their positions without penalty.
150141 *
151- * NOTE: This will accrue streaming fees though not send to operator fee recipient and methodologist.
152- *
153- * @param _newFee Percent of Set accruing to fee extension annually (1% = 1e16, 100% = 1e18)
142+ * @param _newFee New issue fee percentage in precise units (1% = 1e16, 100% = 1e18)
154143 */
155- function updateStreamingFee (uint256 _newFee )
144+ function updateIssueFee (uint256 _newFee )
156145 external
157- mutualUpgrade (manager. operator (), manager. methodologist ())
146+ onlyOperator
158147 timeLockUpgrade
159148 {
160- bytes memory callData = abi.encodeWithSelector (
161- IStreamingFeeModule.updateStreamingFee.selector ,
162- manager.setToken (),
163- _newFee
164- );
149+ bytes memory callData = abi.encodeWithSignature ("updateIssueFee(address,uint256) " , manager.setToken (), _newFee);
150+ invokeManager (address (issuanceModule), callData);
151+ }
165152
166- invokeManager (address (streamingFeeModule), callData);
153+ /**
154+ * ONLY OPERATOR: Updates redeem fee on IssuanceModule. Only is executed once time lock has passed.
155+ * Because the method is timelocked, each party must call it twice: once to set the lock and once to execute.
156+ *
157+ * Method is timelocked to protect token owners from sudden changes in fee structure which
158+ * they would rather not bear. The delay gives them a chance to exit their positions without penalty.
159+ *
160+ * @param _newFee New redeem fee percentage in precise units (1% = 1e16, 100% = 1e18)
161+ */
162+ function updateRedeemFee (uint256 _newFee )
163+ external
164+ onlyOperator
165+ timeLockUpgrade
166+ {
167+ bytes memory callData = abi.encodeWithSignature ("updateRedeemFee(address,uint256) " , manager.setToken (), _newFee);
168+ invokeManager (address (issuanceModule), callData);
167169 }
168170
169171 /**
170- * MUTUAL UPGRADE : Updates fee recipient on streaming fee module .
172+ * ONLY OPERATOR : Updates fee recipient on both streaming fee and issuance modules .
171173 *
172174 * @param _newFeeRecipient Address of new fee recipient. This should be the address of the fee extension itself.
173175 */
174176 function updateFeeRecipient (address _newFeeRecipient )
175177 external
176- mutualUpgrade (manager. operator (), manager. methodologist ())
178+ onlyOperator
177179 {
178- bytes memory callData = abi.encodeWithSelector (
179- IStreamingFeeModule.updateFeeRecipient.selector ,
180- manager.setToken (),
181- _newFeeRecipient
182- );
183-
180+ bytes memory callData = abi.encodeWithSignature ("updateFeeRecipient(address,address) " , manager.setToken (), _newFeeRecipient);
184181 invokeManager (address (streamingFeeModule), callData);
182+ invokeManager (address (issuanceModule), callData);
185183 }
186184
187185 /**
188- * MUTUAL UPGRADE: Updates fee split between operator and methodologist. Split defined in precise units (1% = 10^16).
189- * Fees will be accrued and distributed before the new split goes into effect.
186+ * ONLY OPERATOR: Updates fee split between operator and methodologist. Split defined in precise units (1% = 10^16).
190187 *
191188 * @param _newFeeSplit Percent of fees in precise units (10^16 = 1%) sent to operator, (rest go to the methodologist).
192189 */
193190 function updateFeeSplit (uint256 _newFeeSplit )
194191 external
195- mutualUpgrade (manager. operator (), manager. methodologist ())
192+ onlyOperator
196193 {
197194 require (_newFeeSplit <= PreciseUnitMath.preciseUnit (), "Fee must be less than 100% " );
198195 accrueFeesAndDistribute ();
199196 operatorFeeSplit = _newFeeSplit;
200197 }
201198
202199 /**
203- * OPERATOR ONLY: Updates the address that receives the operator's share of the fees (see IIP-72)
200+ * ONLY OPERATOR : Updates the address that receives the operator's fees (see IIP-72)
204201 *
205202 * @param _newOperatorFeeRecipient Address to send operator's fees to.
206203 */
@@ -211,4 +208,4 @@ contract StreamingFeeSplitExtension is BaseExtension, TimeLockUpgrade, MutualUpg
211208 require (_newOperatorFeeRecipient != address (0 ), "Zero address not valid " );
212209 operatorFeeRecipient = _newOperatorFeeRecipient;
213210 }
214- }
211+ }
0 commit comments