From da7f9860e59fcf6075caa6d527114953aa371236 Mon Sep 17 00:00:00 2001 From: Alex Forshtat Date: Tue, 21 Jan 2025 16:25:17 +0100 Subject: [PATCH] Fix some issues with RIP-7560 --- .../bundler/src/modules/ExecutionManager.ts | 2 +- packages/bundler/src/modules/initServer.ts | 5 ++-- packages/bundler/test/BundlerManager.test.ts | 4 ++-- packages/bundler/test/BundlerServer.test.ts | 2 +- .../bundler/test/DebugMethodHandler.test.ts | 2 +- .../bundler/test/UserOpMethodHandler.test.ts | 2 +- packages/bundler/test/ValidateManager.test.ts | 2 +- .../src/AccountAbstractionEntity.ts | 1 + .../validation-manager/src/ERC7562Parser.ts | 24 ++++++++++++------- .../src/ValidationManagerRIP7560.ts | 1 + packages/validation-manager/src/index.ts | 2 +- 11 files changed, 28 insertions(+), 19 deletions(-) diff --git a/packages/bundler/src/modules/ExecutionManager.ts b/packages/bundler/src/modules/ExecutionManager.ts index d0bb0582..a10816fc 100644 --- a/packages/bundler/src/modules/ExecutionManager.ts +++ b/packages/bundler/src/modules/ExecutionManager.ts @@ -150,7 +150,7 @@ export class ExecutionManager { const { configuration, entryPoint, unsafe } = this.validationManager._getDebugConfiguration() const mergedConfiguration = Object.assign({}, configuration, configOverrides) const pvgc = new PreVerificationGasCalculator(mergedConfiguration) - const erc7562Parser = new ERC7562Parser(entryPoint.address, mergedConfiguration.senderCreator ?? '', true) + const erc7562Parser = new ERC7562Parser(entryPoint.address, mergedConfiguration.senderCreator ?? '') this.validationManager = new ValidationManager( entryPoint, unsafe, diff --git a/packages/bundler/src/modules/initServer.ts b/packages/bundler/src/modules/initServer.ts index b15761b1..00df8f64 100644 --- a/packages/bundler/src/modules/initServer.ts +++ b/packages/bundler/src/modules/initServer.ts @@ -10,6 +10,7 @@ import { MempoolManager } from './MempoolManager' import { BundleManager } from './BundleManager' import { AA_ENTRY_POINT, + AA_NONCE_MANAGER, AA_SENDER_CREATOR, AA_STAKE_MANAGER, IValidationManager, @@ -42,13 +43,13 @@ export function initServer (config: BundlerConfig, signer: Signer): [ExecutionMa let validationManager: IValidationManager let bundleManager: IBundleManager if (!config.rip7560) { - const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true) + const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator) const tracerProvider = config.tracerRpcUrl == null ? undefined : getNetworkProvider(config.tracerRpcUrl) validationManager = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser, tracerProvider) bundleManager = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, signer, eventsManager, mempoolManager, validationManager, reputationManager, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, config.conditionalRpc) } else { - const erc7562Parser = new ERC7562Parser(AA_ENTRY_POINT, AA_SENDER_CREATOR, true) + const erc7562Parser = new ERC7562Parser(AA_ENTRY_POINT, AA_SENDER_CREATOR, AA_NONCE_MANAGER) const stakeManager = IRip7560StakeManager__factory.connect(AA_STAKE_MANAGER, signer) validationManager = new ValidationManagerRIP7560(stakeManager, entryPoint.provider as JsonRpcProvider, erc7562Parser, config.unsafe) bundleManager = new BundleManagerRIP7560(entryPoint.provider as JsonRpcProvider, signer, eventsManager, mempoolManager, validationManager, reputationManager, diff --git a/packages/bundler/test/BundlerManager.test.ts b/packages/bundler/test/BundlerManager.test.ts index 415f3140..9827b7df 100644 --- a/packages/bundler/test/BundlerManager.test.ts +++ b/packages/bundler/test/BundlerManager.test.ts @@ -65,7 +65,7 @@ describe('#BundlerManager', () => { const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay) const mempoolMgr = new MempoolManager(repMgr) const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig) - const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true) + const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator) const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser) const evMgr = new EventsManager(entryPoint, mempoolMgr, repMgr) bm = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, entryPoint.signer, evMgr, mempoolMgr, validMgr, repMgr, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, config.conditionalRpc) @@ -123,7 +123,7 @@ describe('#BundlerManager', () => { const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay) const mempoolMgr = new MempoolManager(repMgr) const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig) - const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true) + const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator) const validMgr = new ValidationManager(_entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser) const evMgr = new EventsManager(_entryPoint, mempoolMgr, repMgr) bundleMgr = new BundleManager(_entryPoint, _entryPoint.provider as JsonRpcProvider, _entryPoint.signer, evMgr, mempoolMgr, validMgr, repMgr, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, false) diff --git a/packages/bundler/test/BundlerServer.test.ts b/packages/bundler/test/BundlerServer.test.ts index b0ce30d8..cb7e30b4 100644 --- a/packages/bundler/test/BundlerServer.test.ts +++ b/packages/bundler/test/BundlerServer.test.ts @@ -61,7 +61,7 @@ describe('BundleServer', function () { const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay) const mempoolMgr = new MempoolManager(repMgr) const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig) - const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true) + const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator) const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser) const evMgr = new EventsManager(entryPoint, mempoolMgr, repMgr) const bundleMgr = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, entryPoint.signer, evMgr, mempoolMgr, validMgr, repMgr, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, false) diff --git a/packages/bundler/test/DebugMethodHandler.test.ts b/packages/bundler/test/DebugMethodHandler.test.ts index 463b36d1..761d0277 100644 --- a/packages/bundler/test/DebugMethodHandler.test.ts +++ b/packages/bundler/test/DebugMethodHandler.test.ts @@ -71,7 +71,7 @@ describe('#DebugMethodHandler', () => { const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay) const mempoolMgr = new MempoolManager(repMgr) const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig) - const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true) + const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator) const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser) const eventsManager = new EventsManager(entryPoint, mempoolMgr, repMgr) const bundleMgr = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, entryPoint.signer, eventsManager, mempoolMgr, validMgr, repMgr, diff --git a/packages/bundler/test/UserOpMethodHandler.test.ts b/packages/bundler/test/UserOpMethodHandler.test.ts index a2509e82..c47dbe96 100644 --- a/packages/bundler/test/UserOpMethodHandler.test.ts +++ b/packages/bundler/test/UserOpMethodHandler.test.ts @@ -89,7 +89,7 @@ describe('UserOpMethodHandler', function () { const repMgr = new ReputationManager(provider, BundlerReputationParams, parseEther(config.minStake), config.minUnstakeDelay) mempoolMgr = new MempoolManager(repMgr) const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig) - const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true) + const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator) const validMgr = new ValidationManager(entryPoint, config.unsafe, preVerificationGasCalculator, erc7562Parser) const evMgr = new EventsManager(entryPoint, mempoolMgr, repMgr) const bundleMgr = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, entryPoint.signer, evMgr, mempoolMgr, validMgr, repMgr, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, false) diff --git a/packages/bundler/test/ValidateManager.test.ts b/packages/bundler/test/ValidateManager.test.ts index a737334b..c582b104 100644 --- a/packages/bundler/test/ValidateManager.test.ts +++ b/packages/bundler/test/ValidateManager.test.ts @@ -157,7 +157,7 @@ describe('#ValidationManager', () => { const preVerificationGasCalculator = new PreVerificationGasCalculator(MainnetConfig) const senderCreator = '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c' - const erc7562Parser = new ERC7562Parser(entryPoint.address, senderCreator, true) + const erc7562Parser = new ERC7562Parser(entryPoint.address, senderCreator) vm = new ValidationManager(entryPoint, unsafe, preVerificationGasCalculator, erc7562Parser) if (!await supportsDebugTraceCall(ethers.provider, false)) { diff --git a/packages/validation-manager/src/AccountAbstractionEntity.ts b/packages/validation-manager/src/AccountAbstractionEntity.ts index d50d2b1e..9f705600 100644 --- a/packages/validation-manager/src/AccountAbstractionEntity.ts +++ b/packages/validation-manager/src/AccountAbstractionEntity.ts @@ -6,5 +6,6 @@ export enum AccountAbstractionEntity { senderCreator = 'SenderCreator', entryPoint = 'EntryPoint', nativeEntryPoint = 'NativeEntryPoint', + nativeNonceManager = 'NativeNonceManager', none = 'none' } diff --git a/packages/validation-manager/src/ERC7562Parser.ts b/packages/validation-manager/src/ERC7562Parser.ts index c801be30..f3b2e893 100644 --- a/packages/validation-manager/src/ERC7562Parser.ts +++ b/packages/validation-manager/src/ERC7562Parser.ts @@ -255,10 +255,12 @@ export class ERC7562Parser { private contractAddresses: string[] = [] private storageMap: StorageMap = {} + private bailOnViolation: boolean = false + constructor ( readonly entryPointAddress: string, readonly senderCreatorAddress: string, - readonly bailOnViolation: boolean + readonly nonceManagerAddress?: string, ) {} private _init (erc7562Call: ERC7562Call): void { @@ -364,6 +366,9 @@ export class ERC7562Parser { } else if (this.senderCreatorAddress.toLowerCase() === call.to.toLowerCase()) { this.currentEntity = AccountAbstractionEntity.senderCreator this.currentEntityAddress = this.senderCreatorAddress + } else if (this.nonceManagerAddress?.toLowerCase() === call.to.toLowerCase()) { + this.currentEntity = AccountAbstractionEntity.nativeNonceManager + this.currentEntityAddress = this.nonceManagerAddress! } else { throw new RpcError(`could not find entity name for address ${call.to}. This should not happen. This is a bug.`, 0) } @@ -394,8 +399,8 @@ export class ERC7562Parser { private _parseEntitySlots ( userOp: OperationBase ): { - [addr: string]: Set - } { + [addr: string]: Set + } { // for each entity (sender, factory, paymaster), hold the valid slot addresses const entityAddresses = [userOp.sender.toLowerCase(), userOp.paymaster?.toLowerCase(), userOp.factory?.toLowerCase()] const entitySlots: { [addr: string]: Set } = {} @@ -426,11 +431,9 @@ export class ERC7562Parser { tracerResults: ERC7562Call, validationResult: ValidationResult ): ERC7562ValidationResults { + this.bailOnViolation = true const results = this.parseResults(userOp, tracerResults, validationResult) - if (results.ruleViolations.length > 0) { - // TODO: human-readable description of which rules were violated. - throw new Error('Rules Violated') - } + this.bailOnViolation = false return results } @@ -713,8 +716,11 @@ export class ERC7562Parser { userOp: OperationBase, tracerResults: ERC7562Call ): void { - if (tracerResults.to.toLowerCase() === this.entryPointAddress.toLowerCase()) { - // Currently inside the EntryPoint deposit code, no access control applies here + if ( + tracerResults.to.toLowerCase() === this.entryPointAddress.toLowerCase() || + tracerResults.to.toLowerCase() === this.nonceManagerAddress?.toLowerCase() + ) { + // Currently inside system code, no access control applies here return } const allSlots: string[] = [ diff --git a/packages/validation-manager/src/ValidationManagerRIP7560.ts b/packages/validation-manager/src/ValidationManagerRIP7560.ts index 4e6015a6..825fe59a 100644 --- a/packages/validation-manager/src/ValidationManagerRIP7560.ts +++ b/packages/validation-manager/src/ValidationManagerRIP7560.ts @@ -20,6 +20,7 @@ import { ERC7562Parser } from './ERC7562Parser' export const AA_ENTRY_POINT = '0x0000000000000000000000000000000000007560' export const AA_SENDER_CREATOR = '0x00000000000000000000000000000000ffff7560' export const AA_STAKE_MANAGER = '0x570Aa568b6cf62ff08c6C3a3b3DB1a0438E871Fb' +export const AA_NONCE_MANAGER = '0x632fafb21910d6c8b4a3995063dd984f2b829c02' export class ValidationManagerRIP7560 implements IValidationManager { constructor ( diff --git a/packages/validation-manager/src/index.ts b/packages/validation-manager/src/index.ts index 4a916422..bea25cee 100644 --- a/packages/validation-manager/src/index.ts +++ b/packages/validation-manager/src/index.ts @@ -58,7 +58,7 @@ export async function checkRulesViolations ( } const entryPoint = IEntryPoint__factory.connect(entryPointAddress, provider) const senderCreator = '0xefc2c1444ebcc4db75e7613d20c6a62ff67a167c' - const erc7562Parser = new ERC7562Parser(entryPointAddress, senderCreator, true) + const erc7562Parser = new ERC7562Parser(entryPointAddress, senderCreator) const validationManager = new ValidationManager( entryPoint, false,