Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/master/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ export async function bootstrap() {

const rpcChainConfigs: RpcChainConfig[] = [];

for (const { chainId, rpcs } of chainsSettings) {
for (const { chainId, rpcs, isTestChain } of chainsSettings) {
const rpcChainConfig: RpcChainConfig =
rpcManagerService.prepareRpcChainConfig(chainId, rpcs);
rpcManagerService.prepareRpcChainConfig(chainId, rpcs, isTestChain);

rpcChainConfigs.push(rpcChainConfig);
}
Expand Down
127 changes: 127 additions & 0 deletions src/modules/contracts/resources/SmartSessionsAbi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
export const SmartSessionsAbi = [
{
type: "function",
name: "enableSessions",
inputs: [
{
name: "sessions",
type: "tuple[]",
internalType: "struct Session[]",
components: [
{
name: "sessionValidator",
type: "address",
internalType: "contract ISessionValidator",
},
{
name: "sessionValidatorInitData",
type: "bytes",
internalType: "bytes",
},
{ name: "salt", type: "bytes32", internalType: "bytes32" },
{
name: "userOpPolicies",
type: "tuple[]",
internalType: "struct PolicyData[]",
components: [
{
name: "policy",
type: "address",
internalType: "address",
},
{ name: "initData", type: "bytes", internalType: "bytes" },
],
},
{
name: "erc7739Policies",
type: "tuple",
internalType: "struct ERC7739Data",
components: [
{
name: "allowedERC7739Content",
type: "tuple[]",
internalType: "struct ERC7739Context[]",
components: [
{
name: "appDomainSeparator",
type: "bytes32",
internalType: "bytes32",
},
{
name: "contentName",
type: "string[]",
internalType: "string[]",
},
],
},
{
name: "erc1271Policies",
type: "tuple[]",
internalType: "struct PolicyData[]",
components: [
{
name: "policy",
type: "address",
internalType: "address",
},
{
name: "initData",
type: "bytes",
internalType: "bytes",
},
],
},
],
},
{
name: "actions",
type: "tuple[]",
internalType: "struct ActionData[]",
components: [
{
name: "actionTargetSelector",
type: "bytes4",
internalType: "bytes4",
},
{
name: "actionTarget",
type: "address",
internalType: "address",
},
{
name: "actionPolicies",
type: "tuple[]",
internalType: "struct PolicyData[]",
components: [
{
name: "policy",
type: "address",
internalType: "address",
},
{
name: "initData",
type: "bytes",
internalType: "bytes",
},
],
},
],
},
{
name: "permitERC4337Paymaster",
type: "bool",
internalType: "bool",
},
],
},
],
outputs: [
{
name: "permissionIds",
type: "bytes32[]",
internalType: "PermissionId[]",
},
],
stateMutability: "nonpayable",
},
];
2 changes: 2 additions & 0 deletions src/modules/contracts/resources/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type Hex } from "viem";
import { SmartSessionsAbi } from "./SmartSessionsAbi";
import { arbitrumOracle } from "./arbitrum-oracle";
import { chainlinkAggregatorV3 } from "./chainlink-aggregator-v3";
import { entryPointV7 } from "./entry-point-v7";
Expand All @@ -10,6 +11,7 @@ export const ABI_MAP = {
entryPointV7,
meeEntryPointV7,
optimismOracle,
SmartSessionsAbi,
arbitrumOracle,
} as const;

Expand Down
8 changes: 5 additions & 3 deletions src/modules/rpc-manager/rpc-manager.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { ProviderMetrics } from "./provider-metrics";
export class RpcManagerService {
private configs: Map<string, RpcChainConfig> = new Map();
private healthCheckIntervals: Map<string, NodeJS.Timeout> = new Map();
private minimumRequestsForPromotion = 50;
private minimumRequestsForPromotion = 10;
private initialized = false;
private promotionInProgress: Map<string, boolean> = new Map();
private healthCheckInProgress: Map<string, boolean> = new Map();
Expand Down Expand Up @@ -712,7 +712,7 @@ export class RpcManagerService {
}
}

prepareRpcChainConfig(chainId: string, rpcs: string[]) {
prepareRpcChainConfig(chainId: string, rpcs: string[], isTestChain: boolean) {
const providers = rpcs.map((rpc, index) => {
return {
url: rpc,
Expand All @@ -727,7 +727,9 @@ export class RpcManagerService {
providers,
failureThreshold: 3,
promotionThreshold: 0.95,
healthCheckInterval: 1000, // Every 1 seconds, there will be a health check
// Mainnet chain: every 30 seconds, there will be a health check
// Testnet chain: every 2 minutes, there will be a health check
healthCheckInterval: isTestChain ? 120_000 : 30_000,
};

return rpcChainConfigs;
Expand Down
59 changes: 58 additions & 1 deletion src/modules/simulator/simulation.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ChainsService } from "@/chains";
import { BadRequestException, packUint128Pair, withTrace } from "@/common";
import { SmartSessionsAbi } from "@/contracts/resources/SmartSessionsAbi";
import { TokenWithPermitAbi } from "@/contracts/resources/erc20-with-permit";
import { type ConfigType, InjectConfig } from "@/core/config";
import { Logger } from "@/core/logger";
Expand All @@ -24,7 +25,11 @@ import {
type TriggerType,
} from "@/quotes";
import { RpcManagerService } from "@/rpc-manager";
import { type GrantPermissionResponseType, SmartSessionMode } from "@/sessions";
import {
type GrantPermissionResponseType,
Session,
SmartSessionMode,
} from "@/sessions";
import { StorageService } from "@/storage";
import { TokenSlotDetectionService } from "@/token-slot-detection";
import {
Expand All @@ -44,6 +49,7 @@ import {
type Hex,
type StateOverride,
concatHex,
decodeFunctionData,
encodeAbiParameters,
encodeFunctionData,
erc20Abi,
Expand Down Expand Up @@ -664,6 +670,55 @@ export class SimulationService {
{ callFrom: "Simulation and gas estimation phase" },
);

let additionalSessionEnableVerifcationGasLimit = 0n;

try {
// Enable sessions function selector
const ENABLE_SESSIONS_FUNTION_SELECTOR = "0x21712407";

const isEnableSessionsFlow = signedPackedUserOp.callData.includes(
ENABLE_SESSIONS_FUNTION_SELECTOR.slice(2),
);

if (isEnableSessionsFlow) {
const calls = this.decodeCalldata(signedPackedUserOp.callData);

const [enableSessionsCalls] = calls.calls.filter(
(call) =>
(call as ComposableCall).functionSig ===
ENABLE_SESSIONS_FUNTION_SELECTOR,
);

const enableSessionCalldata = (
(enableSessionsCalls as ComposableCall)
.inputParams[0] as unknown as [number, Hex]
)[1];

const { args } = decodeFunctionData({
abi: SmartSessionsAbi,
data: `${ENABLE_SESSIONS_FUNTION_SELECTOR}${enableSessionCalldata.slice(2)}`,
});

const [sessions] = args as Session[][];
if (sessions) {
for (const session of sessions) {
for (const action of session.actions) {
// Add additional 5K gas for each policies in actions to ensure more vgl for bulk enable permissions
additionalSessionEnableVerifcationGasLimit +=
BigInt(action.actionPolicies.length) * 5000n;
}
}
}
}
} catch (error) {
this.logger.trace(
{
error,
},
"Failed to calculate additional verification gas limit for enable sessions flow",
);
}

this.logger.trace(
{
simulationFailed,
Expand Down Expand Up @@ -785,6 +840,8 @@ export class SimulationService {
verificationGasLimit +=
simulationGasLimitBuffers.verificationGasLimit;

verificationGasLimit += additionalSessionEnableVerifcationGasLimit;

return {
userOpIndex,
chainId,
Expand Down
Loading