t-isol 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,14 +10,17 @@ interface ITransferAuthorize {
10
10
  /// @param nonce unique nonce used by the authorization
11
11
  event AuthorizeUsed(address indexed authorizer, bytes32 indexed nonce);
12
12
 
13
- /// @notice Emitted when a transfer with authorization is executed
14
- event TransferWithAuthorize(address indexed from, address indexed to, uint256 value, uint256 timeMFG, uint256 timeEXP, bytes32 indexed nonce, bytes auth);
13
+ /// @notice Emitted when a transfer with authorization is executed
14
+ event TransferWithAuthorize(address indexed from, address indexed to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 indexed nonce);
15
15
 
16
16
  /// @notice Emitted when a transferFrom with authorization is executed
17
- event TransferFromWithAuthorize(address indexed from, address indexed to, uint256 value, uint256 timeMFG, uint256 timeEXP, bytes32 indexed nonce);
17
+ event TransferFromWithAuthorize(address indexed from, address indexed to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 indexed nonce);
18
+
19
+ /// @notice Emitted when a approve with authorization is executed
20
+ event ApproveWithAuthorize(address indexed from, address indexed to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 indexed nonce);
18
21
 
19
22
  /// @notice Emitted when a burn with authorization is executed
20
- event BurnWithAuthorize(address indexed from, uint256 value, uint256 timeMFG, uint256 timeEXP, bytes32 indexed nonce);
23
+ event BurnWithAuthorize(address indexed from, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 indexed nonce);
21
24
 
22
25
  /// @notice Returns whether a nonce has been used for a given authorizer
23
26
  /// @param authorizer the account that signed the authorization
@@ -33,31 +36,44 @@ interface ITransferAuthorize {
33
36
  address from,
34
37
  address to,
35
38
  uint256 value,
36
- uint256 timeMFG,
37
- uint256 timeEXP,
39
+ uint256 validAfter,
40
+ uint256 validBefore,
38
41
  bytes32 nonce,
39
- bytes calldata auth
42
+ bytes calldata signature
40
43
  ) external;
41
44
 
42
- /// @notice Execute a "transferFrom with authorization" - typically any relayer may submit
45
+ // ++
46
+ /// @notice Execute a "transfer with authorization" - typically any relayer may submit
43
47
  function transferFromWithAuthorize(
44
48
  address from,
45
49
  address to,
46
50
  uint256 value,
47
- uint256 timeMFG,
48
- uint256 timeEXP,
51
+ uint256 validAfter,
52
+ uint256 validBefore,
53
+ bytes32 nonce,
54
+ bytes calldata signature
55
+ ) external;
56
+
57
+ // ++
58
+ /// @notice Execute a "approve with authorization" - typically any relayer may submit
59
+ function approveWithAuthorize(
60
+ address from,
61
+ address to,
62
+ uint256 value,
63
+ uint256 validAfter,
64
+ uint256 validBefore,
49
65
  bytes32 nonce,
50
- bytes calldata auth
66
+ bytes calldata signature
51
67
  ) external;
52
68
 
53
- /// @notice Execute a "burn with authorization" - typically any relayer may submit
69
+ /// @notice Execute a "approve with authorization" - typically any relayer may submit
54
70
  function burnWithAuthorize(
55
71
  address from,
56
72
  // address to,
57
73
  uint256 value,
58
- uint256 timeMFG,
59
- uint256 timeEXP,
74
+ uint256 validAfter,
75
+ uint256 validBefore,
60
76
  bytes32 nonce,
61
- bytes calldata auth
77
+ bytes calldata signature
62
78
  ) external;
63
79
  }
@@ -7,22 +7,24 @@ import "./ITransferAuthorize.sol";
7
7
 
8
8
  /// @title TransferAuthorize
9
9
  /// @notice Abstract helper implementing EIP-712 verification and nonce tracking for off-chain signed authorizations
