Skip to content

Commit

Permalink
πŸ‘·πŸ»β€β™‚οΈ Test ValidateSessionUserOp
Browse files Browse the repository at this point in the history
  • Loading branch information
JaredBorders committed Sep 29, 2023
1 parent 7c7731e commit 00f862b
Show file tree
Hide file tree
Showing 3 changed files with 202 additions and 42 deletions.
164 changes: 155 additions & 9 deletions test/SMv2SessionValidationModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,68 @@ pragma solidity 0.8.18;
import {
Bootstrap, SMv2SessionValidationModule
} from "test/utils/Bootstrap.sol";
import {
UserOperationSignature,
UserOperation,
UserOperationLib
} from "test/utils/UserOperationSignature.sol";
import {IAccount} from "src/kwenta/smv2/IAccount.sol";

contract SMv2SessionValidationModuleTest is Bootstrap {
address signer;
uint256 signerPrivateKey;
address bad_signer;
uint256 bad_signerPrivateKey;

address sessionKey;
address smv2ProxyAccount;
bytes4 smv2ExecuteSelector;
address destinationContract;
uint256 callValue;
bytes funcCallData;
bytes sessionKeyData;
bytes sessionKeySignature;
bytes callSpecificData;

bytes4 public constant EXECUTE_SELECTOR = 0xb61d27f6;
bytes4 public constant EXECUTE_OPTIMIZED_SELECTOR = 0x0000189a;

UserOperationSignature userOpSignature;
UserOperation op;
bytes32 userOpHash;
bytes data;

function setUp() public {
initializeOptimismGoerli();

userOpSignature = new UserOperationSignature();

// signers
signerPrivateKey = 0x12341234;
signer = vm.addr(signerPrivateKey);
bad_signerPrivateKey = 0x12341235;
bad_signer = vm.addr(bad_signerPrivateKey);

// session key data
sessionKey = address(0x1);
sessionKey = signer;
smv2ProxyAccount = address(0x2);
smv2ExecuteSelector = IAccount.execute.selector;

// params
// validateSessionParams params
destinationContract = smv2ProxyAccount;
callValue = 0;
funcCallData = abi.encode(smv2ExecuteSelector, bytes4(""));
funcCallData = abi.encode(smv2ExecuteSelector, bytes32(""));
sessionKeyData =
abi.encode(sessionKey, smv2ProxyAccount, smv2ExecuteSelector);
callSpecificData = "";

// validateSessionUserOp params
op.callData = abi.encodeWithSelector(
EXECUTE_SELECTOR, destinationContract, callValue, funcCallData
);
userOpHash = userOpSignature.hashUserOperation(op);
sessionKeySignature =
userOpSignature.getUserOperationSignature(op, signerPrivateKey);
}
}

Expand Down Expand Up @@ -158,22 +193,133 @@ contract ValidateSessionParams is SMv2SessionValidationModuleTest {

contract ValidateSessionUserOp is SMv2SessionValidationModuleTest {
function test_validateSessionUserOp() public {
assertTrue(false);
bool isValid = smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, sessionKeySignature
);

assertTrue(isValid);
}

function test_validateSessionUserOp_op_invalid() public {
assertTrue(false);
function test_validateSessionUserOp_op_callData_invalid() public {
bytes4 invalidSelector = bytes4("");
op.callData = abi.encodeWithSelector(
invalidSelector, smv2ProxyAccount, callValue, funcCallData
);

vm.expectRevert(
abi.encodeWithSelector(
SMv2SessionValidationModule.InvalidSelector.selector
)
);

smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, sessionKeySignature
);

destinationContract = address(0);
op.callData = abi.encodeWithSelector(
EXECUTE_SELECTOR, destinationContract, callValue, funcCallData
);

vm.expectRevert(
abi.encodeWithSelector(
SMv2SessionValidationModule.InvalidDestinationContract.selector
)
);

smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, sessionKeySignature
);

callValue = 1;
destinationContract = smv2ProxyAccount;
op.callData = abi.encodeWithSelector(
EXECUTE_SELECTOR, destinationContract, callValue, funcCallData
);

vm.expectRevert(
abi.encodeWithSelector(
SMv2SessionValidationModule.InvalidCallValue.selector
)
);

smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, sessionKeySignature
);

callValue = 0;
funcCallData = abi.encode(bytes4(""), bytes4(""));
op.callData = abi.encodeWithSelector(
EXECUTE_SELECTOR, destinationContract, callValue, funcCallData
);

vm.expectRevert(
abi.encodeWithSelector(
SMv2SessionValidationModule.InvalidSMv2Selector.selector
)
);

smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, sessionKeySignature
);
}

function test_validateSessionUserOp_userOpHash_invalid() public {
assertTrue(false);
bytes32 invalidUserOpHash = bytes32("");
bool isValid = smv2SessionValidationModule.validateSessionUserOp(
op, invalidUserOpHash, sessionKeyData, sessionKeySignature
);

assertFalse(isValid);
}

function test_validateSessionUserOp_sessionKeyData_invalid() public {
assertTrue(false);
address invalidSessionKey = address(0);
sessionKeyData =
abi.encode(invalidSessionKey, smv2ProxyAccount, smv2ExecuteSelector);

bool isValid = smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, sessionKeySignature
);

assertFalse(isValid);

address invalidSmv2ProxyAccount = address(0);
sessionKeyData =
abi.encode(sessionKey, invalidSmv2ProxyAccount, smv2ExecuteSelector);

vm.expectRevert(
abi.encodeWithSelector(
SMv2SessionValidationModule.InvalidDestinationContract.selector
)
);

smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, sessionKeySignature
);

bytes4 invalidSmv2ExecuteSelector = bytes4("");
sessionKeyData =
abi.encode(sessionKey, smv2ProxyAccount, invalidSmv2ExecuteSelector);

vm.expectRevert(
abi.encodeWithSelector(
SMv2SessionValidationModule.InvalidSMv2Selector.selector
)
);

smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, sessionKeySignature
);
}

function test_validateSessionUserOp_sessionKeySignature_invalid() public {
assertTrue(false);
bytes memory invalidSessionKeySignature =
userOpSignature.getUserOperationSignature(op, bad_signerPrivateKey);
bool isValid = smv2SessionValidationModule.validateSessionUserOp(
op, userOpHash, sessionKeyData, invalidSessionKeySignature
);

assertFalse(isValid);
}
}
44 changes: 11 additions & 33 deletions test/SMv3SessionValidationModule.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,27 @@ contract SMv3SessionValidationModuleTest is Bootstrap {
}

contract ValidateSessionParams is SMv3SessionValidationModuleTest {
function test_validateSessionParams() public {
assertTrue(false);
}
function test_validateSessionParams() public {}

function test_validateSessionParams_destinationContract() public {
assertTrue(false);
}
function test_validateSessionParams_destinationContract() public {}

function test_validateSessionParams_callValue() public {
assertTrue(false);
}
function test_validateSessionParams_callValue() public {}

function test_validateSessionParams_funcCallData() public {
assertTrue(false);
}
function test_validateSessionParams_funcCallData() public {}

function test_validateSessionParams_sessionKeyData() public {
assertTrue(false);
}
function test_validateSessionParams_sessionKeyData() public {}

function test_validateSessionParams_callSpecificData() public {
assertTrue(false);
}
function test_validateSessionParams_callSpecificData() public {}
}

contract ValidateSessionUserOp is SMv3SessionValidationModuleTest {
function test_validateSessionUserOp() public {
assertTrue(false);
}
function test_validateSessionUserOp() public {}

function test_validateSessionUserOp_op() public {
assertTrue(false);
}
function test_validateSessionUserOp_op() public {}

function test_validateSessionUserOp_userOpHash() public {
assertTrue(false);
}
function test_validateSessionUserOp_userOpHash() public {}

function test_validateSessionUserOp_sessionKeyData() public {
assertTrue(false);
}
function test_validateSessionUserOp_sessionKeyData() public {}

function test_validateSessionUserOp_sessionKeySignature() public {
assertTrue(false);
}
function test_validateSessionUserOp_sessionKeySignature() public {}
}
36 changes: 36 additions & 0 deletions test/utils/UserOperationSignature.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.18;

import {
UserOperation,
UserOperationLib
} from "src/biconomy/interfaces/UserOperation.sol";
import {ECDSA} from "src/openzeppelin/ECDSA.sol";
import {Vm} from "lib/forge-std/src/Vm.sol";

contract UserOperationSignature {
using ECDSA for bytes32;
using UserOperationLib for UserOperation;

Vm private constant vm =
Vm(address(uint160(uint256(keccak256("hevm cheat code")))));

function getUserOperationSignature(
UserOperation calldata op,
uint256 privateKey
) public returns (bytes memory sig) {
bytes32 hash = hashUserOperation(op).toEthSignedMessageHash();

(uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, hash);

return bytes.concat(r, s, bytes1(v));
}

function hashUserOperation(UserOperation calldata op)
public
pure
returns (bytes32)
{
return op.hash();
}
}

0 comments on commit 00f862b

Please sign in to comment.