Skip to content

Commit

Permalink
chore: introducing abstracted EIP712 messaging formating to comply wi…
Browse files Browse the repository at this point in the history
…th offchain formatting"
  • Loading branch information
RonTuretzky committed Dec 27, 2024
1 parent ee548c4 commit 8c31b97
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
18 changes: 18 additions & 0 deletions src/contracts/LayerSDK.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
pragma solidity 0.8.23;

import {ECDSAStakeRegistry} from '@eigenlayer-middleware/unaudited/ECDSAStakeRegistry.sol';

import {ECDSAUpgradeable} from '@openzeppelin-upgrades/contracts/utils/cryptography/ECDSAUpgradeable.sol';
import {ILayerSDK} from 'interfaces/ILayerSDK.sol';

contract LayerSDK is ILayerSDK {
using ECDSAUpgradeable for bytes32;

/// @notice bytes4(keccak256("isValidSignature(bytes32,bytes)")
bytes4 internal constant _ERC1271_SIGNATURE = 0x1626ba7e;

Expand Down Expand Up @@ -36,4 +40,18 @@ contract LayerSDK is ILayerSDK {
function _validateLayerTask(Task memory _task) internal view returns (bool _isValid) {
_isValid = (_ERC1271_SIGNATURE == STAKE_REGISTRY.isValidSignature(_task.dataHash, _task.signatureData));
}

/**
* @notice Validates the format of an EIP-712 signed message
* @param _messageHash The hash of the message
* @param _message The message to verify is hashed according to EIP-712
* @return _isValid Whether the message hash represents the message according to EIP-712
*/
function _validateEthSignedMessage(
bytes32 _messageHash,
string memory _message
) internal pure returns (bool _isValid) {
bytes32 messageHash = keccak256(abi.encodePacked(_message));
_isValid = _messageHash == messageHash.toEthSignedMessageHash();
}
}
18 changes: 11 additions & 7 deletions src/example-contracts/OffchainMessageConsumer.sol
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {LayerSDK} from 'contracts/LayerSDK.sol';
import {ILayerSDK, LayerSDK} from 'contracts/LayerSDK.sol';

contract OffchainMessageConsumer is LayerSDK {
/// @notice The expected hash of the offchain message
bytes32 private constant _MESSAGE_HASH = keccak256(abi.encode('Hello, World!'));
/// @notice The expected content of the offchain message
string private constant _MESSAGE = 'Hello, World!';

/// @notice Initializer
constructor(address _stakeRegistry) LayerSDK(_stakeRegistry) {}

/**
* @notice Validates a layer task from off-chain AVS operator
* @param _offchainData The off-chain data to verify
* @param _task The off-chain data to verify
* @return _isValid Whether the task is valid
*/
function validateOffchainMessage(string calldata _offchainData) external view returns (bool _isValid) {
Task memory _task = Task({dataHash: bytes32(bytes(_offchainData[0:32])), signatureData: bytes(_offchainData[32:])});
_isValid = _validateLayerTask(_task) && _task.dataHash == _MESSAGE_HASH;
function validateOffchainMessage(ILayerSDK.Task calldata _task)
external
view
onlyValidLayerTask(_task)
returns (bool _isValid)
{
_isValid = _validateEthSignedMessage(_task.dataHash, _MESSAGE);
}
}

0 comments on commit 8c31b97

Please sign in to comment.