Skip to content

Commit

Permalink
temporary replacement for git diff generation
Browse files Browse the repository at this point in the history
  • Loading branch information
JaredBorders committed Oct 3, 2023
1 parent d0ce77b commit e7cbbb0
Showing 1 changed file with 58 additions and 33 deletions.
91 changes: 58 additions & 33 deletions src/SMv2SessionValidationModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ import {
import {ECDSA} from "src/openzeppelin/ECDSA.sol";

/**
* @title Kwenta Smart Margin v2 Session Validation Module for Biconomy Smart Accounts.
* @dev Validates userOps for `Account.execute()` using a session key signature.
* @title Kwenta Smart Margin v3 Session Validation Module for Biconomy Smart Accounts.
* @dev Validates userOps for
* `IEngine.modifyCollateral()`
* `IEngine.commitOrder()`
* `IEngine.invalidateUnorderedNonces()`
* `IERC7412.fulfillOracleQuery()`
* using a session key signature.
* @author Fil Makarov - <[email protected]>
* @author JaredBorders ([email protected])
*/
contract SMv2SessionValidationModule is ISessionValidationModule {
contract SMv3SessionValidationModule is ISessionValidationModule {
error InvalidSelector();
error InvalidSMv2Selector();
error InvalidSMv3Selector();
error InvalidDestinationContract();
error InvalidCallValue();

Expand All @@ -36,32 +41,36 @@ contract SMv2SessionValidationModule is ISessionValidationModule {
) external virtual override returns (address) {
(
address sessionKey,
address smv2ProxyAccount,
bytes4 smv2ExecuteSelector
) = abi.decode(_sessionKeyData, (address, address, bytes4));

/// @dev ensure destinationContract is the SMv2ProxyAccount
if (destinationContract != smv2ProxyAccount) {
address smv3Engine,
bytes4 smv3ModifyCollateralSelector,
bytes4 smv3CommitOrderSelector,
bytes4 smv3InvalidateUnorderedNoncesSelector,
bytes4 smv3FulfillOracleQuerySelector
) = abi.decode(
_sessionKeyData, (address, address, bytes4, bytes4, bytes4, bytes4)
);

/// @dev ensure destinationContract is the smv3Engine
if (destinationContract != smv3Engine) {
revert InvalidDestinationContract();
}

/// @dev ensure the function selector is the `SmartAccount.execute` selector
if (bytes4(_funcCallData[0:4]) != smv2ExecuteSelector) {
revert InvalidSMv2Selector();
/// @dev ensure the function selector is the a valid selector
bytes4 funcSelector = bytes4(_funcCallData[0:4]);
if (
funcSelector != smv3ModifyCollateralSelector
&& funcSelector != smv3CommitOrderSelector
&& funcSelector != smv3InvalidateUnorderedNoncesSelector
&& funcSelector != smv3FulfillOracleQuerySelector
) {
revert InvalidSMv3Selector();
}

/// @dev ensure call value is zero
if (callValue != 0) {
revert InvalidCallValue();
}

// (IAccount.Command[] memory _commands, bytes[] memory _inputs) = abi.decode(
// _funcCallData[4:],
// (IAccount.Command[], bytes[])
// );

/// @custom:add-param-validation-here-if-needed

return sessionKey;
}

Expand Down Expand Up @@ -89,21 +98,18 @@ contract SMv2SessionValidationModule is ISessionValidationModule {
revert InvalidSelector();
}

(
address sessionKey,
address smv2ProxyAccount,
bytes4 smv2ExecuteSelector
) = abi.decode(_sessionKeyData, (address, address, bytes4));
(address sessionKey, address smv3Engine,,,,) = abi.decode(
_sessionKeyData, (address, address, bytes4, bytes4, bytes4, bytes4)
);

{
// we expect _op.callData to be `SmartAccount.execute(to, value, calldata)` calldata
(address destinationContract, uint256 callValue,) = abi.decode(
_op.callData[4:], // skip selector
(address, uint256, bytes)
);

/// @dev ensure destinationContract is the SMv2ProxyAccount
if (destinationContract != smv2ProxyAccount) {
/// @dev ensure destinationContract is the smv3Engine
if (destinationContract != smv3Engine) {
revert InvalidDestinationContract();
}

Expand All @@ -114,19 +120,38 @@ contract SMv2SessionValidationModule is ISessionValidationModule {
}

// working with userOp.callData
// check if the call is conforms to `IAccount.execute`
// check if the call is conforms to valid smv3Engine selectors
bytes calldata data;
{
uint256 offset = uint256(bytes32(_op.callData[4 + 64:4 + 96]));
uint256 length =
uint256(bytes32(_op.callData[4 + offset:4 + offset + 32]));
// we expect data to be the `IAccount.execute(Command[] _commands, bytes[] _inputs)` calldata
data = _op.callData[4 + offset + 32:4 + offset + 32 + length];
}

/// @dev ensure the function selector is the smv2ExecuteSelector selector
if (bytes4(data[0:4]) != smv2ExecuteSelector) {
revert InvalidSMv2Selector();
{
(
,
,
bytes4 smv3ModifyCollateralSelector,
bytes4 smv3CommitOrderSelector,
bytes4 smv3InvalidateUnorderedNoncesSelector,
bytes4 smv3FulfillOracleQuerySelector
) = abi.decode(
_sessionKeyData,
(address, address, bytes4, bytes4, bytes4, bytes4)
);

/// @dev ensure the function selector is the a valid selector
bytes4 funcSelector = bytes4(data[0:4]);
if (
funcSelector != smv3ModifyCollateralSelector
&& funcSelector != smv3CommitOrderSelector
&& funcSelector != smv3InvalidateUnorderedNoncesSelector
&& funcSelector != smv3FulfillOracleQuerySelector
) {
revert InvalidSMv3Selector();
}
}

/// @dev this method of signature validation is out-of-date
Expand Down

0 comments on commit e7cbbb0

Please sign in to comment.