Skip to content

Commit a946b64

Browse files
committed
Handling ssc cost via stakes.
1 parent 3f88c50 commit a946b64

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

contracts/core/EntryPoint.sol

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import "../interfaces/IAccount.sol";
77
import "../interfaces/IAccountExecute.sol";
88
import "../interfaces/IPaymaster.sol";
99
import "../interfaces/IEntryPoint.sol";
10+
import "../interfaces/ISscOpcodes.sol";
1011

1112
import "../utils/Exec.sol";
1213
import "./StakeManager.sol";
@@ -28,8 +29,18 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard,
2829

2930
using UserOperationLib for PackedUserOperation;
3031

32+
int256 constant public SSC_STORAGE_SLOT_COST = 12800000000000000;
33+
int256 constant public SSC_STORAGE_SLOT_REFUND = 12672000000000000;
34+
35+
int256 constant public SSC_ACCOUNT_COST = 12800000000000000;
36+
int256 constant public SSC_ACCOUNT_REFUND = 12672000000000000;
37+
38+
int256 constant public SSC_CODE_CREATED_COST = 12800000000000000;
39+
3140
SenderCreator private immutable _senderCreator = new SenderCreator();
3241

42+
ISscOpcodes private immutable _ssc = ISscOpcodes(address(0x665e930982A9a03c844641d453a2C3462ED7Ff41));
43+
3344
function senderCreator() internal view virtual returns (SenderCreator) {
3445
return _senderCreator;
3546
}
@@ -82,6 +93,7 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard,
8293
returns
8394
(uint256 collected) {
8495
uint256 preGas = gasleft();
96+
int256 preSSC = _netSSC();
8597
bytes memory context = getMemoryBytesFromOffset(opInfo.contextOffset);
8698
bool success;
8799
{
@@ -110,6 +122,13 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard,
110122
collected := mload(0)
111123
mstore(0x40, saveFreePtr)
112124
}
125+
int256 netSSC = _netSSC() - preSSC;
126+
if (netSSC < 0) {
127+
// increment deposit for the user's account
128+
_incrementDeposit(userOp.sender, uint256(-netSSC));
129+
} else {
130+
_decrementDeposit(userOp.sender, uint256(netSSC));
131+
}
113132
}
114133
if (!success) {
115134
bytes32 innerRevertCode;
@@ -178,6 +197,8 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard,
178197
uint256 opslen = ops.length;
179198
UserOpInfo[] memory opInfos = new UserOpInfo[](opslen);
180199

200+
int256 preSSC = _netSSC();
201+
181202
unchecked {
182203
for (uint256 i = 0; i < opslen; i++) {
183204
UserOpInfo memory opInfo = opInfos[i];
@@ -200,6 +221,15 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard,
200221
collected += _executeUserOp(i, ops[i], opInfos[i]);
201222
}
202223

224+
// this can be negative in cases of refunds
225+
int256 netSSC = _netSSC() - preSSC;
226+
if (netSSC < 0) {
227+
_decrementDeposit(beneficiary, uint256(netSSC));
228+
} else {
229+
// increment deposit for the user's account
230+
_incrementDeposit(beneficiary, uint256(-netSSC));
231+
}
232+
203233
_compensate(beneficiary, collected);
204234
}
205235
}
@@ -413,6 +443,15 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard,
413443
}
414444
}
415445

446+
/**
447+
* Calculates total ssc cost / refund
448+
*/
449+
function _netSSC() internal view returns (int256) {
450+
return int256(_ssc.accountsCreated()) * SSC_ACCOUNT_COST - int256(_ssc.accountsCleared()) * SSC_ACCOUNT_REFUND
451+
+ int256(_ssc.slotsCreated()) * SSC_STORAGE_SLOT_COST - int256(_ssc.slotsCleared()) * SSC_STORAGE_SLOT_REFUND
452+
+ int256(_ssc.codeCreated()) * SSC_CODE_CREATED_COST;
453+
}
454+
416455
/**
417456
* Create sender smart contract account if init code is provided.
418457
* @param opIndex - The operation index.

contracts/core/StakeManager.sol

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ abstract contract StakeManager is IStakeManager {
5656
return newAmount;
5757
}
5858

59+
/**
60+
* Increments an account's deposit.
61+
* @param account - The account to increment.
62+
* @param amount - The amount to increment by.
63+
* @return the updated deposit of this account
64+
*/
65+
function _decrementDeposit(address account, uint256 amount) internal returns (uint256) {
66+
unchecked {
67+
DepositInfo storage info = deposits[account];
68+
require(info.deposit >= amount, "cannot decrement stake");
69+
uint256 newAmount = info.deposit - amount;
70+
info.deposit = newAmount;
71+
return newAmount;
72+
}
73+
}
74+
5975
/**
6076
* Add to the deposit of the given account.
6177
* @param account - The account to add to.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity ^0.8.23;
3+
4+
interface ISscOpcodes {
5+
function accountsCreated() external view returns (uint256); // D0
6+
function accountsCleared() external view returns (uint256); // D1
7+
function slotsCreated() external view returns (uint256); // D2
8+
function slotsCleared() external view returns (uint256); // D3
9+
function codeCreated() external view returns (uint256); // D4
10+
}

0 commit comments

Comments
 (0)