From 0346c84fa7b2b971d8519443922bdb583304691a Mon Sep 17 00:00:00 2001 From: Jeff Smale <6363749+jeffsmale90@users.noreply.github.com> Date: Fri, 12 Dec 2025 10:32:55 +1300 Subject: [PATCH] Function call scope no longer accepts native token value, unless explicitly configured. --- .../caveatBuilder/scope/functionCallScope.ts | 14 ++++-- .../delegationManagement.test.ts | 6 +-- .../scope/functionCallScope.test.ts | 47 +++++++++++++++++++ 3 files changed, 59 insertions(+), 8 deletions(-) diff --git a/packages/smart-accounts-kit/src/caveatBuilder/scope/functionCallScope.ts b/packages/smart-accounts-kit/src/caveatBuilder/scope/functionCallScope.ts index 947295c9..2b863a92 100644 --- a/packages/smart-accounts-kit/src/caveatBuilder/scope/functionCallScope.ts +++ b/packages/smart-accounts-kit/src/caveatBuilder/scope/functionCallScope.ts @@ -6,17 +6,18 @@ import type { AllowedTargetsBuilderConfig } from '../allowedTargetsBuilder'; import { createCaveatBuilder } from '../coreCaveatBuilder'; import type { CoreCaveatBuilder } from '../coreCaveatBuilder'; import type { ExactCalldataBuilderConfig } from '../exactCalldataBuilder'; +import type { ValueLteBuilderConfig } from '../valueLteBuilder'; type FunctionCallScopeBaseConfig = { type: 'functionCall'; + allowedCalldata?: AllowedCalldataBuilderConfig[]; + exactCalldata?: ExactCalldataBuilderConfig; + valueLte?: ValueLteBuilderConfig; }; export type FunctionCallScopeConfig = FunctionCallScopeBaseConfig & AllowedTargetsBuilderConfig & - AllowedMethodsBuilderConfig & { - allowedCalldata?: AllowedCalldataBuilderConfig[]; - exactCalldata?: ExactCalldataBuilderConfig; - }; + AllowedMethodsBuilderConfig; const isFunctionCallConfig = ( config: FunctionCallScopeConfig, @@ -49,9 +50,12 @@ export function createFunctionCallCaveatBuilder( ); } + const valueLteConfig = config.valueLte ?? { maxValue: 0n }; + const caveatBuilder = createCaveatBuilder(environment) .addCaveat('allowedTargets', { targets }) - .addCaveat('allowedMethods', { selectors }); + .addCaveat('allowedMethods', { selectors }) + .addCaveat('valueLte', valueLteConfig); if (allowedCalldata && allowedCalldata.length > 0) { allowedCalldata.forEach((calldataConfig) => { diff --git a/packages/smart-accounts-kit/test/DelegationFramework/DelegationManager/delegationManagement.test.ts b/packages/smart-accounts-kit/test/DelegationFramework/DelegationManager/delegationManagement.test.ts index c710dbdf..83660ef9 100644 --- a/packages/smart-accounts-kit/test/DelegationFramework/DelegationManager/delegationManagement.test.ts +++ b/packages/smart-accounts-kit/test/DelegationFramework/DelegationManager/delegationManagement.test.ts @@ -98,7 +98,7 @@ describe('DelegationManager - Delegation Management', () => { }); expect(isHex(encodedData, { strict: true })).toBe(true); - expect(encodedData.length).toBe(1482); + expect(encodedData.length).toBe(1930); }); }); @@ -123,7 +123,7 @@ describe('DelegationManager - Delegation Management', () => { }); expect(isHex(encodedData, { strict: true })).toBe(true); - expect(encodedData.length).toBe(1482); + expect(encodedData.length).toBe(1930); }); }); @@ -154,7 +154,7 @@ describe('DelegationManager - Delegation Management', () => { }); expect(isHex(encodedData, { strict: true })).toBe(true); - expect(encodedData.length).toBe(2442); + expect(encodedData.length).toBe(2890); }); }); }); diff --git a/packages/smart-accounts-kit/test/caveatBuilder/scope/functionCallScope.test.ts b/packages/smart-accounts-kit/test/caveatBuilder/scope/functionCallScope.test.ts index fb666004..04040ddc 100644 --- a/packages/smart-accounts-kit/test/caveatBuilder/scope/functionCallScope.test.ts +++ b/packages/smart-accounts-kit/test/caveatBuilder/scope/functionCallScope.test.ts @@ -14,6 +14,7 @@ describe('createFunctionCallCaveatBuilder', () => { AllowedMethodsEnforcer: randomAddress(), AllowedCalldataEnforcer: randomAddress(), ExactCalldataEnforcer: randomAddress(), + ValueLteEnforcer: randomAddress(), }, } as unknown as SmartAccountsEnvironment; @@ -39,6 +40,11 @@ describe('createFunctionCallCaveatBuilder', () => { args: '0x', terms: concat(config.selectors as Hex[]), }, + { + enforcer: environment.caveatEnforcers.ValueLteEnforcer, + args: '0x', + terms: toHex(0n, { size: 32 }), + }, ]); }); @@ -66,6 +72,11 @@ describe('createFunctionCallCaveatBuilder', () => { args: '0x', terms: concat(config.selectors as Hex[]), }, + { + enforcer: environment.caveatEnforcers.ValueLteEnforcer, + args: '0x', + terms: toHex(0n, { size: 32 }), + }, { enforcer: environment.caveatEnforcers.AllowedCalldataEnforcer, args: '0x', @@ -101,6 +112,11 @@ describe('createFunctionCallCaveatBuilder', () => { args: '0x', terms: concat(config.selectors as Hex[]), }, + { + enforcer: environment.caveatEnforcers.ValueLteEnforcer, + args: '0x', + terms: toHex(0n, { size: 32 }), + }, { enforcer: environment.caveatEnforcers.ExactCalldataEnforcer, args: '0x', @@ -109,6 +125,37 @@ describe('createFunctionCallCaveatBuilder', () => { ]); }); + it('creates a Function Call CaveatBuilder with configured valueLte', () => { + const config: FunctionCallScopeConfig = { + type: 'functionCall', + targets: [randomAddress()], + selectors: ['0x12345678'], + valueLte: { maxValue: 123n }, + }; + + const caveatBuilder = createFunctionCallCaveatBuilder(environment, config); + + const caveats = caveatBuilder.build(); + + expect(caveats).to.deep.equal([ + { + enforcer: environment.caveatEnforcers.AllowedTargetsEnforcer, + args: '0x', + terms: concat(config.targets), + }, + { + enforcer: environment.caveatEnforcers.AllowedMethodsEnforcer, + args: '0x', + terms: concat(config.selectors as Hex[]), + }, + { + enforcer: environment.caveatEnforcers.ValueLteEnforcer, + args: '0x', + terms: toHex(123n, { size: 32 }), + }, + ]); + }); + it('throws an error for invalid configuration', () => { const config = { type: 'functionCall',