Skip to content

Commit

Permalink
chore: test support for smart sessions (#565)
Browse files Browse the repository at this point in the history
* chore: add test support for smart sessions
  • Loading branch information
joepegler authored Sep 3, 2024
1 parent 678a5cc commit b2a3e28
Show file tree
Hide file tree
Showing 17 changed files with 546 additions and 143 deletions.
4 changes: 4 additions & 0 deletions .github/actions/install-dependencies/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ runs:
- name: Set up foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Installs with yarn
shell: bash
run: yarn install

- name: Install dependencies
shell: bash
run: |
Expand Down
17 changes: 0 additions & 17 deletions .github/workflows/pr-lint.yml

This file was deleted.

Binary file modified bun.lockb
Binary file not shown.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@
"devDependencies": {
"@biomejs/biome": "1.6.0",
"@changesets/cli": "^2.27.1",
"@commitlint/cli": "^19.0.3",
"@commitlint/config-conventional": "^19.0.3",
"@commitlint/cli": "^19.4.1",
"@commitlint/config-conventional": "^19.4.1",
"@ethersproject/abi": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"@ethersproject/wallet": "^5.7.0",
Expand Down
2 changes: 1 addition & 1 deletion scripts/fetch:deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const getDeployments = async () => {
}

// Write ABI index file...
const abiIndexContent = `export * from "./EntryPointABI"\n${coreFiles
const abiIndexContent = `export * from "./UniActionPolicyAbi"\nexport * from "./EntryPointABI"\n${coreFiles
.map((file) => `export * from "./${file}Abi"`)
.join("\n")}`

Expand Down
58 changes: 58 additions & 0 deletions src/__contracts/abi/UniActionPolicyAbi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export const UniActionPolicyAbi = [
{
components: [
{
name: "valueLimitPerUse",
type: "uint256"
},
{
components: [
{
name: "length",
type: "uint256"
},
{
components: [
{
name: "condition",
type: "uint8"
},
{
name: "offset",
type: "uint64"
},
{
name: "isLimited",
type: "bool"
},
{
name: "ref",
type: "bytes32"
},
{
components: [
{
name: "limit",
type: "uint256"
},
{
name: "used",
type: "uint256"
}
],
name: "usage",
type: "tuple"
}
],
name: "rules",
type: "tuple[]"
}
],
name: "paramRules",
type: "tuple"
}
],
name: "ActionConfig",
type: "tuple"
}
] as const
1 change: 1 addition & 0 deletions src/__contracts/abi/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./UniActionPolicyAbi"
export * from "./EntryPointABI"
export * from "./NexusAbi"
export * from "./K1ValidatorAbi"
Expand Down
3 changes: 2 additions & 1 deletion src/__contracts/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Hex } from "viem"
export const addresses: Record<string, Hex> = {
Nexus: "0x776d63154D2aa9256D72C420416c930F3B735464",
K1Validator: "0xd98238BBAeA4f91683d250003799EAd31d7F5c55",
K1ValidatorFactory: "0x8025afaD10209b8bEF3A3C94684AaE4D309c9996"
K1ValidatorFactory: "0x8025afaD10209b8bEF3A3C94684AaE4D309c9996",
UniActionPolicy: "0x28120dC008C36d95DE5fa0603526f219c1Ba80f6"
} as const
export default addresses
2 changes: 2 additions & 0 deletions src/account/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export const DefaultGasLimit = {
}

export const ERROR_MESSAGES = {
INVALID_HEX:
"Invalid hex, if you are targeting a number, consider using pad() and toHex() from viem: pad(toHex(BigInt(2000))",
ACCOUNT_NOT_DEPLOYED: "Account has not yet been deployed",
ACCOUNT_ALREADY_DEPLOYED: "Account already deployed",
NO_NATIVE_TOKEN_BALANCE_DURING_DEPLOY:
Expand Down
147 changes: 147 additions & 0 deletions src/modules/smartSessions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { type Address, type Hex, encodeAbiParameters } from "viem"
import { UniActionPolicyAbi } from "../__contracts/abi"
import { type AnyReferenceValue, parseReferenceValue } from "./utils/Helper"

export type Rule = {
/**
* EQUAL = 0,
* GREATER_THAN = 1,
* LESS_THAN = 2,
* GREATER_THAN_OR_EQUAL = 3,
* LESS_THAN_OR_EQUAL = 4,
* NOT_EQUAL = 5
*/
condition: ParamCondition
/**
* The offset in the calldata where the value to be checked is located.
* The offset is in multiples of 32 bytes. (Note: not the offsetIndex)
* The offsetIndex is generally the index of the arg in the method that you wish to target.
* The exception is when the arg is in an array
* In this case, the offsetIndex needs to be figured out using its position in the array
* (See the 'use-of-dynamic-types' example below for how to figure out the offsetIndex for an array)
*
* https://docs.soliditylang.org/en/develop/abi-spec.html#use-of-dynamic-types
*
* */
offsetIndex: number
/**
* If the rule is limited, the usage object will contain the limit and the used values.
*/
isLimited: boolean
/**
* The reference value to compare against. You can pass in the raw hex value or a human-friendly value.
* Use the raw hex value if you are sure of the value you are passing in.
*/
ref: AnyReferenceValue
/**
* The usage object will contain the limit and the used values, and is only required if the isLimited property is true.
*/
usage: LimitUsage
}

export type ActionConfig = {
valueLimitPerUse: bigint
paramRules: {
length: number
rules: Rule[]
}
}

export const toActionConfig = (config: ActionConfig): RawActionConfig => ({
valueLimitPerUse: BigInt(config.valueLimitPerUse),
paramRules: {
length: BigInt(config.paramRules.length),
rules: config.paramRules.rules.map((rule) => {
const parsedRef = parseReferenceValue(rule.ref)
return {
condition: rule.condition,
offset: BigInt(rule.offsetIndex) * BigInt(32),
isLimited: rule.isLimited,
ref: parsedRef,
usage: rule.usage
}
})
}
})

export type RawActionConfig = {
valueLimitPerUse: bigint
paramRules: RawParamRules
}

export type RawParamRules = {
length: bigint
rules: RawParamRule[]
}

export type RawParamRule = {
condition: ParamCondition
offset: bigint
isLimited: boolean
ref: Hex
usage: LimitUsage
}

export type LimitUsage = {
limit: bigint
used: bigint
}

export enum ParamCondition {
EQUAL = 0,
GREATER_THAN = 1,
LESS_THAN = 2,
GREATER_THAN_OR_EQUAL = 3,
LESS_THAN_OR_EQUAL = 4,
NOT_EQUAL = 5
}

export type Policy = {
address: Hex
initData: Hex
deInitData: Hex
}

export type Params = {
token: Address
limit: bigint
}[]

export const MAX_RULES = 16

export const toUniversalActionPolicy = (
actionConfig: ActionConfig
): Policy => ({
address: "0x28120dC008C36d95DE5fa0603526f219c1Ba80f6",
initData: encodeAbiParameters(UniActionPolicyAbi, [
toActionConfig(actionConfig)
]),
deInitData: "0x"
})

export const sudoPolicy: Policy = {
address: "0x",
initData: "0x",
deInitData: "0x"
}

export const toSpendingLimitsPolicy = (params: Params): Policy => {
return {
address: "0xDe9688b24c00699Ad51961ef90Ce5a9a8C49982B",
initData: encodeAbiParameters(
[{ type: "address[]" }, { type: "uint256[]" }],
[params.map(({ token }) => token), params.map(({ limit }) => limit)]
),
deInitData: "0x"
}
}

export const policies = {
to: {
universalAction: toUniversalActionPolicy,
spendingLimits: toSpendingLimitsPolicy
},
sudo: sudoPolicy
} as const

export default policies
Loading

0 comments on commit b2a3e28

Please sign in to comment.