10
- /// @dev Implementations should call `_verifyX..` and `_useAuthorize` before performing state changes
10
+ /// @dev Implementations should call `_verify` and `_useAuthorize` before performing state changes
11
11
  abstract contract TransferAuthorize is ITransferAuthorize, EIP712 {
12
12
  using ECDSA for bytes32;
13
13
 
14
14
  /// @dev mapping to track used nonces per authorizer: authorizer => nonce => used
15
15
  mapping(address => mapping(bytes32 => bool)) private _authorizeState;
16
16
 
17
- /// @dev EIP-712 type hashes for the two supported authorization structures
18
17
  bytes32 public constant TRANSFER_TYPEHASH =
19
- keccak256("TransferWithAuthorize(address from, address to, uint256 value, uint256 timeMFG, uint256 timeEXP, bytes32 nonce)");
18
+ keccak256("TransferWithAuthorize(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)");
20
19
 
21
20
  bytes32 public constant TRANSFERFROM_TYPEHASH =
22
- keccak256("TransferFromWithAuthorize(address from, address to, uint256 value, uint256 timeMFG, uint256 timeEXP, bytes32 nonce)");
21
+ keccak256("TransferFromWithAuthorize(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)");
22
+
23
+ bytes32 public constant APPROVE_TYPEHASH =
24
+ keccak256("ApproveWithAuthorize(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)");
23
25
 
24
26
  bytes32 public constant BURN_TYPEHASH =
25
- keccak256("BurnWithAuthorize(address from, address to, uint256 value, uint256 timeMFG, uint256 timeEXP, bytes32 nonce)");
27
+ keccak256("BurnWithAuthorize(address from,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)");
26
28
 
27
29
  /// @param name EIP-712 domain name
28
30
  /// @param version EIP-712 domain version
@@ -50,82 +52,107 @@ abstract contract TransferAuthorize is ITransferAuthorize, EIP712 {
50
52
  emit AuthorizeUsed(authorizer, nonce);
51
53
  }
52
54
 
53
- /// @dev Verify an EIP-712 typed signature (auth) for TransferWithAuthorize and return the recovered signer
55
+ /// @dev Verify an EIP-712 typed signature for TransferWithAuthorize and return the recovered signer
54
56
  function _verifyTransfer(
55
57
  address from,
56
58
  address to,
57
59
  uint256 value,
58
- uint256 timeMFG,
59
- uint256 timeEXP,
60
+ uint256 validAfter,
61
+ uint256 validBefore,
60
62
  bytes32 nonce,
61
- bytes calldata auth
62
- ) internal returns (address signer) {
63
- require(block.timestamp >= timeMFG, "TransferAuthorize: timestamp");
64
- require(block.timestamp <= timeEXP, "TransferAuthorize: expired");
63
+ bytes calldata signature
64
+ ) internal view returns (address signer) {
65
+ require(block.timestamp >= validAfter, "TransferAuthorize: not yet valid");
66
+ require(block.timestamp <= validBefore, "TransferAuthorize: expired");
65
67
  bytes32 structHash = keccak256(
66
68
  abi.encode(
67
69
  TRANSFER_TYPEHASH,
68
70
  from,
69
71
  to,
70
72
  value,
71
- timeMFG,
72
- timeEXP,
73
+ validAfter,
74
+ validBefore,
73
75
  nonce
74
76
  )
75
77
  );
76
- signer = ECDSA.recover(_hashTypedDataV4(structHash), auth);
77
- emit TransferWithAuthorize(from, to, value, timeMFG, timeEXP, nonce, auth);
78
+ signer = ECDSA.recover(_hashTypedDataV4(structHash), signature);
78
79
  }
79
80
 
80
- /// @dev Verify an EIP-712 typed signature (auth) for TransferFromWithAuthorize and return the recovered signer
81
+ /// @dev Verify an EIP-712 typed signature for TransferFromWithAuthorize and return the recovered signer
81
82
  function _verifyTransferFrom(
82
83
  address from,
83
84
  address to,
84
85
  uint256 value,
85
- uint256 timeMFG,
86
- uint256 timeEXP,
86
+ uint256 validAfter,
87
+ uint256 validBefore,
87
88
  bytes32 nonce,
88
- bytes calldata auth
89
+ bytes calldata signature
89
90
  ) internal view returns (address signer) {
90
- require(block.timestamp >= timeMFG, "TransferAuthorize: not yet time");
91
- require(block.timestamp <= timeEXP, "TransferAuthorize: expired");
91
+ require(block.timestamp >= validAfter, "TransferAuthorize: not yet valid");
92
+ require(block.timestamp <= validBefore, "TransferAuthorize: expired");
92
93
  bytes32 structHash = keccak256(
93
94
  abi.encode(
94
95
  TRANSFERFROM_TYPEHASH,
95
96
  from,
96
97
  to,
97
98
  value,
98
- timeMFG,
99
- timeEXP,
99
+ validAfter,
100
+ validBefore,
101
+ nonce
102
+ )
103
+ );
104
+ signer = ECDSA.recover(_hashTypedDataV4(structHash), signature);
105
+ }
106
+
107
+ /// @dev Verify an EIP-712 typed signature for ApproveWithAuthorize and return the recovered signer
108
+ function _verifyApprove(
109
+ address from,
110
+ address to,
111
+ uint256 value,
112
+ uint256 validAfter,
113
+ uint256 validBefore,
114
+ bytes32 nonce,
115
+ bytes calldata signature
116
+ ) internal view returns (address signer) {
117
+ require(block.timestamp >= validAfter, "TransferAuthorize: not yet valid");
118
+ require(block.timestamp <= validBefore, "TransferAuthorize: expired");
119
+ bytes32 structHash = keccak256(
120
+ abi.encode(
121
+ APPROVE_TYPEHASH,
122
+ from,
123
+ to,
124
+ value,
125
+ validAfter,
126
+ validBefore,
100
127
  nonce
101
128
  )
102
129
  );
103
- signer = ECDSA.recover(_hashTypedDataV4(structHash), auth);
130
+ signer = ECDSA.recover(_hashTypedDataV4(structHash), signature);
104
131
  }
105
132
 
106
- /// @dev Verify an EIP-712 typed signature (auth) for BurnWithAuthorize and return the recovered signer
133
+ /// @dev Verify an EIP-712 typed signature for BurnWithAuthorize and return the recovered signer
107
134
  function _verifyBurn(
108
135
  address from,
109
136
  // address to,
110
137
  uint256 value,
111
- uint256 timeMFG,
112
- uint256 timeEXP,
138
+ uint256 validAfter,
139
+ uint256 validBefore,
113
140
  bytes32 nonce,
114
- bytes calldata auth
141
+ bytes calldata signature
115
142
  ) internal view returns (address signer) {
116
- require(block.timestamp >= timeMFG, "TransferAuthorize: not yet time");
117
- require(block.timestamp <= timeEXP, "TransferAuthorize: expired");
143
+ require(block.timestamp >= validAfter, "TransferAuthorize: not yet valid");
144
+ require(block.timestamp <= validBefore, "TransferAuthorize: expired");
118
145
  bytes32 structHash = keccak256(
119
146
  abi.encode(
120
147
  BURN_TYPEHASH,
121
148
  from,
122
149
  // to,
123
150
  value,
124
- timeMFG,
125
- timeEXP,
151
+ validAfter,
152
+ validBefore,
126
153
  nonce
127
154
  )
128
155
  );
129
- signer = ECDSA.recover(_hashTypedDataV4(structHash), auth);
156
+ signer = ECDSA.recover(_hashTypedDataV4(structHash), signature);
130
157
  }
131
158
  }
