From d2c39133a93468384c503cef74c5da1f18504921 Mon Sep 17 00:00:00 2001 From: Dror Tirosh Date: Thu, 26 Dec 2024 17:56:39 +0200 Subject: [PATCH] AA-499 fix EntryPointSimulations config EntryPointSimulations should be compiled with the same compiler settings as EntryPoint --- contracts/core/EntryPoint.sol | 10 ++++++-- contracts/core/EntryPointSimulations.sol | 10 +++++--- hardhat.config.ts | 7 +++--- package.json | 2 +- reports/gas-checker.txt | 32 ++++++++++++------------ test/entrypointsimulations.test.ts | 3 ++- 6 files changed, 38 insertions(+), 26 deletions(-) diff --git a/contracts/core/EntryPoint.sol b/contracts/core/EntryPoint.sol index 7d76303c..b8a3aa9e 100644 --- a/contracts/core/EntryPoint.sol +++ b/contracts/core/EntryPoint.sol @@ -546,7 +546,7 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard, } catch { revert FailedOpWithRevert(opIndex, "AA33 reverted", Exec.getReturnData(REVERT_REASON_MAX_LEN)); } - if (preGas - gasleft() > pmVerificationGasLimit) { + if (preGas - gasleft() > _getVerificationGasLimit(pmVerificationGasLimit)) { revert FailedOp(opIndex, "AA36 over paymasterVerificationGasLimit"); } } @@ -652,7 +652,7 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard, } unchecked { - if (preGas - gasleft() > verificationGasLimit) { + if (preGas - gasleft() > _getVerificationGasLimit(verificationGasLimit)) { revert FailedOp(opIndex, "AA26 over verificationGasLimit"); } } @@ -673,6 +673,12 @@ contract EntryPoint is IEntryPoint, StakeManager, NonceManager, ReentrancyGuard, } } + // return verification gas limit. + // This method is overridden in EntryPointSimulations, for slightly stricter gas limits. + function _getVerificationGasLimit(uint256 verificationGasLimit) internal pure virtual returns (uint256) { + return verificationGasLimit; + } + /** * Process post-operation, called just after the callData is executed. * If a paymaster is defined and its validation returned a non-empty context, its postOp is called. diff --git a/contracts/core/EntryPointSimulations.sol b/contracts/core/EntryPointSimulations.sol index e0ddcaef..a5debe8a 100644 --- a/contracts/core/EntryPointSimulations.sol +++ b/contracts/core/EntryPointSimulations.sol @@ -13,8 +13,6 @@ import "../interfaces/IEntryPointSimulations.sol"; * This contract should never be deployed on-chain and is only used as a parameter for the "eth_call" request. */ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations { - // solhint-disable-next-line var-name-mixedcase - AggregatorStakeInfo private NOT_AGGREGATED = AggregatorStakeInfo(address(0), StakeInfo(0, 0)); SenderCreator private _senderCreator; @@ -75,7 +73,7 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations { getMemoryBytesFromOffset(outOpInfo.contextOffset) ); - AggregatorStakeInfo memory aggregatorInfo = NOT_AGGREGATED; + AggregatorStakeInfo memory aggregatorInfo; // = NOT_AGGREGATED; if (uint160(aggregator) != SIG_VALIDATION_SUCCESS && uint160(aggregator) != SIG_VALIDATION_FAILED) { aggregatorInfo = AggregatorStakeInfo( aggregator, @@ -187,4 +185,10 @@ contract EntryPointSimulations is EntryPoint, IEntryPointSimulations { StakeManager.depositTo(account); } } + + //slightly stricter gas limit than the real EntryPoint + function _getVerificationGasLimit(uint256 verificationGasLimit) internal pure virtual override returns (uint256) { + return verificationGasLimit - 300; + } + } diff --git a/hardhat.config.ts b/hardhat.config.ts index 4c499c2e..07aa9562 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -30,7 +30,7 @@ function getNetwork (name: string): { url: string, accounts: { mnemonic: string // return getNetwork1(`wss://${name}.infura.io/ws/v3/${process.env.INFURA_ID}`) } -const optimizedComilerSettings = { +const optimizedCompilerSettings = { version: '0.8.23', settings: { optimizer: { enabled: true, runs: 1000000 }, @@ -50,8 +50,9 @@ const config: HardhatUserConfig = { } }], overrides: { - 'contracts/core/EntryPoint.sol': optimizedComilerSettings, - 'contracts/samples/SimpleAccount.sol': optimizedComilerSettings + 'contracts/core/EntryPoint.sol': optimizedCompilerSettings, + 'contracts/core/EntryPointSimulations.sol': optimizedCompilerSettings, + 'contracts/samples/SimpleAccount.sol': optimizedCompilerSettings } }, networks: { diff --git a/package.json b/package.json index 21f3550b..028fd5d8 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "lint:js": "eslint -f unix .", "lint-fix": "eslint -f unix . --fix", "lint:sol": "solhint -f unix \"contracts/**/*.sol\" --max-warnings 0", - "gas-calc": "./scripts/gascalc", + "gas-calc": "yarn compile && ./scripts/gascalc", "mocha-gascalc": "TS_NODE_TRANSPILE_ONLY=1 npx ts-mocha --bail gascalc/*", "test": "./scripts/hh-wrapper test", "coverage": "COVERAGE=1 hardhat coverage", diff --git a/reports/gas-checker.txt b/reports/gas-checker.txt index 6d67773e..d5c67407 100644 --- a/reports/gas-checker.txt +++ b/reports/gas-checker.txt @@ -12,44 +12,44 @@ ║ │ │ │ (delta for │ (compared to ║ ║ │ │ │ one UserOp) │ account.exec()) ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ simple │ 1 │ 80004 │ │ ║ +║ simple │ 1 │ 79968 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ ║ simple - diff from previous │ 2 │ │ 42168 │ 12841 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ simple │ 10 │ 459895 │ │ ║ +║ simple │ 10 │ 459883 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ simple - diff from previous │ 11 │ │ 42235 │ 12908 ║ +║ simple - diff from previous │ 11 │ │ 42271 │ 12944 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ simple paymaster │ 1 │ 86147 │ │ ║ +║ simple paymaster │ 1 │ 86135 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ simple paymaster with diff │ 2 │ │ 41048 │ 11721 ║ +║ simple paymaster with diff │ 2 │ │ 41036 │ 11709 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ simple paymaster │ 10 │ 455682 │ │ ║ +║ simple paymaster │ 10 │ 455634 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ simple paymaster with diff │ 11 │ │ 41148 │ 11821 ║ +║ simple paymaster with diff │ 11 │ │ 41136 │ 11809 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ big tx 5k │ 1 │ 181036 │ │ ║ +║ big tx 5k │ 1 │ 181048 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ big tx - diff from previous │ 2 │ │ 142702 │ 16604 ║ +║ big tx - diff from previous │ 2 │ │ 142678 │ 16580 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ big tx 5k │ 10 │ 1465441 │ │ ║ +║ big tx 5k │ 10 │ 1465429 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ big tx - diff from previous │ 11 │ │ 142722 │ 16624 ║ +║ big tx - diff from previous │ 11 │ │ 142746 │ 16648 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ ║ paymaster+postOp │ 1 │ 87758 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ ║ paymaster+postOp with diff │ 2 │ │ 42647 │ 13320 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ paymaster+postOp │ 10 │ 471848 │ │ ║ +║ paymaster+postOp │ 10 │ 471764 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ paymaster+postOp with diff │ 11 │ │ 42704 │ 13377 ║ +║ paymaster+postOp with diff │ 11 │ │ 42716 │ 13389 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ ║ token paymaster │ 1 │ 128809 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ token paymaster with diff │ 2 │ │ 66384 │ 37057 ║ +║ token paymaster with diff │ 2 │ │ 66396 │ 37069 ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ token paymaster │ 10 │ 726686 │ │ ║ +║ token paymaster │ 10 │ 726722 │ │ ║ ╟────────────────────────────────┼───────┼───────────────┼────────────────┼─────────────────────╢ -║ token paymaster with diff │ 11 │ │ 66536 │ 37209 ║ +║ token paymaster with diff │ 11 │ │ 66452 │ 37125 ║ ╚════════════════════════════════╧═══════╧═══════════════╧════════════════╧═════════════════════╝ diff --git a/test/entrypointsimulations.test.ts b/test/entrypointsimulations.test.ts index 723b8053..6e6fe548 100644 --- a/test/entrypointsimulations.test.ts +++ b/test/entrypointsimulations.test.ts @@ -64,6 +64,7 @@ describe('EntryPointSimulations', function () { function costInRange (simCost: BigNumber, epCost: BigNumber, message: string): void { const diff = simCost.sub(epCost).toNumber() const max = 350 + console.log(`validate ${message} cost ${simCost.toNumber()} should be slightly above ep cost ${epCost.toNumber()} actual diff=${diff}`) expect(diff).to.be.within(0, max, `${message} cost ${simCost.toNumber()} should be (up to ${max}) above ep cost ${epCost.toNumber()}`) } @@ -294,7 +295,7 @@ describe('EntryPointSimulations', function () { describe(`compare to execution ${withPaymaster} paymaster`, () => { let execVgl: number let execPmVgl: number - const diff = 2000 + const diff = 500 before(async () => { execPmVgl = withPaymaster === 'without' ? 0 : await findUserOpWithMin(async n => userOpWithGas(1e6, n), false, entryPoint, 1, 500000) execVgl = await findUserOpWithMin(async n => userOpWithGas(n, execPmVgl), false, entryPoint, 1, 500000)