Skip to main content

Universal Action Policy

The universal action policy allows for controlled access to specific contract functions with optional parameter-based rules. Below is an example that restricts a function call to a specific parameter value.
Security Consideration: Always set appropriate time bounds and carefully consider which contract functions to expose.

  // the rest of initialization is same as here: smart-sessions/execute-transactions-on-users-behalf
      const EMPTY_RAW_RULE = {
        condition: ParamCondition.EQUAL,
        offset: 0n,
        isLimited: false,
        ref: "0x0000000000000000000000000000000000000000000000000000000000000000" as `0x${string}`,
        usage: { limit: 0n, used: 0n }
      }

      const uniActionPolicyInfoUSDC = getUniversalActionPolicy({
        valueLimitPerUse: maxUint256,
        paramRules: {
          length: 2n,
          rules: [
            // rule to restrict usdc transfer recepient
            {
              condition: ParamCondition.EQUAL,
              isLimited: false,
              offset: 0n,
              ref: pad(recepientAddress),
              usage: { limit: 0n, used: 0n }
            },
            // rule to restrict every transfer to be less than
            // or equal to 3 usdc, and total spending limit of 100 usdc
            {
              condition: ParamCondition.LESS_THAN_OR_EQUAL,
              isLimited: true,
              offset: 32n,
              ref: pad(toHex(parseUnits("3", 6))),
              usage: { limit: parseUnits("100", 6), used: 0n }
            },
            // fill the rest of rules with the placeholder rule
            // they do not matter since length above is 2
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE,
            EMPTY_RAW_RULE
          ]
        }
      })

      const sessionDetails =
        await sessionMeeClient.grantPermissionTypedDataSign({
          redeemer: redeemerAddress,
          feeToken,
          actions: [
            {
              actionTargetSelector: toFunctionSelector(
                getAbiItem({ abi: erc20Abi, name: "transfer" })
              ),
              actionPolicies: [uniActionPolicyInfoUSDC],
              chainId: targetChain.id,
              actionTarget: mcUSDC.addressOn(targetChain.id)
            }
          ],
          maxPaymentAmount: parseUnits("3", 6)
        })

Common Use Cases

  • Token Allowances: Set maximum spending limits for ERC20 tokens
  • Whitelisted Transfers: Restrict transfers to approved addresses only
  • Budget Management: Implement departmental spending controls
  • DeFi Risk Management: Limit exposure in DeFi protocols
  • Automated Payments: Control recurring token payments
  • Treasury Operations: Manage organizational token distributions

Best Practices

  1. Whitelist Recipients: Always specify allowed recipient addresses
  2. Dual Limits: Implement both per-transaction and cumulative limits
  3. Token Decimals: Carefully account for token decimal places when setting limits
  4. Usage Tracking: Monitor cumulative usage against total limits
  5. Multiple Tokens: Set appropriate limits for each token type
  6. Regular Reviews: Periodically audit spending patterns and adjust limits
  7. Combine Policies: Use with time-based restrictions for enhanced security
I