Skip to content

Commit

Permalink
WIP: Add support for RIP-7560 transaction type
Browse files Browse the repository at this point in the history
  • Loading branch information
forshtat committed Jan 21, 2025
1 parent 5f2c358 commit 646c686
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 38 deletions.
7 changes: 5 additions & 2 deletions packages/bundler/src/modules/initServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { BundlerReputationParams, ReputationManager } from './ReputationManager'
import { MempoolManager } from './MempoolManager'
import { BundleManager } from './BundleManager'
import {
AA_ENTRY_POINT,
AA_STAKE_MANAGER,
IValidationManager,
ValidationManager,
ValidationManagerRIP7560,
IValidationManager, AA_STAKE_MANAGER
} from '@account-abstraction/validation-manager'
import { BundlerConfig } from '../BundlerConfig'
import { EventsManager } from './EventsManager'
Expand All @@ -36,15 +38,16 @@ export function initServer (config: BundlerConfig, signer: Signer): [ExecutionMa
const eventsManager = new EventsManager(entryPoint, mempoolManager, reputationManager)
const mergedPvgcConfig = Object.assign({}, ChainConfigs[config.chainId] ?? {}, config)
const preVerificationGasCalculator = new PreVerificationGasCalculator(mergedPvgcConfig)
const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true)
let validationManager: IValidationManager
let bundleManager: IBundleManager
if (!config.rip7560) {
const erc7562Parser = new ERC7562Parser(entryPoint.address, config.senderCreator, true)
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, config.senderCreator, true)
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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export enum AccountAbstractionEntity {
aggregator = 'aggregator',
senderCreator = 'SenderCreator',
entryPoint = 'EntryPoint',
nativeEntryPoint = 'NativeEntryPoint',
none = 'none'
}
233 changes: 230 additions & 3 deletions packages/validation-manager/src/ERC7562Parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,222 @@ import { ValidationResult } from './IValidationManager'
import { ERC7562Call } from './ERC7562Call'
import { getOpcodeName } from './enum/EVMOpcodes'

// TODO: Use artifact from the submodule
const RIP7560EntryPointABI = [
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'sender',
type: 'address'
},
{
indexed: true,
internalType: 'address',
name: 'paymaster',
type: 'address'
},
{
indexed: true,
internalType: 'address',
name: 'deployer',
type: 'address'
}
],
name: 'RIP7560AccountDeployed',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'sender',
type: 'address'
},
{
indexed: true,
internalType: 'address',
name: 'paymaster',
type: 'address'
},
{
indexed: false,
internalType: 'uint256',
name: 'nonceKey',
type: 'uint256'
},
{
indexed: false,
internalType: 'uint256',
name: 'nonceSequence',
type: 'uint256'
},
{
indexed: false,
internalType: 'uint256',
name: 'executionStatus',
type: 'uint256'
}
],
name: 'RIP7560TransactionEvent',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'sender',
type: 'address'
},
{
indexed: true,
internalType: 'address',
name: 'paymaster',
type: 'address'
},
{
indexed: false,
internalType: 'uint256',
name: 'nonceKey',
type: 'uint256'
},
{
indexed: false,
internalType: 'uint256',
name: 'nonceSequence',
type: 'uint256'
},
{
indexed: false,
internalType: 'bytes',
name: 'revertReason',
type: 'bytes'
}
],
name: 'RIP7560TransactionPostOpRevertReason',
type: 'event'
},
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: 'address',
name: 'sender',
type: 'address'
},
{
indexed: false,
internalType: 'uint256',
name: 'nonceKey',
type: 'uint256'
},
{
indexed: false,
internalType: 'uint256',
name: 'nonceSequence',
type: 'uint256'
},
{
indexed: false,
internalType: 'bytes',
name: 'revertReason',
type: 'bytes'
}
],
name: 'RIP7560TransactionRevertReason',
type: 'event'
},
{
inputs: [
{
internalType: 'uint256',
name: 'validAfter',
type: 'uint256'
},
{
internalType: 'uint256',
name: 'validUntil',
type: 'uint256'
}
],
name: 'acceptAccount',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [
{
internalType: 'uint256',
name: 'validAfter',
type: 'uint256'
},
{
internalType: 'uint256',
name: 'validUntil',
type: 'uint256'
},
{
internalType: 'bytes',
name: 'context',
type: 'bytes'
}
],
name: 'acceptPaymaster',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [
{
internalType: 'uint256',
name: 'validAfter',
type: 'uint256'
},
{
internalType: 'uint256',
name: 'validUntil',
type: 'uint256'
}
],
name: 'sigFailAccount',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [
{
internalType: 'uint256',
name: 'validAfter',
type: 'uint256'
},
{
internalType: 'uint256',
name: 'validUntil',
type: 'uint256'
},
{
internalType: 'bytes',
name: 'context',
type: 'bytes'
}
],
name: 'sigFailPaymaster',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
}
]

