1
1
// SPDX-License-Identifier: MIT
2
2
pragma solidity ^ 0.8.28 ;
3
3
4
+ import {LibPercentage} from "../libs/LibPercentage.sol " ;
4
5
import {ICheckpointTracker} from "./ICheckpointTracker.sol " ;
5
6
import {IProposerFees} from "./IProposerFees.sol " ;
6
7
import {IProverManager} from "./IProverManager.sol " ;
7
8
import {IPublicationFeed} from "./IPublicationFeed.sol " ;
9
+
8
10
import "@openzeppelin/contracts/utils/math/SafeCast.sol " ;
9
11
10
12
abstract contract BaseProverManager is IProposerFees , IProverManager {
11
13
using SafeCast for uint256 ;
14
+ using LibPercentage for uint96 ;
12
15
13
16
struct Period {
14
17
// SLOT 1
@@ -17,7 +20,7 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
17
20
// SLOT 2
18
21
// the fee that the prover is willing to charge for proving each publication
19
22
uint96 fee;
20
- // the percentage (in bps ) of the fee that is charged for delayed publications.
23
+ // the percentage (with two decimals precision ) of the fee that is charged for delayed publications.
21
24
uint16 delayedFeePercentage;
22
25
// the timestamp of the end of the period. Default to zero while the period is open.
23
26
uint40 end;
@@ -94,7 +97,7 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
94
97
// Deduct fee from proposer's balance
95
98
uint96 fee = _periods[periodId].fee;
96
99
if (isDelayed) {
97
- fee = _calculatePercentage ( fee, _periods[periodId].delayedFeePercentage). toUint96 ( );
100
+ fee = fee. scaleByPercentage ( _periods[periodId].delayedFeePercentage);
98
101
}
99
102
_balances[proposer] -= fee;
100
103
}
@@ -147,7 +150,7 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
147
150
(uint40 end ,) = _closePeriod (period, _exitDelay (), 0 );
148
151
149
152
// Reward the evictor and slash the prover
150
- uint96 evictorIncentive = _calculatePercentage ( period.stake, _evictorIncentivePercentage ()). toUint96 ( );
153
+ uint96 evictorIncentive = period.stake. scaleByBPS ( _evictorIncentivePercentage ());
151
154
_balances[msg .sender ] += evictorIncentive;
152
155
period.stake -= evictorIncentive;
153
156
@@ -209,7 +212,7 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
209
212
uint256 delayedPubFee;
210
213
211
214
if (numDelayedPublications > 0 ) {
212
- uint256 delayedFee = _calculatePercentage ( baseFee, period.delayedFeePercentage);
215
+ uint96 delayedFee = baseFee. scaleByPercentage ( period.delayedFeePercentage);
213
216
delayedPubFee = numDelayedPublications * delayedFee;
214
217
}
215
218
@@ -228,8 +231,7 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
228
231
require (provenPublication.timestamp > period.end, "Publication must be after period " );
229
232
230
233
uint96 stake = period.stake;
231
- _balances[period.prover] +=
232
- period.pastDeadline ? _calculatePercentage (stake, _rewardPercentage ()).toUint96 () : stake;
234
+ _balances[period.prover] += period.pastDeadline ? stake.scaleByBPS (_rewardPercentage ()) : stake;
233
235
period.stake = 0 ;
234
236
}
235
237
@@ -246,7 +248,7 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
246
248
247
249
Period storage period = _periods[currentPeriod];
248
250
fee = period.fee;
249
- delayedFee = _calculatePercentage ( fee, period.delayedFeePercentage). toUint96 ( );
251
+ delayedFee = fee. scaleByPercentage ( period.delayedFeePercentage);
250
252
}
251
253
252
254
/// @notice Get the balance of a user
@@ -273,7 +275,7 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
273
275
/// @param fee The fee to be outbid (either the current period's fee or next period's winning fee)
274
276
/// @param offeredFee The new bid
275
277
function _ensureSufficientUnderbid (uint96 fee , uint96 offeredFee ) internal view virtual {
276
- uint256 requiredMaxFee = _calculatePercentage ( fee, _maxBidPercentage ());
278
+ uint96 requiredMaxFee = fee. scaleByBPS ( _maxBidPercentage ());
277
279
require (offeredFee <= requiredMaxFee, "Offered fee not low enough " );
278
280
}
279
281
@@ -310,10 +312,9 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
310
312
/// @return _ The reward percentage
311
313
function _rewardPercentage () internal view virtual returns (uint16 );
312
314
313
- /// @dev The percentage (in bps) of the fee that is charged for delayed publications
314
- /// @dev It is recommended to set this to >10,000 bps since delayed publications should usually be charged at a
315
- /// higher rate
316
- /// @return _ The multiplier expressed in basis points. This value should usually be greater than 10,000 bps(100%).
315
+ /// @dev The percentage of the fee that is charged for delayed publications
316
+ /// @dev It is recommended to set this to >100 since delayed publications should usually be charged at a higher rate
317
+ /// @return _ The multiplier as a percentage (two decimals). This value should usually be greater than 100 (100%).
317
318
function _delayedFeePercentage () internal view virtual returns (uint16 );
318
319
319
320
/// @dev Increases `user`'s balance by `amount` and emits a `Deposit` event
@@ -339,14 +340,6 @@ abstract contract BaseProverManager is IProposerFees, IProverManager {
339
340
_updatePeriod (nextPeriod, prover, fee, _livenessBond ());
340
341
}
341
342
342
- /// @dev Calculates the percentage of a given numerator scaling up to avoid precision loss
343
- /// @param amount The number to calculate the percentage of
344
- /// @param bps The percentage expressed in basis points(https://muens.io/solidity-percentages)
345
- /// @return _ The calculated percentage of the given numerator
346
- function _calculatePercentage (uint256 amount , uint256 bps ) private pure returns (uint256 ) {
347
- return (amount * bps) / 10_000 ;
348
- }
349
-
350
343
/// @dev Updates a period with prover information and transfers the liveness bond
351
344
/// @param period The period to update
352
345
/// @param prover The address of the prover
0 commit comments