Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple call policies do not work with session keys #147

Open
0xernesto opened this issue Jun 11, 2024 · 2 comments
Open

Multiple call policies do not work with session keys #147

0xernesto opened this issue Jun 11, 2024 · 2 comments

Comments

@0xernesto
Copy link

0xernesto commented Jun 11, 2024

Having multiple call policies for a session key does not work.

I can get the session key to work end-to-end for each individual policy below when it is the only policy in the array. When more than one policy is in the array, I get a 400 response status with the following detail: UserOperation reverted during simulation with reason: 0x.

I also tried including the permissions associated with each policy below in the permissions array of a single call policy, but that resulted in UserOperation reverted during simulation with reason: duplicate permissionHash.

const permissionPlugin = await toPermissionValidator(publicClient, {
        entryPoint,
        signer: emptySessionKeySigner,
        policies: [
            callPolicy1,
            callPolicy2,
            callPolicy3,
            callPolicy4,
        ],
    });

const sessionKeyAccount = await createKernelAccount(publicClient, {
        entryPoint,
        plugins: {
            sudo: ecdsaValidator,
            regular: permissionPlugin,
        },
    });

I'm also running into issues when using zeroAddress as the target. Passing an actual address works, but when passing zeroAddress, I get a 400 response status with the following detail UserOperation reverted during simulation with reason: 0x.

const getErc20Policy = (toAddress) =>
    toCallPolicy({
        permissions: [
            {
                target: SEPOLIA_USDC_CONTRACT,
                valueLimit: BigInt(0),
                abi: erc20Abi,
                functionName: "transfer",
                args: [
                    {
                        condition: ParamCondition.EQUAL,
                        value: toAddress,
                    },
                    null,
                ],
            },
        ],
    });

The sessionKeyAgentERC20AndEth.js script in this repo is what I was using to test.

@0xernesto
Copy link
Author

0xernesto commented Jun 20, 2024

@SahilVasava , doing the following got me to a point where only the first permission in the policy works. The overarching question is:
how do I create a policy where an agent can send any ERC-20 tokens and ETH to a limited amount of addresses (not just one)?

Neither the SDK docs or examples show how to do this.

Additionally, using an individual ERC-20 token address as the target works, but using zeroAddress to indicate all ERC-20 tokens does not work, as the docs say to do.

toCallPolicy(
{
	permissions: [
		{
			target: SEPOLIA_USDC_CONTRACT,
			valueLimit: BigInt(0),
			abi: erc20Abi,
			functionName: "transfer",
			args: [
				{
					condition: ParamCondition.EQUAL,
					value: TEST_ADDRESS_1,  // <------ sending USDC to this works
				},
				null,
			],
		},
	],
},
{
	permissions: [
		{
			target: SEPOLIA_USDC_CONTRACT,
			valueLimit: BigInt(0),
			abi: erc20Abi,
			functionName: "transfer",
			args: [
				{
					condition: ParamCondition.EQUAL,
					value: TEST_ADDRESS_2, // <------ sending USDC to this does not work
				},
				null,
			],
		},
	],
},
{
	permissions: [
		{
			target: TEST_ADDRESS_1, // <------ sending ETH to this does not work
			valueLimit: maxInt256,
		},
	],
},
{
	permissions: [
		{
			target: TEST_ADDRESS_2, // <------ sending ETH to this does not work
			valueLimit: maxInt256,
		},
	],
});

@adnpark
Copy link
Contributor

adnpark commented Jun 25, 2024

Hey @0xernesto, sorry for the late reply.

First, if you want to set multiple permissions on the call policy, you can set like this:
Note that for now, using different multiple permissions emits type error message, but you can ignore it. This will be fixed in the next version.

const callPolicy = await toCallPolicy({
                permissions: [
                    {
                        abi: erc20Abi,
                        target: SEPOLIA_USDC_CONTRACT,
                        functionName: "transfer",
                        args: [
                            {
                                condition: ParamCondition.EQUAL,
                                value: TEST_ADDRESS_1
                            },
                            null
                        ]
                    },
                    {
                       // This will emit type error but you can just ignore it.
                        abi: vaultAbi,
                        target: VAULT_CONTRACT,
                        functionName: "deposit",
                        args: [
                            {
                                condition: ParamCondition.EQUAL,
                                value: DEPOSIT_AMOUNT
                            },
                            null
                        ]
                    }
                ]
            })

In your cases, you basically want to set OR condition for the same contract function. Like give permisson to transfer to TEST_ADDRESS_1 or TEST_ADDRESS_2. Unfortunately, using this kind of OR condition in permission is not supported now.

{
	target: SEPOLIA_USDC_CONTRACT,
	valueLimit: BigInt(0),
	abi: erc20Abi,
	functionName: "transfer",
	args: [
		{
			condition: ParamCondition.EQUAL,
			value: TEST_ADDRESS_1,  // <------ sending USDC to this works
		},
		null,
	],
},
{
	target: SEPOLIA_USDC_CONTRACT,
	valueLimit: BigInt(0),
	abi: erc20Abi,
	functionName: "transfer",
	args: [
		{
			condition: ParamCondition.EQUAL,
			value: TEST_ADDRESS_2, // <------ sending USDC to this does not work
		},
		null,
	],
},

Regarding native token transfers, I could reproduce the error message when trying to set permissions for the native token transfers. The user op reverted during the simulation. I'm currently investigating the issue and will let you know as soon as it is resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants