Reputation: 11
I am getting signature by using Wagmi's signTypedDataAsync function as below.
takerOrder.signature = await signTypedDataAsync({
types: {
Order: [
{name: 'salt', type: 'uint256'},
{name: 'maker', type: 'address'},
{name: 'signer', type: 'address'},
{name: 'taker', type: 'address'},
{name: 'tokenId', type: 'uint256'},
{name: 'makerAmount', type: 'uint256'},
{name: 'takerAmount', type: 'uint256'},
{name: 'expiration', type: 'uint256'},
{name: 'nonce', type: 'uint256'},
{name: 'feeRateBps', type: 'uint256'},
{name: 'side', type: 'uint8'},
{name: 'signatureType', type: 'uint8'}
]
},
primaryType: 'Order',
message: takerOrder
});
And I want to verify the signature in Solidity, but failed.
Here is OrderStruct.sol file content.
// SPDX-License-Identifier: MIT
pragma solidity <0.9.0;
bytes32 constant ORDER_TYPEHASH = keccak256(
"Order(uint256 salt,address maker,address signer,address taker,uint256 tokenId,uint256 makerAmount,uint256 takerAmount,uint256 expiration,uint256 nonce,uint256 feeRateBps,uint8 side,uint8 signatureType)"
);
struct Order {
/// @notice Unique salt to ensure entropy
uint256 salt;
/// @notice Maker of the order, i.e the source of funds for the order
address maker;
/// @notice Signer of the order
address signer;
/// @notice Address of the order taker. The zero address is used to indicate a public order
address taker;
/// @notice Token Id of the CTF ERC1155 asset to be bought or sold
/// If BUY, this is the tokenId of the asset to be bought, i.e the makerAssetId
/// If SELL, this is the tokenId of the asset to be sold, i.e the takerAssetId
uint256 tokenId;
/// @notice Maker amount, i.e the maximum amount of tokens to be sold
uint256 makerAmount;
/// @notice Taker amount, i.e the minimum amount of tokens to be received
uint256 takerAmount;
/// @notice Timestamp after which the order is expired
uint256 expiration;
/// @notice Nonce used for onchain cancellations
uint256 nonce;
/// @notice Fee rate, in basis points, charged to the order maker, charged on proceeds
uint256 feeRateBps;
/// @notice The side of the order: BUY or SELL
Side side;
/// @notice Signature type used by the Order: EOA, POLY_PROXY or POLY_GNOSIS_SAFE
SignatureType signatureType;
/// @notice The order signature
bytes signature;
}
enum SignatureType
// 0: ECDSA EIP712 signatures signed by EOAs
{
EOA,
// 1: EIP712 signatures signed by EOAs that own Polymarket Proxy wallets
POLY_PROXY,
// 2: EIP712 signatures signed by EOAs that own Polymarket Gnosis safes
POLY_GNOSIS_SAFE
}
enum Side
// 0: buy
{
BUY,
// 1: sell
SELL
}
enum MatchType
// 0: buy vs sell
{
COMPLEMENTARY,
// 1: both buys
MINT,
// 2: both sells
MERGE
}
struct OrderStatus {
bool isFilledOrCancelled;
uint256 remaining;
}
And here is Hashing.sol file content.
// SPDX-License-Identifier: MIT
pragma solidity <0.9.0;
import { EIP712 } from "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol";
import { IHashing } from "../interfaces/IHashing.sol";
import { Order, ORDER_TYPEHASH } from "../libraries/OrderStructs.sol";
abstract contract Hashing is EIP712, IHashing {
bytes32 public immutable domainSeparator;
constructor(string memory name, string memory version) EIP712(name, version) {
domainSeparator = _domainSeparatorV4();
}
/// @notice Computes the hash for an order
/// @param order - The order to be hashed
function hashOrder(Order memory order) public view override returns (bytes32) {
return _hashTypedDataV4(
keccak256(
abi.encode(
ORDER_TYPEHASH,
order.salt,
order.maker,
order.signer,
order.taker,
order.tokenId,
order.makerAmount,
order.takerAmount,
order.expiration,
order.nonce,
order.feeRateBps,
order.side,
order.signatureType
)
)
);
}
}
Here is Verifier.sol file content.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
/// @title Signatures
/// @notice Maintains logic that defines the various signature types and validates them
contract Verifier {
/// @notice Verifies an ECDSA signature
/// @dev Reverts if the signature length is invalid or the recovered signer is the zero address
/// @param signer - Address of the signer
/// @param structHash - The hash of the struct being verified
/// @param signature - The signature to be verified
function verifyECDSASignature(address signer, bytes32 structHash, bytes memory signature)
external
pure
returns (bool)
{
return ECDSA.recover(structHash, signature) == signer;
}
}
After getting hash value of order by using hashOrder function, I invoked verifyECDSASignature function with order's signer and signature, and hash value as structHash, but it returns false, and signer is really not the same with ECDSA.recover(structHash, signature) result value. I really have no idea how to connect wagmi's signTypedDataAsync to ECDSA.recover. Would you please teach me how to do it?
Upvotes: 1
Views: 168