Skip to content

Commit fcabd1a

Browse files
committed
fix(chore): address PR #22 review — BigInt safety, PaymasterClient floor, M7r6 selector, EIP-55
[Blocking] BigInt→Number unsafe conversion (Claude H1 / Codex M1): - UserClient.ts + SuperPaymasterClient.ts: replace Math.max(Number(...)) with pure BigInt comparison const base = est.paymasterPostOpGasLimit + 100_000n; result = base > 200_000n ? base : 200_000n [Blocking] PaymasterClient OOG fix incomplete (Codex H1): - submitGaslessUserOperation: default floor raised 150k→200k - autoEstimate path now applies same 100k buffer + 200k floor (caller-supplied value is respected as-is) [Blocking] sepoliaV07Config silently re-targets r4 (Codex H2): - AirAccountVersion type: add "M7r6" selector - sepoliaV07Config("M7r6") routes to factoryM7r6 for legacy r6 account recovery - JSDoc updated with explicit warning: M7r6 = recovery only, not for new account creation [Suggested] EIP-55 checksum consistency (Claude M1 / Codex L1): - All 5 r4 addresses now use EIP-55 mixed-case checksum [Suggested] factoryM7r5Prev @deprecated JSDoc (Claude L1 / Codex L2)
1 parent 612e804 commit fcabd1a

5 files changed

Lines changed: 35 additions & 19 deletions

File tree

packages/airaccount/src/server/config.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,34 @@ export interface ServerConfig {
5353
logger?: ILogger;
5454
}
5555

56-
/** AirAccount contract version selection. */
57-
export type AirAccountVersion = "M5" | "M7";
56+
/** AirAccount contract version selection.
57+
* - "M7" — r4 audit-final (default). Use for all new account creation.
58+
* - "M7r6" — r6 deployment (2026-03-29, superseded). Use ONLY to recover existing r6-deployed accounts.
59+
* - "M5" — legacy 6-field InitConfig deployment.
60+
*/
61+
export type AirAccountVersion = "M5" | "M7" | "M7r6";
5862