@@ -10,6 +10,7 @@ import "@openzeppelin/contracts/access/Ownable.sol";
10
10
  /// @notice ERC20 extension that supports EIP-712 based `transferWithAuthorize` and `receiveWithAuthorize` flows
11
11
  /// @dev `receiveWithAuthorize` restricts the caller to the `to` address (recipient submits the proof). `transferWithAuthorize` is open to relayers.
12
12
  abstract contract ERC20xTransferWithAuthorize is ERC20, TransferAuthorize, ReentrancyGuard, Ownable {
13
+
13
14
  constructor(
14
15
  string memory name,
15
16
  string memory symbol,
@@ -24,7 +25,7 @@ abstract contract ERC20xTransferWithAuthorize is ERC20, TransferAuthorize, Reent
24
25
  _mint(msg.sender, initialSupply * 10 ** decimals());
25
26
  }
26
27
 
27
- /// @notice Relayer-triggered transfer using an off-chain signature (auth) by `from`.
28
+ /// @notice Relayer-triggered transfer using an off-chain signature by `from`.
28
29
  /// @dev This allows anyone (a relayer) to submit the signed authorization on-chain.
29
30
  function transferWithAuthorize(
30
31
  address from,
@@ -33,7 +34,7 @@ abstract contract ERC20xTransferWithAuthorize is ERC20, TransferAuthorize, Reent
33
34
  uint256 validAfter,
34
35
  uint256 validBefore,
35
36
  bytes32 nonce,
36
- bytes calldata auth
37
+ bytes calldata signature
37
38
  ) external override nonReentrant {
38
39
  address signer = _verifyTransfer(
39
40
  from,
@@ -42,14 +43,15 @@ abstract contract ERC20xTransferWithAuthorize is ERC20, TransferAuthorize, Reent
42
43
  validAfter,
43
44
  validBefore,
44
45
  nonce,
45
- auth
46
+ signature
46
47
  );
47
- require(signer == from, "ERC20TransferAuthorize: invalid authorization signature");
48
+ require(signer == from, "ERC20TransferAuthorize: invalid signature");
48
49
  _useAuthorize(from, nonce);
49
50
  _transfer(from, to, value);
51
+ emit TransferWithAuthorize(from, to, value, validAfter, validBefore, nonce);
50
52
  }
51
53
 
52
- /// @notice Relayer-triggered transfer using an off-chain signature (auth) by `from`.
54
+ /// @notice Relayer-triggered transfer using an off-chain signature by `from`.
53
55
  /// @dev This allows anyone (a relayer) to submit the signed authorization on-chain.
54
56
  function transferFromWithAuthorize(
55
57
  address from,
@@ -58,7 +60,7 @@ abstract contract ERC20xTransferWithAuthorize is ERC20, TransferAuthorize, Reent
58
60
  uint256 validAfter,
59
61
  uint256 validBefore,
60
62
  bytes32 nonce,
61
- bytes calldata auth
63
+ bytes calldata signature
62
64
  ) external override nonReentrant {
63
65
  address signer = _verifyTransferFrom(
64
66
  from,
@@ -67,15 +69,40 @@ abstract contract ERC20xTransferWithAuthorize is ERC20, TransferAuthorize, Reent
67
69
  validAfter,
68
70
  validBefore,
69
71
  nonce,
70
- auth
72
+ signature
71
73
  );
72
- require(signer == from, "ERC20TransferAuthorize: invalid authorization signature");
74
+ require(signer == from, "ERC20TransferAuthorize: invalid signature");
73
75
  _useAuthorize(from, nonce);
74
76
  _spendAllowance(from, to, value);
75
77
  _transfer(from, to, value);
76
78
  }
77
79
 
78
- /// @notice Relayer-triggered transfer using an off-chain signature (auth) by `from`.
80
+ /// @notice Relayer-triggered transfer using an off-chain signature by `from`.
81
+ /// @dev This allows anyone (a relayer) to submit the signed authorization on-chain.
82
+ function approveWithAuthorize(
83
+ address from,
84
+ address to,
85
+ uint256 value,
86
+ uint256 validAfter,
87
+ uint256 validBefore,
88
+ bytes32 nonce,
89
+ bytes calldata signature
90
+ ) external override nonReentrant {
91
+ address signer = _verifyApprove(
92
+ from,
93
+ to,
94
+ value,
95
+ validAfter,
96
+ validBefore,
97
+ nonce,
98
+ signature
99
+ );
100
+ require(signer == from, "ERC20TransferAuthorize: invalid signature");
101
+ _useAuthorize(from, nonce);
102
+ _approve(from, to, value);
103
+ }
104
+
105
+ /// @notice Relayer-triggered transfer using an off-chain signature by `from`.
79
106
  /// @dev This allows anyone (a relayer) to submit the signed authorization on-chain.
80
107
  function burnWithAuthorize(
81
108
  address from,
@@ -84,7 +111,7 @@ abstract contract ERC20xTransferWithAuthorize is ERC20, TransferAuthorize, Reent
84
111
  uint256 validAfter,
85
112
  uint256 validBefore,
86
113
  bytes32 nonce,
87
- bytes calldata auth
114
+ bytes calldata signature
88
115
  ) external override nonReentrant {
89
116
  address signer = _verifyBurn(
90
117
  from,
@@ -93,9 +120,9 @@ abstract contract ERC20xTransferWithAuthorize is ERC20, TransferAuthorize, Reent
93
120
  validAfter,
94
121
  validBefore,
95
122
  nonce,
96
- auth
123
+ signature
97
124
  );
98
- require(signer == from, "ERC20TransferAuthorize: invalid authorization signature");
125
+ require(signer == from, "ERC20TransferAuthorize: invalid signature");
99
126
  _useAuthorize(from, nonce);
100
127
  _burn(from, value);
101
128
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "t-isol",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "devDependencies": {