Skip to content

Commit

Permalink
sessionData length check
Browse files Browse the repository at this point in the history
  • Loading branch information
Filipp Makarov authored and Filipp Makarov committed Sep 20, 2023
1 parent 5d3735f commit 484e2a2
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ contract BatchedSessionRouter is BaseAuthorizationModule {
) = abi.decode(userOp.callData[4:], (address[], uint256[], bytes[]));

uint256 length = sessionData.length;
require(length == destinations.length, "Lengths mismatch");

// TODO: since we do not sign SessionDatas[] , can it somehow be messed with?
// like provide it in the wrong order. => should not work as it will be verified along with the calldata

// iterate over batched operations
for (uint256 i; i < length; ) {
// validate the sessionKey
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ contract ERC20SessionValidationModule is ISessionValidationModule {
* @param callValue value to be sent with the call
* @param _funcCallData the data for the call. is parsed inside the SVM
* @param _sessionKeyData SessionKey data, that describes sessionKey permissions
* param _callSpecificData additional data, for example some proofs if the SVM utilizes merkle trees itself
* for example to store a list of allowed tokens or receivers
*/
function validateSessionParams(
address destinationContract,
Expand Down
110 changes: 108 additions & 2 deletions test/module/BatchedSessionRouter.Module.specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from "../utils/setupHelper";
import { computeAddress } from "ethers/lib/utils";

describe("SessionKey: Session Router", async () => {
describe("SessionKey: Batched Session Router", async () => {
const [
deployer,
smartAccountOwner,
Expand Down Expand Up @@ -371,7 +371,7 @@ describe("SessionKey: Session Router", async () => {
[approveCallData, interactCallData],
],
userSA.address,
nonAuthSessionKey,
nonAuthSessionKey, // not authorized session key
entryPoint,
sessionKeyManager.address,
[
Expand Down Expand Up @@ -402,6 +402,112 @@ describe("SessionKey: Session Router", async () => {
.withArgs(0, "AA24 signature error");
});

it("Should revert when sessionData array is empty", async () => {
const {
entryPoint,
userSA,
sessionKeyManager,
sessionRouter,
mockProtocol,
mockToken,
} = await setupTests();
const tokenAmountToTransfer = ethers.utils.parseEther("1.7534");

const MockProtocol = await ethers.getContractFactory("MockProtocol");
const IERC20 = await ethers.getContractFactory("ERC20");

const approveCallData = IERC20.interface.encodeFunctionData("approve", [
mockProtocol.address,
tokenAmountToTransfer,
]);
const interactCallData = MockProtocol.interface.encodeFunctionData(
"interact",
[mockToken.address, tokenAmountToTransfer]
);

const userOp = await makeEcdsaSessionKeySignedBatchUserOp(
"executeBatch_y6U",
[
[mockToken.address, mockProtocol.address],
[0, 0],
[approveCallData, interactCallData],
],
userSA.address,
sessionKey,
entryPoint,
sessionKeyManager.address,
[], //empty session data array
sessionRouter.address
);

await expect(
entryPoint.handleOps([userOp], alice.address, { gasLimit: 10000000 })
)
.to.be.revertedWith("FailedOp")
.withArgs(0, "AA23 reverted: Lengths mismatch");
});

it("Should revert if not enough session datas provided", async () => {
const {
entryPoint,
userSA,
sessionKeyManager,
erc20SessionModule,
sessionKeyData,
leafData,
merkleTree,
sessionRouter,
mockProtocol,
mockProtocolSVM,
mockToken,
sessionKeyData2,
leafData2,
} = await setupTests();
const tokenAmountToTransfer = ethers.utils.parseEther("1.7534");

const MockProtocol = await ethers.getContractFactory("MockProtocol");
const IERC20 = await ethers.getContractFactory("ERC20");

const approveCallData = IERC20.interface.encodeFunctionData("approve", [
mockProtocol.address,
tokenAmountToTransfer,
]);
const interactCallData = MockProtocol.interface.encodeFunctionData(
"interact",
[mockToken.address, tokenAmountToTransfer]
);

const userOp = await makeEcdsaSessionKeySignedBatchUserOp(
"executeBatch_y6U",
[
[mockToken.address, mockProtocol.address],
[0, 0],
[approveCallData, interactCallData],
],
userSA.address,
sessionKey,
entryPoint,
sessionKeyManager.address,
[
[
0,
0,
erc20SessionModule.address,
sessionKeyData,
merkleTree.getHexProof(ethers.utils.keccak256(leafData)),
"0x",
],
],
sessionRouter.address
);

await expect(
entryPoint.handleOps([userOp], alice.address, { gasLimit: 10000000 })
)
.to.be.revertedWith("FailedOp")
.withArgs(0, "AA23 reverted: Lengths mismatch");
});

it("Should revert when when at least one SVM permission is violated", async () => {
const {
entryPoint,
Expand Down

0 comments on commit 484e2a2

Please sign in to comment.