5963
/**
6064
* Build a pre-configured EntryPointVersionConfig for Sepolia using a known AirAccount deployment.
6165
* Eliminates the need to look up contract addresses manually.
6266
*
6367
* @example
64-
* // Use M7 (default)
68+
* // Use M7 r4 audit-final (default)
6569
* const config = { entryPoints: { v07: sepoliaV07Config() }, ... };
6670
*
71+
* // Recover an existing r6-deployed account (do NOT use for new accounts)
72+
* const config = { entryPoints: { v07: sepoliaV07Config("M7r6") }, ... };
73+
*
6774
* // Use M5 legacy
6875
* const config = { entryPoints: { v07: sepoliaV07Config("M5") }, ... };
6976
*/
7077
export function sepoliaV07Config(version: AirAccountVersion = "M7"): EntryPointVersionConfig {
7178
const factoryAddress =
7279
version === "M5"
7380
? AIRACCOUNT_ADDRESSES.sepolia.factoryM5
74-
: AIRACCOUNT_ADDRESSES.sepolia.factory;
81+
: version === "M7r6"
82+
? AIRACCOUNT_ADDRESSES.sepolia.factoryM7r6
83+
: AIRACCOUNT_ADDRESSES.sepolia.factory; // "M7" = r4 audit-final (default)
7584

7685
return {
7786
entryPointAddress: ENTRYPOINT_ADDRESSES[EntryPointVersion.V0_7].sepolia,

packages/airaccount/src/server/constants/entrypoint.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ export const AIRACCOUNT_ADDRESSES = {
7070
factoryM4: "0x914db0a849f55e68a726c72fd02b7114b1176d88",
7171
// M5 factory r5 — 6-field InitConfig, guardian acceptance sigs required
7272
factoryM5: "0xd72a236d84be6c388a8bc7deb64afd54704ae385",
73-
// M7 factory r5 (prev) — defaultCommunityGuardian was address(0), do not use for new accounts
74-
factoryM7r5Prev: "0xa0007c5db27548d8c1582773856db1d123107383",
73+
/** @deprecated defaultCommunityGuardian was address(0); superseded by r6 and r4. Do not use for new accounts. */
74+
factoryM7r5Prev: "0xa0007c5dB27548D8c1582773856dB1D123107383",
7575

7676
// ── Deprecated: r6 addresses (2026-03-29 deployment, superseded by r4 audit-final) ──────────
7777
// Retain for legacy account lookups and historical event indexing ONLY.
@@ -89,18 +89,18 @@ export const AIRACCOUNT_ADDRESSES = {
8989

9090
// ── Current: r4 audit-final (freeze/m7-v0.16.0, 660 tests, all audit findings resolved) ─────
9191
// M7 factory r4 — EIP-1167 clone factory, full audit-final release
92-
factory: "0x61bbaf9e1b8fd78ff874776cfa50497db9d43c3f",
93-
factoryM7: "0x61bbaf9e1b8fd78ff874776cfa50497db9d43c3f",
92+
factory: "0x61bBAf9E1b8Fd78fF874776cFa50497dB9d43C3F",
93+
factoryM7: "0x61bBAf9E1b8Fd78fF874776cFa50497dB9d43C3F",
9494
// M7 account implementation r4 (shared by all clone proxies, 23,847B EIP-170 compliant)
9595
accountImpl: "0xA674D308ce22230B70412b20Ee5a66fC6B24F49c",
9696
validatorRouter: "0x730a162Ce3202b94cC5B74181B75b11eBB3045B1",
9797
blsAlgorithm: "0xc2096E8D04beb3C337bb388F5352710d62De0287",
9898
blsAggregator: "0x7700aec8a15a94db5697c581de8c88ecf83b59ff",
9999
superPaymaster: "0x16cE0c7d846f9446bbBeb9C5a84A4D140fAeD94A",
100100
// M7 r4 ERC-7579 modules (pre-installed by factory on every new account)
101-
compositeValidator: "0xb65569950c48aa56dbe876915ca3605fd6ff2980",
102-
tierGuardHook: "0x67f878295cff7451cbd2a775c4490607af1b07d7",
103-
agentSessionKeyValidator: "0x1f06961e133217801f92e1cf552187f594a32873",
101+
compositeValidator: "0xB65569950C48AA56dbe876915ca3605fD6FF2980",
102+
tierGuardHook: "0x67f878295cFF7451CBD2A775C4490607AF1b07d7",
103+
agentSessionKeyValidator: "0x1F06961e133217801F92e1CF552187F594a32873",
104104
// M6 继承合约(M7 factory 仍可配合使用)
105105
sessionKeyValidator: "0xcaba5a18e46f728b5330ea33bd099693a1b76217",
106106
calldataParserRegistry: "0x7099eb39fbab795e66dd71fbeaace150edf1b3c3",

packages/enduser/src/UserClient.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,8 +499,9 @@ export class UserClient extends BaseClient {
499499
verificationGasLimit = est.verificationGasLimit + SAFETY_PAD;
500500

501501
// SuperPaymaster postOp calls burnFromWithOpHash (~40k gas) + storage writes.
502-
// Add 100k buffer; floor at 200k to prevent OOG.
503-
paymasterPostOpGasLimit = BigInt(Math.max(Number(est.paymasterPostOpGasLimit + 100000n), 200000));
502+
// Add 100k buffer; floor at 200k to prevent OOG. Pure BigInt to avoid Number precision loss.
503+
const _postOpBase = est.paymasterPostOpGasLimit + 100_000n;
504+
paymasterPostOpGasLimit = _postOpBase > 200_000n ? _postOpBase : 200_000n;
504505

505506
autoEstimate = false; // logic handled
506507
}

packages/paymaster/src/V4/PaymasterClient.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,13 +336,13 @@ export class PaymasterClient {
336336
verificationGasLimit: options?.verificationGasLimit,
337337
callGasLimit: options?.callGasLimit,
338338
paymasterVerificationGasLimit: options?.paymasterVerificationGasLimit,
339-
paymasterPostOpGasLimit: options?.paymasterPostOpGasLimit ?? 150000n
339+
paymasterPostOpGasLimit: options?.paymasterPostOpGasLimit ?? 200_000n
340340
};
341341

342342
if (options?.autoEstimate !== false && (!gasLimits.verificationGasLimit || !gasLimits.callGasLimit)) {
343343
const est = await this.estimateUserOperationGas(
344-
client, wallet, aaAddress, entryPoint, paymasterAddress, token, bundlerUrl, callData,
345-
{
344+
client, wallet, aaAddress, entryPoint, paymasterAddress, token, bundlerUrl, callData,
345+
{
346346
validityWindow: options?.validityWindow,
347347
operator: options?.operator,
348348
factory: options?.factory,
@@ -353,7 +353,12 @@ export class PaymasterClient {
353353
gasLimits.verificationGasLimit = options?.verificationGasLimit ?? est.verificationGasLimit;
354354
gasLimits.callGasLimit = options?.callGasLimit ?? est.callGasLimit;
355355
gasLimits.paymasterVerificationGasLimit = options?.paymasterVerificationGasLimit ?? est.paymasterVerificationGasLimit;
356-
gasLimits.paymasterPostOpGasLimit = options?.paymasterPostOpGasLimit ?? est.paymasterPostOpGasLimit;
356+
// SuperPaymaster postOp calls burnFromWithOpHash (~40k) + storage writes.
357+
// Apply 100k buffer with 200k floor. Pure BigInt to avoid Number precision loss.
358+
if (!options?.paymasterPostOpGasLimit) {
359+
const _base = est.paymasterPostOpGasLimit + 100_000n;
360+
gasLimits.paymasterPostOpGasLimit = _base > 200_000n ? _base : 200_000n;
361+
}
357362
}
358363

359364
// 1. Get Nonce

packages/paymaster/src/V4/SuperPaymasterClient.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ export class SuperPaymasterClient {
114114
const tunedPMVerificationGas = tuneGasLimit(bundlerEstimateVGL, 60_000n, 0.45);
115115

116116
// SuperPaymaster postOp calls burnFromWithOpHash (~40k gas) + storage writes.
117-
// Add 100k buffer; floor at 200k to prevent OOG in postOp.
118-
const tunedPostOp = BigInt(Math.max(Number(est.paymasterPostOpGasLimit + 100000n), 200000));
117+
// Add 100k buffer; floor at 200k to prevent OOG. Pure BigInt to avoid Number precision loss.
118+
const _postOpBase = est.paymasterPostOpGasLimit + 100_000n;
119+
const tunedPostOp = _postOpBase > 200_000n ? _postOpBase : 200_000n;
119120

120121
console.log(`[SuperPaymasterClient] 🔧 Tuned Limits: VGL=${tunedVGL}, PMVGL=${tunedPMVerificationGas}, PostOp=${tunedPostOp}`);
121122

0 commit comments

Comments
 (0)