Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
23 changes: 7 additions & 16 deletions src/modules/validators/smart-sessions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,17 @@ describe('getPolicyData', () => {
// ---------------------------------------------------------------------------

describe('getSessionData', () => {
test('no actions → single sudoAction fallback', () => {
test('no actions → sudoAction fallback + dummy preclaimop action', () => {
const data = getSessionData(baseSession)
expect(data.actions).toHaveLength(1)
expect(data.actions).toHaveLength(2)
expect(data.actions[0].actionTarget).toBe(
SMART_SESSIONS_FALLBACK_TARGET_FLAG,
)
expect(data.actions[0].actionTargetSelector).toBe(
SMART_SESSIONS_FALLBACK_TARGET_SELECTOR_FLAG,
)
expect(data.actions[1].actionTarget).toBe(DUMMY_PRECLAIMOP_TARGET)
expect(data.actions[1].actionTargetSelector).toBe(DUMMY_PRECLAIMOP_SELECTOR)
})

test('explicit actions → user action + 3 injected (WETH deposit + intent-execution fallback + dummy preclaimop)', () => {
Expand Down Expand Up @@ -177,25 +179,14 @@ describe('getSessionData', () => {
expect(dummyAction!.actionPolicies[0].initData).toBe('0x')
})

test('no explicit actions → sudoAction fallback only (dummy injected via injectedActions path is not used)', () => {
// Sessions without explicit actions use the [sudoAction] fallback directly,
// which covers all (target, selector) pairs — no dummy action needed.
const data = getSessionData(baseSession)
expect(data.actions).toHaveLength(1)
expect(data.actions[0].actionTarget).toBe(
SMART_SESSIONS_FALLBACK_TARGET_FLAG,
)
})

test('empty actions array → same sudoAction fallback as no actions', () => {
// actions: [] is truthy but has no elements — must be treated the same as
// actions: undefined so injectedActions are not appended.
test('empty actions array → same as no actions (sudoAction + dummy)', () => {
const sessionWithEmptyActions: Session = { ...baseSession, actions: [] }
const data = getSessionData(sessionWithEmptyActions)
expect(data.actions).toHaveLength(1)
expect(data.actions).toHaveLength(2)
expect(data.actions[0].actionTarget).toBe(
SMART_SESSIONS_FALLBACK_TARGET_FLAG,
)
expect(data.actions[1].actionTarget).toBe(DUMMY_PRECLAIMOP_TARGET)
})

test('multiple policies on one action', () => {
Expand Down
49 changes: 32 additions & 17 deletions src/modules/validators/smart-sessions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -704,26 +704,41 @@ function getSessionData(
},
]

// Map a list of actions (user-defined + injected) to the on-chain format.
const mapActions = (acts: Action[]) =>
acts.map((action) => ({
actionTargetSelector:
'selector' in action
? action.selector
: SMART_SESSIONS_FALLBACK_TARGET_SELECTOR_FLAG,
actionTarget:
'target' in action
? action.target
: SMART_SESSIONS_FALLBACK_TARGET_FLAG,
actionPolicies: action.policies?.map((policy) =>
getPolicyData(policy, useDevContracts),
) ?? [
{
policy: SUDO_POLICY_ADDRESS,
initData: '0x' as Hex,
},
],
}))

const actions = session.actions?.length
? [...session.actions, ...injectedActions].map((action) => ({
actionTargetSelector:
'selector' in action
? action.selector
: SMART_SESSIONS_FALLBACK_TARGET_SELECTOR_FLAG,
actionTarget:
'target' in action
? action.target
: SMART_SESSIONS_FALLBACK_TARGET_FLAG,
actionPolicies: action.policies?.map((policy) =>
getPolicyData(policy, useDevContracts),
) ?? [
? mapActions([...session.actions, ...injectedActions])
: // No explicit actions — still inject the dummy preclaimop action so the
// filler can call verifyExecution in ENABLE mode even for catch-all sessions.
[
sudoAction,
...mapActions([
{
policy: SUDO_POLICY_ADDRESS,
initData: '0x' as Hex,
target: DUMMY_PRECLAIMOP_TARGET,
selector: DUMMY_PRECLAIMOP_SELECTOR,
policies: [{ type: 'sudo' as const }],
},
],
}))
: [sudoAction]
]),
]
return {
sessionValidator: validator.address,
salt: zeroHash,
Expand Down
Loading