Support EIP-1271 Signature Types
Closed this issue · 1 comments
Summary
Add support for two new order signature types to orders:
EIP1271Wallet
EIP1271OrderWallet
.
Respectively, these new signature are analagous to OrderValidator
(proposed in #33) and the Wallet
signature type introduced in 2.0
. However, their callbacks implement the EIP-1271 standard, which takes an arbitrary bytes
payload for the data that is signed.
Motivation
EIP-1271 provides a more flexible way for wallets to validate arbitrary data (not just Orders
). A wallet implementing this standard could use the same callback/function to parse different types of data and validate signatures based on some context.
Status
Branch: 3.0
- #1885 in review: Initial implementation.
Specification
Restrictions
- Callbacks will be called via
staticcall()
. If the contract attempts to update state during call, the validation will fail.
Encoding of data
EIP1271Wallet
data
is simply the 32-byte hash placed in abytes
array.
EIP1271OrderWallet
data
is the abi-encodedOrder
. E.g,abi.encode(order)
.
The callback contract
In both cases, the callback contract is determined by the order maker.
Implementation
Contracts validating the EIP1271Wallet
and EIP1271OrderWallet
signature types must expose an isValidSignature
function with the following signature:
function isValidSignature(
bytes memory data,
bytes memory signature
)
public
view
returns (bytes4 magicBytes);
Example
Here is a trivial implementation of EIP1271OrderWallet
:
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
contract MyEIP1271Wallet {
bytes4 constant public EIP1271_MAGIC_VALUE = 0x20c13b0b;
address constant public AUTHORIZED_MAKER = 0x645b6e008c70efa2e5d9ac897740a21dc59eda0e;
// 0x order structure
struct Order {
address makerAddress;
address takerAddress;
address feeRecipientAddress;
address senderAddress;
uint256 makerAssetAmount;
uint256 takerAssetAmount;
uint256 makerFee;
uint256 takerFee;
uint256 expirationTimeSeconds;
uint256 salt;
bytes makerAssetData;
bytes takerAssetData;
bytes makerFeeAssetData;
bytes takerFeeAssetData;
}
/// @dev EIP1271 wallet callback.
/// @param data The ABI-encoded `Order`.
/// @param signature Signature data for the order.
/// @return magicValue `EIP1271_MAGIC_VALUE` if valid.
function isValidSignature(
bytes memory data
bytes memory signature
)
public
view
returns (bytes4 magicValue)
{
// Decode the order.
Order memory order = abi.decode(data, (Order));
if (order.makerAddress == AUTHORIZED_MAKER) {
magicValue = EIP1271_MAGIC_VALUE;
}
}
}
Retiring since we're consolidating signature types with the EIP-1271 pattern in #33