@@ -77,6 +77,8 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
7777
7878 uint256 internal _totalShares;
7979
80+ uint256 public multiplierNonce;
81+
8082 // Events:
8183
8284 /**
@@ -104,13 +106,37 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
104106 // Modifiers:
105107
106108 modifier updateMultiplier () {
107- (uint256 newMultiplier , uint256 periodsPassed ) = getCurrentMultiplier ();
109+ (uint256 newMultiplier , uint256 periodsPassed , uint256 newMultiplierNonce ) = getCurrentMultiplier ();
108110 lastTimeFeeApplied = lastTimeFeeApplied + periodLength * periodsPassed;
109111 if (multiplier != newMultiplier) {
110- _updateMultiplier (newMultiplier);
112+ _updateMultiplier (newMultiplier, newMultiplierNonce );
111113 }
112114 _;
113115 }
116+
117+ modifier onlyMultiplierUpdater () {
118+ require (
119+ _msgSender () == multiplierUpdater,
120+ "BackedToken: Only multiplier updater "
121+ );
122+ _;
123+ }
124+
125+ modifier onlyUpdatedMultiplier (uint256 oldMultiplier ) {
126+ require (
127+ multiplier == oldMultiplier,
128+ "BackedToken: Multiplier changed in the meantime "
129+ );
130+ _;
131+ }
132+
133+ modifier onlyNewerMultiplierNonce (uint256 newMultiplierNonce ) {
134+ require (
135+ multiplierNonce < newMultiplierNonce,
136+ "BackedToken: Multiplier nonce is outdated. "
137+ );
138+ _;
139+ }
114140
115141 // constructor, set lastTimeFeeApplied to lock the implementation instance.
116142 constructor () {
@@ -155,6 +181,7 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
155181 require (_lastTimeFeeApplied != 0 , "Invalid last time fee applied " );
156182
157183 multiplier = 1e18 ;
184+ multiplierNonce = 0 ;
158185 periodLength = _periodLength;
159186 lastTimeFeeApplied = _lastTimeFeeApplied;
160187 feePerPeriod = _feePerPeriod;
@@ -164,7 +191,7 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
164191 * @dev See {IERC20-totalSupply}.
165192 */
166193 function totalSupply () public view virtual override returns (uint256 ) {
167- (uint256 newMultiplier , ) = getCurrentMultiplier ();
194+ (uint256 newMultiplier , , ) = getCurrentMultiplier ();
168195 return _getUnderlyingAmountByShares (_totalShares, newMultiplier);
169196 }
170197
@@ -174,7 +201,7 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
174201 function balanceOf (
175202 address account
176203 ) public view virtual override returns (uint256 ) {
177- (uint256 newMultiplier , ) = getCurrentMultiplier ();
204+ (uint256 newMultiplier , , ) = getCurrentMultiplier ();
178205 return _getUnderlyingAmountByShares (sharesOf (account), newMultiplier);
179206 }
180207
@@ -186,14 +213,16 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
186213 public
187214 view
188215 virtual
189- returns (uint256 newMultiplier , uint256 periodsPassed )
216+ returns (uint256 newMultiplier , uint256 periodsPassed , uint256 newMultiplierNonce )
190217 {
191218 periodsPassed = (block .timestamp - lastTimeFeeApplied) / periodLength;
192219 newMultiplier = multiplier;
220+ newMultiplierNonce = multiplierNonce;
193221 if (feePerPeriod > 0 ) {
194222 for (uint256 index = 0 ; index < periodsPassed; index++ ) {
195223 newMultiplier = (newMultiplier * (1e18 - feePerPeriod)) / 1e18 ;
196224 }
225+ newMultiplierNonce += periodsPassed;
197226 }
198227 }
199228
@@ -210,7 +239,7 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
210239 function getSharesByUnderlyingAmount (
211240 uint256 _underlyingAmount
212241 ) external view returns (uint256 ) {
213- (uint256 newMultiplier , ) = getCurrentMultiplier ();
242+ (uint256 newMultiplier , , ) = getCurrentMultiplier ();
214243 return _getSharesByUnderlyingAmount (_underlyingAmount, newMultiplier);
215244 }
216245
@@ -220,7 +249,7 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
220249 function getUnderlyingAmountByShares (
221250 uint256 _sharesAmount
222251 ) external view returns (uint256 ) {
223- (uint256 newMultiplier , ) = getCurrentMultiplier ();
252+ (uint256 newMultiplier , , ) = getCurrentMultiplier ();
224253 return _getUnderlyingAmountByShares (_sharesAmount, newMultiplier);
225254 }
226255
@@ -319,7 +348,7 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
319348 }
320349
321350 /**
322- * @dev Function to change the contract multiplier, only if oldMultiplier did not change in the meantime. Allowed only for owner
351+ * @dev Function to change the contract multiplier, only if oldMultiplier did not change in the meantime. Allowed only for multiplierUpdater
323352 *
324353 * Emits a { MultiplierChanged } event
325354 *
@@ -328,16 +357,24 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
328357 function updateMultiplierValue (
329358 uint256 newMultiplier ,
330359 uint256 oldMultiplier
331- ) external updateMultiplier {
332- require (
333- _msgSender () == multiplierUpdater,
334- "BackedToken: Only multiplier updater "
335- );
336- require (
337- multiplier == oldMultiplier,
338- "BackedToken: Multiplier changed in the meantime "
339- );
340- _updateMultiplier (newMultiplier);
360+ ) public onlyMultiplierUpdater updateMultiplier onlyUpdatedMultiplier (oldMultiplier) {
361+ _updateMultiplier (newMultiplier, multiplierNonce + 1 );
362+ }
363+
364+ /**
365+ * @dev Function to change the contract multiplier with nonce, only if oldMultiplier did not change in the meantime. Allowed only for multiplierUpdater
366+ *
367+ * Emits a { MultiplierChanged } event
368+ *
369+ * @param newMultiplier New multiplier value
370+ * @param newMultiplierNonce New multplier nonce
371+ */
372+ function updateMultiplierWithNonce (
373+ uint256 newMultiplier ,
374+ uint256 oldMultiplier ,
375+ uint256 newMultiplierNonce
376+ ) external onlyMultiplierUpdater updateMultiplier onlyUpdatedMultiplier (oldMultiplier) onlyNewerMultiplierNonce (newMultiplierNonce){
377+ _updateMultiplier (newMultiplier, newMultiplierNonce);
341378 }
342379
343380 /**
@@ -469,8 +506,9 @@ contract BackedAutoFeeTokenImplementation is BackedTokenImplementation {
469506 *
470507 * Emit an {MultiplierUpdated} event.
471508 */
472- function _updateMultiplier (uint256 newMultiplier ) internal virtual {
509+ function _updateMultiplier (uint256 newMultiplier , uint256 newMultiplierNonce ) internal virtual {
473510 multiplier = newMultiplier;
511+ multiplierNonce = newMultiplierNonce;
474512 emit MultiplierUpdated (newMultiplier);
475513 }
476514
0 commit comments