@@ -39,7 +39,7 @@ contract BiconomySponsorshipPaymaster is
39
39
40
40
address public verifyingSigner;
41
41
address public feeCollector;
42
- uint48 public postopCost ;
42
+ uint48 public postOpCost ;
43
43
uint32 private constant PRICE_DENOMINATOR = 1e6 ;
44
44
45
45
// note: could rename to PAYMASTER_ID_OFFSET
@@ -55,8 +55,11 @@ contract BiconomySponsorshipPaymaster is
55
55
)
56
56
BasePaymaster (_owner, _entryPoint)
57
57
{
58
- // TODO
59
- // Check for zero address
58
+ if (_verifyingSigner == address (0 )) {
59
+ revert VerifyingSignerCanNotBeZero ();
60
+ } else if (_feeCollector == address (0 )) {
61
+ revert FeeCollectorCanNotBeZero ();
62
+ }
60
63
verifyingSigner = _verifyingSigner;
61
64
feeCollector = _feeCollector;
62
65
}
@@ -123,17 +126,19 @@ contract BiconomySponsorshipPaymaster is
123
126
* @notice only to be called by the owner of the contract.
124
127
*/
125
128
function setPostopCost (uint48 value ) external payable onlyOwner {
126
- require (value <= 200_000 , "Gas overhead too high " );
127
- uint256 oldValue = postopCost;
128
- postopCost = value;
129
+ if (value > 200_000 ) {
130
+ revert PostOpCostTooHigh ();
131
+ }
132
+ uint256 oldValue = postOpCost;
133
+ postOpCost = value;
129
134
emit PostopCostChanged (oldValue, value);
130
135
}
131
136
132
137
/**
133
138
* @dev Override the default implementation.
134
139
*/
135
140
function deposit () external payable virtual override {
136
- revert ( " Use depositFor() instead " );
141
+ revert UseDepositForInstead ( );
137
142
}
138
143
139
144
/**
@@ -155,15 +160,19 @@ contract BiconomySponsorshipPaymaster is
155
160
function withdrawTo (address payable withdrawAddress , uint256 amount ) external override nonReentrant {
156
161
if (withdrawAddress == address (0 )) revert CanNotWithdrawToZeroAddress ();
157
162
uint256 currentBalance = paymasterIdBalances[msg .sender ];
158
- require (amount <= currentBalance, "Sponsorship Paymaster: Insufficient funds to withdraw from gas tank " );
163
+ if (amount > currentBalance) {
164
+ revert InsufficientFundsInGasTank ();
165
+ }
159
166
paymasterIdBalances[msg .sender ] = currentBalance - amount;
160
167
entryPoint.withdrawTo (withdrawAddress, amount);
161
168
emit GasWithdrawn (msg .sender , withdrawAddress, amount);
162
169
}
163
170
164
- function withdrawEth (address payable recipient , uint256 amount ) external onlyOwner {
171
+ function withdrawEth (address payable recipient , uint256 amount ) external onlyOwner nonReentrant {
165
172
(bool success ,) = recipient.call { value: amount }("" );
166
- require (success, "withdraw failed " );
173
+ if (! success) {
174
+ revert WithdrawalFailed ();
175
+ }
167
176
}
168
177
169
178
/**
@@ -225,20 +234,19 @@ contract BiconomySponsorshipPaymaster is
225
234
bytes calldata signature
226
235
)
227
236
{
228
- paymasterId = address (bytes20 (paymasterAndData[VALID_PND_OFFSET:VALID_PND_OFFSET + 20 ]));
229
- validUntil = uint48 (bytes6 (paymasterAndData[VALID_PND_OFFSET + 20 :VALID_PND_OFFSET + 26 ]));
230
- validAfter = uint48 (bytes6 (paymasterAndData[VALID_PND_OFFSET + 26 :VALID_PND_OFFSET + 32 ]));
231
- priceMarkup = uint32 (bytes4 (paymasterAndData[VALID_PND_OFFSET + 32 :VALID_PND_OFFSET + 36 ]));
232
- signature = paymasterAndData[VALID_PND_OFFSET + 36 :];
237
+ unchecked {
238
+ paymasterId = address (bytes20 (paymasterAndData[VALID_PND_OFFSET:VALID_PND_OFFSET + 20 ]));
239
+ validUntil = uint48 (bytes6 (paymasterAndData[VALID_PND_OFFSET + 20 :VALID_PND_OFFSET + 26 ]));
240
+ validAfter = uint48 (bytes6 (paymasterAndData[VALID_PND_OFFSET + 26 :VALID_PND_OFFSET + 32 ]));
241
+ priceMarkup = uint32 (bytes4 (paymasterAndData[VALID_PND_OFFSET + 32 :VALID_PND_OFFSET + 36 ]));
242
+ signature = paymasterAndData[VALID_PND_OFFSET + 36 :];
243
+ }
233
244
}
234
245
235
246
/// @notice Performs post-operation tasks, such as deducting the sponsored gas cost from the paymasterId's balance
236
247
/// @dev This function is called after a user operation has been executed or reverted.
237
248
/// @param context The context containing the token amount and user sender address.
238
249
/// @param actualGasCost The actual gas cost of the transaction.
239
- /// @param actualUserOpFeePerGas - the gas price this UserOp pays. This value is based on the UserOp's maxFeePerGas
240
- // and maxPriorityFee (and basefee)
241
- // It is not the same as tx.gasprice, which is what the bundler pays.
242
250
function _postOp (
243
251
PostOpMode,
244
252
bytes calldata context ,
@@ -249,23 +257,24 @@ contract BiconomySponsorshipPaymaster is
249
257
override
250
258
{
251
259
unchecked {
252
- (address paymasterId , uint32 dynamicMarkup , bytes32 userOpHash ) =
260
+ (address paymasterId , uint32 dynamicAdjustment , bytes32 userOpHash ) =
253
261
abi.decode (context, (address , uint32 , bytes32 ));
254
262
255
- uint256 balToDeduct = actualGasCost + postopCost * actualUserOpFeePerGas;
256
-
257
- uint256 costIncludingPremium = (balToDeduct * dynamicMarkup) / PRICE_DENOMINATOR;
263
+ uint256 totalGasCost = actualGasCost + (postOpCost * actualUserOpFeePerGas);
264
+ uint256 adjustedGasCost = (totalGasCost * dynamicAdjustment) / PRICE_DENOMINATOR;
258
265
259
- // deduct with premium
260
- paymasterIdBalances[paymasterId] -= costIncludingPremium ;
266
+ // Deduct the adjusted cost
267
+ paymasterIdBalances[paymasterId] -= adjustedGasCost ;
261
268
262
- uint256 actualPremium = costIncludingPremium - balToDeduct;
263
- // "collect" premium
264
- paymasterIdBalances[feeCollector] += actualPremium;
269
+ if (adjustedGasCost > actualGasCost) {
270
+ // Add premium to fee
271
+ uint256 premium = adjustedGasCost - actualGasCost;
272
+ paymasterIdBalances[feeCollector] += premium;
273
+ // Review if we should emit adjustedGasCost as well
274
+ emit PremiumCollected (paymasterId, premium);
275
+ }
265
276
266
- emit GasBalanceDeducted (paymasterId, costIncludingPremium, userOpHash);
267
- // Review if we should emit balToDeduct as well
268
- emit PremiumCollected (paymasterId, actualPremium);
277
+ emit GasBalanceDeducted (paymasterId, adjustedGasCost, userOpHash);
269
278
}
270
279
}
271
280
@@ -294,10 +303,9 @@ contract BiconomySponsorshipPaymaster is
294
303
//ECDSA library supports both 64 and 65-byte long signatures.
295
304
// we only "require" it here so that the revert reason on invalid signature will be of "VerifyingPaymaster", and
296
305
// not "ECDSA"
297
- require (
298
- signature.length == 64 || signature.length == 65 ,
299
- "VerifyingPaymaster: invalid signature length in paymasterAndData "
300
- );
306
+ if (signature.length != 64 && signature.length != 65 ) {
307
+ revert InvalidSignatureLength ();
308
+ }
301
309
302
310
bool validSig = verifyingSigner.isValidSignatureNow (
303
311
ECDSA_solady.toEthSignedMessageHash (getHash (userOp, paymasterId, validUntil, validAfter, priceMarkup)),
@@ -309,18 +317,19 @@ contract BiconomySponsorshipPaymaster is
309
317
return ("" , _packValidationData (true , validUntil, validAfter));
310
318
}
311
319
312
- require (priceMarkup <= 2e6 && priceMarkup > 0 , " Sponsorship Paymaster: Invalid markup % " );
313
-
314
- uint256 maxFeePerGas = userOp. unpackMaxFeePerGas ();
320
+ if (priceMarkup > 2e6 || priceMarkup == 0 ) {
321
+ revert InvalidPriceMarkup ();
322
+ }
315
323
316
324
// Send 1e6 for No markup
317
325
// Send between 0 and 1e6 for discount
318
- uint256 effectiveCost = (( requiredPreFund + (postopCost * maxFeePerGas)) * priceMarkup) / PRICE_DENOMINATOR;
326
+ uint256 effectiveCost = (requiredPreFund * priceMarkup) / PRICE_DENOMINATOR;
319
327
320
- require (
321
- effectiveCost <= paymasterIdBalances[paymasterId],
322
- "Sponsorship Paymaster: paymasterId does not have enough deposit "
323
- );
328
+ if (effectiveCost > paymasterIdBalances[paymasterId]) {
329
+ revert InsufficientFundsForPaymasterId ();
330
+ }
331
+
332
+ context = abi.encode (paymasterId, priceMarkup, userOpHash);
324
333
325
334
context = abi.encode (paymasterId, priceMarkup, userOpHash);
326
335
0 commit comments