diff --git a/contracts/smart-account/modules/SessionValidationModules/ERC20SessionValidationModule.sol b/contracts/smart-account/modules/SessionValidationModules/ERC20SessionValidationModule.sol index 647c4a57..e6b5c777 100644 --- a/contracts/smart-account/modules/SessionValidationModules/ERC20SessionValidationModule.sol +++ b/contracts/smart-account/modules/SessionValidationModules/ERC20SessionValidationModule.sol @@ -22,7 +22,7 @@ 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. expected to store userOp.sender address in this case + * param _callSpecificData additional data. * for example to store a list of allowed tokens or receivers */ function validateSessionParams( @@ -30,15 +30,14 @@ contract ERC20SessionValidationModule is ISessionValidationModule { uint256 callValue, bytes calldata _funcCallData, bytes calldata _sessionKeyData, - bytes calldata _callSpecificData + bytes calldata /*_callSpecificData */ ) external virtual override returns (address) { return _validateSessionParams( destinationContract, callValue, _funcCallData, - _sessionKeyData, - address(bytes20(_callSpecificData[0:20])) + _sessionKeyData ); } @@ -84,8 +83,7 @@ contract ERC20SessionValidationModule is ISessionValidationModule { tokenAddr, callValue, data, - _sessionKeyData, - _op.sender + _sessionKeyData ) == ECDSA.recover( ECDSA.toEthSignedMessageHash(_userOpHash), @@ -106,15 +104,13 @@ 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 userOpSender address of the userOp sender * @return sessionKey address of the sessionKey */ function _validateSessionParams( address destinationContract, uint256 callValue, bytes calldata _funcCallData, - bytes calldata _sessionKeyData, - address userOpSender + bytes calldata _sessionKeyData ) internal returns (address) { ( address sessionKey, @@ -127,6 +123,8 @@ contract ERC20SessionValidationModule is ISessionValidationModule { (address, address, address, uint256, uint256) ); + address userOpSender = address(uint160(maxUsage >> 64)); + maxUsage = uint64(maxUsage); require(destinationContract == token, "ERC20SV Wrong Token"); require(callValue == 0, "ERC20SV Non Zero Value"); diff --git a/test/bundler-integration/module/BatchedSessionRouter.Module.specs.ts b/test/bundler-integration/module/BatchedSessionRouter.Module.specs.ts index 4b477334..16fa0ded 100644 --- a/test/bundler-integration/module/BatchedSessionRouter.Module.specs.ts +++ b/test/bundler-integration/module/BatchedSessionRouter.Module.specs.ts @@ -121,6 +121,10 @@ describe("SessionKey: Batched Session Router (via Bundler)", async () => { ).deploy(); const maxUsage = 10; + const maxUsageAndSAAddress = ethers.utils.hexConcat([ + userSA.address, + ethers.utils.hexZeroPad(ethers.utils.hexlify(maxUsage), 8), + ]); // create leaf for the erc20 session validation module const { sessionKeyData, leafData } = await getERC20SessionKeyParams( @@ -128,7 +132,7 @@ describe("SessionKey: Batched Session Router (via Bundler)", async () => { mockToken.address, mockProtocol.address, maxAmount, - maxUsage, + maxUsageAndSAAddress, 0, 0, erc20SessionModule.address @@ -141,7 +145,7 @@ describe("SessionKey: Batched Session Router (via Bundler)", async () => { mockProtocol.address, // contract to interact with mockToken.address, // token to transfer to protocol maxAmount, - maxUsage, + maxUsageAndSAAddress, 0, 0, mockProtocolSVModule.address @@ -257,7 +261,7 @@ describe("SessionKey: Batched Session Router (via Bundler)", async () => { erc20SessionModule.address, sessionKeyData, merkleTree.getHexProof(ethers.utils.keccak256(leafData)), - userSA.address, + "0x", ], [ 0, @@ -265,7 +269,7 @@ describe("SessionKey: Batched Session Router (via Bundler)", async () => { mockProtocolSVM.address, sessionKeyData2, merkleTree.getHexProof(ethers.utils.keccak256(leafData2)), - userSA.address, + "0x", ], ], signatureOverUserOpHash, diff --git a/test/bundler-integration/module/MultichainValidator.Module.specs.ts b/test/bundler-integration/module/MultichainValidator.Module.specs.ts index 148cc3bf..eaf2861f 100644 --- a/test/bundler-integration/module/MultichainValidator.Module.specs.ts +++ b/test/bundler-integration/module/MultichainValidator.Module.specs.ts @@ -117,13 +117,17 @@ describe("MultichainValidator Module", async () => { // ============== session key setup ============= const maxUsageOfTheSession = 10; + const maxUsageAndSAAddress = ethers.utils.hexConcat([ + expectedSmartAccountAddress, + ethers.utils.hexZeroPad(ethers.utils.hexlify(maxUsageOfTheSession), 8), + ]); const { leafData } = await getERC20SessionKeyParams( sessionKey.address, mockToken.address, charlie.address, maxAmount, - maxUsageOfTheSession, + maxUsageAndSAAddress, 0, 0, erc20SessionModule.address diff --git a/test/bundler-integration/module/SessionValidationModules/ERC20SessionValidation.Module.specs.ts b/test/bundler-integration/module/SessionValidationModules/ERC20SessionValidation.Module.specs.ts index bb55bbc5..0f513455 100644 --- a/test/bundler-integration/module/SessionValidationModules/ERC20SessionValidation.Module.specs.ts +++ b/test/bundler-integration/module/SessionValidationModules/ERC20SessionValidation.Module.specs.ts @@ -3,7 +3,6 @@ import { makeEcdsaSessionKeySignedUserOp, enableNewTreeForSmartAccountViaEcdsa, getERC20SessionKeyParams, - addLeavesForSmartAccountViaEcdsa, } from "../../../utils/sessionKey"; import { ethers, deployments } from "hardhat"; import { makeEcdsaModuleUserOp, fillAndSign } from "../../../utils/userOp"; @@ -110,13 +109,17 @@ describe("SessionKey: ERC20 Session Validation Module (with Bundler)", async () ).deploy(); const maxUsageOfTheSession = 10; + const maxUsageAndSAAddress = ethers.utils.hexConcat([ + userSA.address, + ethers.utils.hexZeroPad(ethers.utils.hexlify(maxUsageOfTheSession), 8), + ]); const { sessionKeyData, leafData } = await getERC20SessionKeyParams( sessionKey.address, mockToken.address, charlie.address, maxAmount, - maxUsageOfTheSession, + maxUsageAndSAAddress, 0, 0, erc20SessionModule.address diff --git a/test/module/SessionValidationModules/ERC20SessionValidation.Module.specs.ts b/test/module/SessionValidationModules/ERC20SessionValidation.Module.specs.ts index 343dc90d..c28ad34e 100644 --- a/test/module/SessionValidationModules/ERC20SessionValidation.Module.specs.ts +++ b/test/module/SessionValidationModules/ERC20SessionValidation.Module.specs.ts @@ -78,13 +78,19 @@ describe("SessionKey: ERC20 Session Validation Module", async () => { ).deploy(); const maxUsageOfTheSession = 1; + const maxUsageAndSAAddress = ethers.utils.hexConcat([ + userSA.address, + ethers.utils.hexZeroPad(ethers.utils.hexlify(maxUsageOfTheSession), 8), + ]); + + console.log(maxUsageAndSAAddress); const { sessionKeyData, leafData } = await getERC20SessionKeyParams( sessionKey.address, mockToken.address, charlie.address, maxAmount, - maxUsageOfTheSession, + maxUsageAndSAAddress, 0, 0, erc20SessionModule.address @@ -117,7 +123,7 @@ describe("SessionKey: ERC20 Session Validation Module", async () => { merkleTree: merkleTree, vulnerableErc20SessionModule: vulnerableErc20SessionModule, sessionKey: sessionKey, - maxUsageOfTheSession: maxUsageOfTheSession, + maxUsageOfTheSession: maxUsageAndSAAddress, }; }); diff --git a/test/utils/sessionKey.ts b/test/utils/sessionKey.ts index 177fac8e..964a24bb 100644 --- a/test/utils/sessionKey.ts +++ b/test/utils/sessionKey.ts @@ -204,7 +204,7 @@ export async function getERC20SessionKeyParams( erc20TokenAddress: string, receiverAddress: string, maxAmountToTransfer: BigNumber, - maxUsage: number, + maxUsage: string, validUntil: number, validAfter: number, sessionValidationModuleAddress: string