Skip to content

Commit

Permalink
replace results.push with index
Browse files Browse the repository at this point in the history
  • Loading branch information
mouseless0x committed Oct 4, 2024
1 parent 8b41b05 commit 801e5c3
Showing 1 changed file with 54 additions and 124 deletions.
178 changes: 54 additions & 124 deletions src/EntryPointSimulations.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,17 @@ import "./IEntryPointSimulations.sol";
*/
contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
// solhint-disable-next-line var-name-mixedcase
AggregatorStakeInfo private NOT_AGGREGATED =
AggregatorStakeInfo(address(0), StakeInfo(0, 0));
AggregatorStakeInfo private NOT_AGGREGATED = AggregatorStakeInfo(address(0), StakeInfo(0, 0));

SenderCreator private _senderCreator;

function initSenderCreator() internal virtual {
//this is the address of the first contract created with CREATE by this address.
address createdObj = address(
uint160(
uint256(
keccak256(
abi.encodePacked(hex"d694", address(this), hex"01")
)
)
)
);
address createdObj = address(uint160(uint256(keccak256(abi.encodePacked(hex"d694", address(this), hex"01")))));
_senderCreator = SenderCreator(createdObj);
}

function senderCreator()
internal
view
virtual
override
returns (SenderCreator)
{
function senderCreator() internal view virtual override returns (SenderCreator) {
// return the same senderCreator as real EntryPoint.
// this call is slightly (100) more expensive than EntryPoint's access to immutable member
return _senderCreator;
Expand All @@ -54,35 +39,23 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
}

/// @inheritdoc IEntryPointSimulations
function simulateValidation(
PackedUserOperation calldata userOp
) public returns (ValidationResult memory) {
function simulateValidation(PackedUserOperation calldata userOp) public returns (ValidationResult memory) {
UserOpInfo memory outOpInfo;

_simulationOnlyValidations(userOp);
(
uint256 validationData,
uint256 paymasterValidationData, // uint256 paymasterVerificationGasLimit

) = _validatePrepayment(0, userOp, outOpInfo);

_validateAccountAndPaymasterValidationData(
0,
validationData,
paymasterValidationData,
address(0)
);
_validateAccountAndPaymasterValidationData(0, validationData, paymasterValidationData, address(0));

StakeInfo memory paymasterInfo = _getStakeInfo(
outOpInfo.mUserOp.paymaster
);
StakeInfo memory paymasterInfo = _getStakeInfo(outOpInfo.mUserOp.paymaster);
StakeInfo memory senderInfo = _getStakeInfo(outOpInfo.mUserOp.sender);
StakeInfo memory factoryInfo;
{
bytes calldata initCode = userOp.initCode;
address factory = initCode.length >= 20
? address(bytes20(initCode[0:20]))
: address(0);
address factory = initCode.length >= 20 ? address(bytes20(initCode[0:20])) : address(0);
factoryInfo = _getStakeInfo(factory);
}

Expand All @@ -96,31 +69,17 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
);

AggregatorStakeInfo memory aggregatorInfo = NOT_AGGREGATED;
if (
uint160(aggregator) != SIG_VALIDATION_SUCCESS &&
uint160(aggregator) != SIG_VALIDATION_FAILED
) {
aggregatorInfo = AggregatorStakeInfo(
aggregator,
_getStakeInfo(aggregator)
);
if (uint160(aggregator) != SIG_VALIDATION_SUCCESS && uint160(aggregator) != SIG_VALIDATION_FAILED) {
aggregatorInfo = AggregatorStakeInfo(aggregator, _getStakeInfo(aggregator));
}
return
ValidationResult(
returnInfo,
senderInfo,
factoryInfo,
paymasterInfo,
aggregatorInfo
);
return ValidationResult(returnInfo, senderInfo, factoryInfo, paymasterInfo, aggregatorInfo);
}

function simulateValidationBulk(
PackedUserOperation[] calldata userOps
) public returns (ValidationResult[] memory) {
ValidationResult[] memory results = new ValidationResult[](
userOps.length
);
function simulateValidationBulk(PackedUserOperation[] calldata userOps)
public
returns (ValidationResult[] memory)
{
ValidationResult[] memory results = new ValidationResult[](userOps.length);

for (uint256 i = 0; i < userOps.length; i++) {
ValidationResult memory result = simulateValidation(userOps[i]);
Expand All @@ -131,19 +90,19 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
return results;
}

function simulateValidationLast(
PackedUserOperation[] calldata userOps
) external returns (ValidationResult memory) {
function simulateValidationLast(PackedUserOperation[] calldata userOps)
external
returns (ValidationResult memory)
{
ValidationResult[] memory results = simulateValidationBulk(userOps);

return results[userOps.length - 1];
}

function simulateCallData(
PackedUserOperation calldata op,
address target,
bytes calldata targetCallData
) public returns (TargetCallResult memory) {
function simulateCallData(PackedUserOperation calldata op, address target, bytes calldata targetCallData)
public
returns (TargetCallResult memory)
{
UserOpInfo memory opInfo;
_simulationOnlyValidations(op);
_validatePrepayment(0, op, opInfo);
Expand All @@ -167,11 +126,7 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
TargetCallResult[] memory results = new TargetCallResult[](ops.length);

for (uint256 i = 0; i < ops.length; i++) {
TargetCallResult memory result = simulateCallData(
ops[i],
targets[i],
targetCallData[i]
);
TargetCallResult memory result = simulateCallData(ops[i], targets[i], targetCallData[i]);

results[i] = result;
}
Expand All @@ -184,50 +139,37 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
address[] calldata targets,
bytes[] calldata targetCallData
) external returns (TargetCallResult memory) {
TargetCallResult[] memory results = simulateCallDataBulk(
ops,
targets,
targetCallData
);
TargetCallResult[] memory results = simulateCallDataBulk(ops, targets, targetCallData);

return results[ops.length - 1];
}

/// @inheritdoc IEntryPointSimulations
function simulateHandleOp(
PackedUserOperation calldata op
) public nonReentrant returns (ExecutionResult memory) {
function simulateHandleOp(PackedUserOperation calldata op) public nonReentrant returns (ExecutionResult memory) {
UserOpInfo memory opInfo;
_simulationOnlyValidations(op);
(
uint256 validationData,
uint256 paymasterValidationData,
uint256 paymasterVerificationGasLimit
) = _validatePrepayment(0, op, opInfo);
(uint256 validationData, uint256 paymasterValidationData, uint256 paymasterVerificationGasLimit) =
_validatePrepayment(0, op, opInfo);

(uint256 paid, uint256 paymasterPostOpGasLimit) = _executeUserOp(
op,
opInfo
);
(uint256 paid, uint256 paymasterPostOpGasLimit) = _executeUserOp(op, opInfo);

return
ExecutionResult(
opInfo.preOpGas,
paid,
validationData,
paymasterValidationData,
paymasterVerificationGasLimit,
paymasterPostOpGasLimit,
false,
"0x"
);
return ExecutionResult(
opInfo.preOpGas,
paid,
validationData,
paymasterValidationData,
paymasterVerificationGasLimit,
paymasterPostOpGasLimit,
false,
"0x"
);
}

function simulateHandleOpBulk(
PackedUserOperation[] calldata ops
) public returns (ExecutionResult[] memory) {
function simulateHandleOpBulk(PackedUserOperation[] calldata ops) public returns (ExecutionResult[] memory) {
ExecutionResult[] memory results = new ExecutionResult[](ops.length);

uint256 resultsIndex = 0;

for (uint256 i = 0; i < ops.length; i++) {
(bool success, bytes memory returnData) = address(this).call(
abi.encodeWithSignature(
Expand All @@ -237,11 +179,8 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
);

if (success) {
ExecutionResult memory execResult = abi.decode(
returnData,
(ExecutionResult)
);
results.push(execResult);
ExecutionResult memory execResult = abi.decode(returnData, (ExecutionResult));
results[resultsIndex++] = execResult;
}

// revert only at last as we are estimating only the last call
Expand All @@ -264,27 +203,20 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
return results;
}

function simulateHandleOpLast(
PackedUserOperation[] calldata ops
) external returns (ExecutionResult memory) {
function simulateHandleOpLast(PackedUserOperation[] calldata ops) external returns (ExecutionResult memory) {
ExecutionResult[] memory results = new ExecutionResult[](ops.length);

results = simulateHandleOpBulk(ops);

return results[ops.length - 1];
}

function _simulationOnlyValidations(
PackedUserOperation calldata userOp
) internal {
function _simulationOnlyValidations(PackedUserOperation calldata userOp) internal {
//initialize senderCreator(). we can't rely on constructor
initSenderCreator();

string memory revertReason = _validateSenderAndPaymaster(
userOp.initCode,
userOp.sender,
userOp.paymasterAndData
);
string memory revertReason =
_validateSenderAndPaymaster(userOp.initCode, userOp.sender, userOp.paymasterAndData);
// solhint-disable-next-line no-empty-blocks
if (bytes(revertReason).length != 0) {
revert FailedOp(0, revertReason);
Expand All @@ -298,11 +230,11 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
* @param sender - The sender address.
* @param paymasterAndData - The paymaster address (followed by other params, ignored by this method)
*/
function _validateSenderAndPaymaster(
bytes calldata initCode,
address sender,
bytes calldata paymasterAndData
) internal view returns (string memory) {
function _validateSenderAndPaymaster(bytes calldata initCode, address sender, bytes calldata paymasterAndData)
internal
view
returns (string memory)
{
if (initCode.length == 0 && sender.code.length == 0) {
// it would revert anyway. but give a meaningful message
return ("AA20 account not deployed");
Expand All @@ -321,9 +253,7 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations {
//make sure depositTo cost is more than normal EntryPoint's cost,
// to mitigate DoS vector on the bundler
// empiric test showed that without this wrapper, simulation depositTo costs less..
function depositTo(
address account
) public payable override(IStakeManager, StakeManager) {
function depositTo(address account) public payable override(IStakeManager, StakeManager) {
unchecked {
// silly code, to waste some gas to make sure depositTo is always little more
// expensive than on-chain call
Expand Down

0 comments on commit 801e5c3

Please sign in to comment.