-
Notifications
You must be signed in to change notification settings - Fork 5
/
RelayingUtils.sol
79 lines (62 loc) · 2.63 KB
/
RelayingUtils.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
pragma solidity ^0.6.0;
// SPDX-License-Identifier: ISC
import "@openzeppelin/contracts/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
library RelayingUtils {
using ECDSA for ECDSA;
// This is similar to the OpenZeppelin Counters.Counter, but backed by a uint32
// it also never decrements
struct NonceCounter {
uint32 _value;
}
function current(NonceCounter storage nonceCounter) internal view returns (uint32) {
return nonceCounter._value;
}
function increment(NonceCounter storage nonceCounter) internal {
// Much like with OZ's Counter, we don't need to overflow-check when adding 1
nonceCounter._value += 1;
}
// Wrap a map address => counter to capture semantics of manipulating nonces
struct NonceMap {
mapping (address => NonceCounter) _nonces;
}
// Get the current (expected) nonce for address `a`
function current(NonceMap storage nm, address a) internal view returns (uint32) {
return current(nm._nonces[a]);
}
// Increment the expected nonce for address `a`
function increment(NonceMap storage nm, address a) internal {
increment(nm._nonces[a]);
}
struct RelayedMessage {
uint32 nonce;
uint256 feeAmount;
bytes tokenData;
}
function messageHash(RelayedMessage memory message) internal pure returns (bytes32) {
bytes memory packedMessage = abi.encode(message.nonce, message.feeAmount, message.tokenData);
return keccak256(packedMessage);
}
function signingHash(RelayedMessage memory message) internal pure returns (bytes32) {
return ECDSA.toEthSignedMessageHash(messageHash(message));
}
function recoverSigner(RelayedMessage memory message, bytes memory signature) internal pure returns (address) {
return ECDSA.recover(signingHash(message), signature);
}
struct RelayedTransfer {
uint32 nonce;
uint256 feeAmount;
uint256 tokenID;
address destination;
}
function messageHash(RelayedTransfer memory transfer) internal pure returns (bytes32) {
bytes memory packedMessage = abi.encode(transfer.nonce, transfer.feeAmount, transfer.tokenID, transfer.destination);
return keccak256(packedMessage);
}
function signingHash(RelayedTransfer memory transfer) internal pure returns (bytes32) {
return ECDSA.toEthSignedMessageHash(messageHash(transfer));
}
function recoverSigner(RelayedTransfer memory transfer, bytes memory signature) internal pure returns (address) {
return ECDSA.recover(signingHash(transfer), signature);
}
}