export interface ERC7562ValidationResults {
storageMap: StorageMap
ruleViolations: ERC7562Violation[]
Expand All @@ -45,7 +261,7 @@ export class ERC7562Parser {
readonly bailOnViolation: boolean
) {}

private _init (erc7562Call: ERC7562Call) {
private _init (erc7562Call: ERC7562Call): void {
this.keccak = erc7562Call.keccak ?? []
this.ruleViolations = []
this.currentEntity = AccountAbstractionEntity.none
Expand Down Expand Up @@ -102,6 +318,7 @@ export class ERC7562Parser {

private _tryDetectKnownMethod (call: ERC7562Call): string {
const mergedAbi = Object.values([
...RIP7560EntryPointABI,
...SenderCreator__factory.abi,
...IEntryPoint__factory.abi,
...IPaymaster__factory.abi
Expand Down Expand Up @@ -366,7 +583,11 @@ export class ERC7562Parser {
let illegalZeroCodeAccess: any
for (const addr of Object.keys(tracerResults.contractSize)) {
// [OP-042]
if (addr.toLowerCase() !== userOp.sender.toLowerCase() && addr.toLowerCase() !== this.entryPointAddress.toLowerCase() && tracerResults.contractSize[addr].contractSize <= 2) {
if (
addr.toLowerCase() !== userOp.sender.toLowerCase() &&
// addr.toLowerCase() !== AA_ENTRY_POINT &&
addr.toLowerCase() !== this.entryPointAddress.toLowerCase() &&
tracerResults.contractSize[addr].contractSize <= 2) {
illegalZeroCodeAccess = tracerResults.contractSize[addr]
illegalZeroCodeAccess.address = addr
this._violationDetected({
Expand All @@ -389,9 +610,15 @@ export class ERC7562Parser {
checkOp054 (erc7562Call: ERC7562Call): void {
const isCallToEntryPoint = this._isCallToEntryPoint(erc7562Call)
const knownMethod = this._tryDetectKnownMethod(erc7562Call)
const isEntryPointCallAllowedRIP7560 = knownMethod === 'acceptAccount' ||
knownMethod === 'acceptPaymaster' ||
knownMethod === 'sigFailAccount' ||
knownMethod === 'sigFailPaymaster'
const isEntryPointCallAllowedOP052 = knownMethod === 'depositTo'
const isEntryPointCallAllowedOP053 = knownMethod === '0x'
const isEntryPointCallAllowed = isEntryPointCallAllowedOP052 || isEntryPointCallAllowedOP053
const isEntryPointCallAllowed = isEntryPointCallAllowedOP052 ||
isEntryPointCallAllowedOP053 ||
isEntryPointCallAllowedRIP7560
const isRuleViolated = isCallToEntryPoint && !isEntryPointCallAllowed
if (isRuleViolated) {
this._violationDetected({
Expand Down
37 changes: 4 additions & 33 deletions packages/validation-manager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { JsonRpcProvider } from '@ethersproject/providers'
import {
AddressZero,
IEntryPoint__factory,
OperationRIP7560,
UserOperation
} from '@account-abstraction/utils'
import { PreVerificationGasCalculator } from '@account-abstraction/sdk'

import { bundlerJSTracerName, debug_traceCall, eth_traceRip7560Validation } from './GethTracer'
import { bundlerJSTracerName, debug_traceCall } from './GethTracer'
// @ts-ignore
import { bundlerCollectorTracer } from './BundlerCollectorTracer'
import { ValidateUserOpResult } from './IValidationManager'
import { ValidationManager } from './ValidationManager'
Expand Down Expand Up @@ -37,37 +37,8 @@ export async function supportsDebugTraceCall (provider: JsonRpcProvider, rip7560
}

if (rip7560) {
// TODO: remove
const defaultsForRip7560Tx: OperationRIP7560 = {
accessList: [],
builderFee: '0x0',
chainId: '0x539',
value: '0x0',
sender: AddressZero,
nonceKey: '0x0',
nonce: '0x0',
executionData: '0x',
callGasLimit: '0x0',
verificationGasLimit: '0x10000',
maxFeePerGas: '0x100000000',
maxPriorityFeePerGas: '0x100000000',
paymaster: AddressZero,
paymasterData: '0x',
factory: AddressZero,
factoryData: '0x',
paymasterVerificationGasLimit: '0x10000',
paymasterPostOpGasLimit: '0x0',
authorizationData: '0x',
authorizationList: []
};

// TODO: align parameter names across 4337 and 7560
(defaultsForRip7560Tx as any).deployer = defaultsForRip7560Tx.factory;
(defaultsForRip7560Tx as any).deployerData = defaultsForRip7560Tx.factoryData
// make sure we can trace a call.
const ret = await eth_traceRip7560Validation(provider, defaultsForRip7560Tx
).catch(e => e)
return ret.traceResults != null
// no need to check for the internal RIP-7560 support
return true
}
// make sure we can trace a call.
const ret = await debug_traceCall(provider,
Expand Down

0 comments on commit 646c686

Please sign in to comment.