Skip to content

Commit

Permalink
♻️ Add sanitizer for multicall
Browse files Browse the repository at this point in the history
  • Loading branch information
insulineru committed Feb 8, 2024
1 parent fb9eea5 commit 9539463
Showing 1 changed file with 53 additions and 18 deletions.
71 changes: 53 additions & 18 deletions src/SMv3SessionValidationModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,17 @@ contract SMv3SessionValidationModule is ISessionValidationModule {
bytes4 funcSelector = bytes4(_funcCallData[0:4]);

// sanitize the selector; ensure it is a valid selector
// that can be called on the smv3Engine)
_sanitizeSelector(funcSelector);
// that can be called on the smv3Engine
if (funcSelector == IEngine.multicall.selector) {
_decomposeAndSanitizeMulticallData(_funcCallData, callValue);
} else {
_sanitizeSelector(funcSelector);

// sanitize the call value; ensure it is zero unless calling
// IEngine.depositEth or EIP7412.fulfillOracleQuery
_sanitizeCallValue(funcSelector, callValue);
}

// sanitize the call value; ensure it is zero unless calling
// IEngine.depositEth or EIP7412.fulfillOracleQuery
_sanitizeCallValue(funcSelector, callValue);

return sessionKey;
}
Expand Down Expand Up @@ -114,10 +119,6 @@ contract SMv3SessionValidationModule is ISessionValidationModule {
// that can be called on the smv3Engine)
_sanitizeSelector(funcSelector);

// sanitize the call value; ensure it is zero unless calling
// IEngine.depositEth or EIP7412.fulfillOracleQuery
_sanitizeCallValue(funcSelector, callValue);

/// @dev this method of signature validation is out-of-date
/// see https://github.com/OpenZeppelin/openzeppelin-sdk/blob/7d96de7248ae2e7e81a743513ccc617a2e6bba21/packages/lib/contracts/cryptography/ECDSA.sol#L6
return ECDSA.recover(
Expand All @@ -135,30 +136,64 @@ contract SMv3SessionValidationModule is ISessionValidationModule {
&& _selector != IEngine.commitOrder.selector
&& _selector != IEngine.invalidateUnorderedNonces.selector
&& _selector != EIP7412.fulfillOracleQuery.selector
&& _selector != IEngine.depositEth.selector
&& _selector != IEngine.withdrawEth.selector
) {
revert InvalidSMv3Selector();
}
}

/// @notice sanitize the call value to ensure it is zero unless calling
/// IEngine.depositEth or EIP7412.fulfillOracleQuery
/// @notice sanitize the call value to ensure it is zero unless calling EIP7412.fulfillOracleQuery
/// @param _selector the selector to sanitize
/// @dev will revert if the call value is not valid
function _sanitizeCallValue(bytes4 _selector, uint256 _callValue)
internal
pure
{
if (
_selector == IEngine.depositEth.selector
|| _selector == EIP7412.fulfillOracleQuery.selector
_selector == EIP7412.fulfillOracleQuery.selector
) {
if (_callValue == 0) {
if (_callValue != 0) {
revert InvalidCallValue();
}
} else if (_callValue != 0) {
revert InvalidCallValue();
}
}

/**
* @dev Processes and validates multicall data arrays, ensuring each call's selector is permitted and checks if
* `EIP7412.fulfillOracleQuery` is called, then validates the call value accordingly.
*
*
* @param _callData the data for the call. is parsed inside the SVM
* @param _callValue value to be sent with the call
*
* Note: This function does not return a value but may revert if it encounters an invalid function selector
* within the multicall data or if the call value does not comply with the prescribed validation rules,
* ensuring the contract's operational parameters are strictly adhered to.
*/
function _decomposeAndSanitizeMulticallData(
bytes calldata _callData,
uint256 _callValue
)
internal
pure
{
bytes[] memory multicallData = abi.decode(_callData[4:], (bytes[]));

bool hasFulfillOracleQueryCall = false;

for (uint256 i = 0; i < multicallData.length; i++) {
bytes4 selector = bytes4(abi.encodePacked(multicallData[i])[:4]);

_sanitizeSelector(selector);

if (selector == EIP7412.fulfillOracleQuery.selector) {
hasFulfillOracleQueryCall = true;
}
}

if (hasFulfillOracleQueryCall) {
_sanitizeCallValue(EIP7412.fulfillOracleQuery.selector, _callValue);
} else {
_sanitizeCallValue(IEngine.multicall.selector, _callValue);
}
}
}

0 comments on commit 9539463

Please sign in to comment.