SignMessagePolicy contract - #26
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a new SignMessagePolicy contract that enforces strict validation rules for signing messages through Safe wallets. The policy ensures only pre-approved EIP-712 structured data (identified by domain and primary type hashes) can be signed.
Key Changes:
- Implements a whitelist-based policy requiring domain and type hash approval per Safe
- Validates that message hashes match the expected EIP-712 structured data format
- Provides configuration interface to set allowed domain/type hash combinations
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| require( | ||
| messageToSign.length == 32 && bytes32(abi.decode(messageToSign, (bytes32))) == messageHash, |
There was a problem hiding this comment.
The double decoding of messageToSign is incorrect. First abi.decode(data[4:], (bytes)) decodes to bytes, then abi.decode(messageToSign, (bytes32)) tries to ABI-decode those bytes. If messageToSign is exactly 32 bytes representing a hash, it should be cast directly with bytes32(messageToSign) using inline assembly or by copying the bytes, not double-decoded.
| require( | |
| messageToSign.length == 32 && bytes32(abi.decode(messageToSign, (bytes32))) == messageHash, | |
| bytes32 messageToSignHash; | |
| assembly { | |
| messageToSignHash := mload(add(messageToSign, 32)) | |
| } | |
| require( | |
| messageToSign.length == 32 && messageToSignHash == messageHash, |
| * @inheritdoc IPolicy | ||
| * @dev This policy requires configuration with allowed domain and type hashes. | ||
| */ | ||
| function configure(address safe, AccessSelector.T selector, bytes memory data) external override returns (bool) { |
There was a problem hiding this comment.
The configure function lacks access control. Any caller can add allowed domain/type hashes for any Safe address. This should verify that msg.sender is authorized to configure the policy for the given Safe, or it should be restricted to the Safe itself or a designated administrator.
| function configure(address safe, AccessSelector.T selector, bytes memory data) external override returns (bool) { | |
| function configure(address safe, AccessSelector.T selector, bytes memory data) external override returns (bool) { | |
| require(msg.sender == safe, "Not authorized"); |
| for (uint256 i = 0; i < domains.length; i++) { | ||
| _domains[safe][domains[i].domainHash][domains[i].primaryTypeHash] = true; | ||
| } |
There was a problem hiding this comment.
The configuration logic only allows adding domain/type hash pairs but provides no mechanism to revoke or remove them. Once a domain/type combination is approved, it cannot be disabled. Consider adding a boolean field to SignatureDomain struct or a separate removal function to support policy updates.
| */ | ||
| function configure(address safe, AccessSelector.T selector, bytes memory data) external override returns (bool) { | ||
| SignatureDomain[] memory domains = abi.decode(data, (SignatureDomain[])); | ||
| for (uint256 i = 0; i < domains.length; i++) { |
There was a problem hiding this comment.
Unbounded loop over domains.length could exceed block gas limits if a large array is passed. Consider adding a reasonable upper limit check or implementing pagination for configuring large numbers of domain/type pairs.
686bae2 to
19295ed
Compare
|
No tests? |
TLDR
Created a
signMessagepolicy based on a Twitter reply: https://x.com/yodl_meister/status/1980580069480493279To Do:
LLM Description
This pull request introduces a new policy contract,
SignMessagePolicy, which enforces strict rules for signing messages in the system. The contract ensures that only messages with explicitly allowed domain and type hashes can be signed, and validates the message hash before permitting the operation. The implementation includes error handling and configuration logic for managing allowed domains and types.New policy contract for signing messages:
SignMessagePolicycontract incontracts/policies/SignMessagePolicy.sol, enforcing that onlysignMessageoperations with approved domain and type hashes are allowed.