From a7b1163a66bc082ba8b157b0e5b4ddbae7edd785 Mon Sep 17 00:00:00 2001 From: shahafn Date: Sun, 25 Aug 2024 15:30:21 +0300 Subject: [PATCH] Adding stake manager --- .idea/vcs.xml | 2 + packages/bundler/src/modules/initServer.ts | 7 +-- packages/bundler/src/runBundler.ts | 2 + packages/utils/contracts/Imports.sol | 2 + .../utils/src/RIP7712NonceManagerUtils.ts | 3 +- packages/utils/src/deployStakeManager.ts | 17 +++++++ .../src/ValidationManagerRIP7560.ts | 48 +++++++++++++++++-- submodules/rip7560 | 2 +- 8 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 packages/utils/src/deployStakeManager.ts diff --git a/.idea/vcs.xml b/.idea/vcs.xml index b6a97370..ad14a99d 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -3,5 +3,7 @@ + + \ No newline at end of file diff --git a/packages/bundler/src/modules/initServer.ts b/packages/bundler/src/modules/initServer.ts index 20328e73..e5564766 100644 --- a/packages/bundler/src/modules/initServer.ts +++ b/packages/bundler/src/modules/initServer.ts @@ -2,7 +2,7 @@ import { JsonRpcProvider } from '@ethersproject/providers' import { Signer } from 'ethers' import { parseEther } from 'ethers/lib/utils' -import { IEntryPoint__factory } from '@account-abstraction/utils' +import { IEntryPoint__factory, IStakeManager__factory } from '@account-abstraction/utils' import { ExecutionManager } from './ExecutionManager' import { BundlerReputationParams, ReputationManager } from './ReputationManager' @@ -11,7 +11,7 @@ import { BundleManager } from './BundleManager' import { ValidationManager, ValidationManagerRIP7560, - IValidationManager + IValidationManager, AA_STAKE_MANAGER } from '@account-abstraction/validation-manager' import { BundlerConfig } from '../BundlerConfig' import { EventsManager } from './EventsManager' @@ -38,7 +38,8 @@ export function initServer (config: BundlerConfig, signer: Signer): [ExecutionMa bundleManager = new BundleManager(entryPoint, entryPoint.provider as JsonRpcProvider, signer, eventsManager, mempoolManager, validationManager, reputationManager, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, config.conditionalRpc) } else { - validationManager = new ValidationManagerRIP7560(entryPoint.provider as JsonRpcProvider, config.unsafe) + const stakeManager = IStakeManager__factory.connect(AA_STAKE_MANAGER, signer) + validationManager = new ValidationManagerRIP7560(stakeManager, entryPoint.provider as JsonRpcProvider, config.unsafe) bundleManager = new BundleManagerRIP7560(entryPoint.provider as JsonRpcProvider, signer, eventsManager, mempoolManager, validationManager, reputationManager, config.beneficiary, parseEther(config.minBalance), config.maxBundleGas, config.conditionalRpc, false) } diff --git a/packages/bundler/src/runBundler.ts b/packages/bundler/src/runBundler.ts index 401c23e0..c8ca6445 100644 --- a/packages/bundler/src/runBundler.ts +++ b/packages/bundler/src/runBundler.ts @@ -22,6 +22,7 @@ import { parseEther } from 'ethers/lib/utils' import { MethodHandlerRIP7560 } from './MethodHandlerRIP7560' import { JsonRpcProvider } from '@ethersproject/providers' import { deployNonceManager } from '@account-abstraction/utils/dist/src/RIP7712NonceManagerUtils' +import { deployStakeManager } from '@account-abstraction/utils/dist/src/deployStakeManager' // this is done so that console.log outputs BigNumber as hex string instead of unreadable object export const inspectCustomSymbol = Symbol.for('nodejs.util.inspect.custom') @@ -137,6 +138,7 @@ export async function runBundler (argv: string[], overrideExit = true): Promise< if (config.rip7560) { await deployNonceManager(provider, wallet as any) + await deployStakeManager(provider, wallet as any) } const { diff --git a/packages/utils/contracts/Imports.sol b/packages/utils/contracts/Imports.sol index f932a199..677612b6 100644 --- a/packages/utils/contracts/Imports.sol +++ b/packages/utils/contracts/Imports.sol @@ -7,3 +7,5 @@ import "@account-abstraction/contracts/samples/SimpleAccountFactory.sol"; import "@account-abstraction/contracts/samples/TokenPaymaster.sol"; import {NonceManager as NonceManagerRIP7712} from "@account-abstraction/rip7560/contracts/predeploys/NonceManager.sol"; +import {StakeManager as StakeManagerRIP7560} from "@account-abstraction/rip7560/contracts/predeploys/StakeManager.sol"; +import {IStakeManager as IStakeManagerRIP7560} from "@account-abstraction/rip7560/contracts/interfaces/IStakeManager.sol"; diff --git a/packages/utils/src/RIP7712NonceManagerUtils.ts b/packages/utils/src/RIP7712NonceManagerUtils.ts index 71fbbead..b5d740be 100644 --- a/packages/utils/src/RIP7712NonceManagerUtils.ts +++ b/packages/utils/src/RIP7712NonceManagerUtils.ts @@ -3,10 +3,11 @@ import { JsonRpcProvider } from '@ethersproject/providers' import { bytecode as nonceManagerByteCode } from '../artifacts/@account-abstraction/rip7560/contracts/predeploys/NonceManager.sol/NonceManager.json' import { DeterministicDeployer } from './DeterministicDeployer' import { NonceManager__factory } from './types/factories/@account-abstraction/rip7560/contracts/predeploys' +import { NonceManager } from './types/@account-abstraction/rip7560/contracts/predeploys' export const entryPointSalt = '0x90d8084deab30c2a37c45e8d47f49f2f7965183cb6990a98943ef94940681de3' -export async function deployNonceManager (provider: JsonRpcProvider, signer = provider.getSigner()): Promise { +export async function deployNonceManager (provider: JsonRpcProvider, signer = provider.getSigner()): Promise { const addr = await new DeterministicDeployer(provider, signer).deterministicDeploy(nonceManagerByteCode, entryPointSalt) return NonceManager__factory.connect(addr, signer) } diff --git a/packages/utils/src/deployStakeManager.ts b/packages/utils/src/deployStakeManager.ts new file mode 100644 index 00000000..82ddeb75 --- /dev/null +++ b/packages/utils/src/deployStakeManager.ts @@ -0,0 +1,17 @@ +import { JsonRpcProvider } from '@ethersproject/providers' + +import { bytecode as stakeManagerByteCode } from '../artifacts/@account-abstraction/rip7560/contracts/predeploys/StakeManager.sol/StakeManager.json' +import { DeterministicDeployer } from './DeterministicDeployer' +import { StakeManager__factory } from './types/factories/@account-abstraction/rip7560/contracts/predeploys' +import { StakeManager } from './types/@account-abstraction/rip7560/contracts/predeploys' + +export const stakeManagerSalt = '0x90d8084deab30c2a37c45e8d47f49f2f7965183cb6990a98943ef94940681de3' + +export async function deployStakeManager (provider: JsonRpcProvider, signer = provider.getSigner()): Promise { + const addr = await new DeterministicDeployer(provider, signer).deterministicDeploy(stakeManagerByteCode, stakeManagerSalt) + return StakeManager__factory.connect(addr, signer) +} + +export function getStakeManagerAddress (): string { + return DeterministicDeployer.getAddress(stakeManagerByteCode, stakeManagerSalt) +} diff --git a/packages/validation-manager/src/ValidationManagerRIP7560.ts b/packages/validation-manager/src/ValidationManagerRIP7560.ts index dcf3c8a5..ecc19ce1 100644 --- a/packages/validation-manager/src/ValidationManagerRIP7560.ts +++ b/packages/validation-manager/src/ValidationManagerRIP7560.ts @@ -4,18 +4,21 @@ import { OperationBase, OperationRIP7560, ReferencedCodeHashes, - getRIP7560TransactionHash + getRIP7560TransactionHash, IStakeManager, StakeInfo } from '@account-abstraction/utils' import { IValidationManager, ValidateUserOpResult, ValidationResult } from './IValidationManager' import { eth_traceRip7560Validation } from './GethTracer' import { tracerResultParser } from './TracerResultParser' import debug from 'debug' +import { isAddress } from 'ethers/lib/utils' export const AA_ENTRY_POINT = '0x0000000000000000000000000000000000007560' +export const AA_STAKE_MANAGER = '0x5271A07b4516A6408E27395941b3D8FC04d96353' export class ValidationManagerRIP7560 implements IValidationManager { constructor ( + readonly stakeManager: IStakeManager, readonly provider: JsonRpcProvider, readonly unsafe: boolean ) { @@ -25,6 +28,43 @@ export class ValidationManagerRIP7560 implements IValidationManager { // TODO } + async _getStakesInfo (operation: OperationBase): Promise<{ senderInfo: StakeInfo, paymasterInfo: StakeInfo, factoryInfo: StakeInfo }> { + const senderTMI = await this.stakeManager.getDepositInfo(operation.sender) + const senderInfo = { + addr: operation.sender, + ...senderTMI + } + let paymasterInfo: StakeInfo = { + addr: '', + stake: 0, + unstakeDelaySec: 0 + } + if (operation.paymaster != null && isAddress(operation.paymaster)) { + const paymasterTMI = await this.stakeManager.getDepositInfo(operation.paymaster) + paymasterInfo = { + addr: operation.paymaster, + ...paymasterTMI + } + } + let factoryInfo: StakeInfo = { + addr: '', + stake: 0, + unstakeDelaySec: 0 + } + if (operation.factory != null && isAddress(operation.factory)) { + const factoryTMI = await this.stakeManager.getDepositInfo(operation.factory) + factoryInfo = { + addr: operation.factory, + ...factoryTMI + } + } + return { + factoryInfo, + paymasterInfo, + senderInfo + } + } + async validateUserOp (operation: OperationBase, previousCodeHashes?: ReferencedCodeHashes): Promise { const transaction = operation as OperationRIP7560 // let storageMap: StorageMap = {} @@ -36,12 +76,10 @@ export class ValidationManagerRIP7560 implements IValidationManager { const traceResult = await this.traceValidation(transaction).catch(e => { throw e }) - // TODO alex shahaf add staked entities support + const stakesInfo = await this._getStakesInfo(operation) const validationResult: ValidationResult = { returnInfo: { sigFailed: false, validAfter: 0, validUntil: 0 }, - factoryInfo: { stake: 0, addr: operation.factory ?? '', unstakeDelaySec: 0 }, - paymasterInfo: { stake: 0, addr: operation.paymaster ?? '', unstakeDelaySec: 0 }, - senderInfo: { stake: 0, addr: operation.sender, unstakeDelaySec: 0 } + ...stakesInfo } debug(`traceResult= ${JSON.stringify(traceResult)}`) // this.parseValidationTracingResult(traceResult) diff --git a/submodules/rip7560 b/submodules/rip7560 index 0ac9ff07..71bde73b 160000 --- a/submodules/rip7560 +++ b/submodules/rip7560 @@ -1 +1 @@ -Subproject commit 0ac9ff073aa9950aefc96bc23f23120f04dc56b5 +Subproject commit 71bde73b88197eb5463f1e988119de9d38a02f57