@1inch/solidity-utils 2.0.11-test5 → 2.0.12
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.
- package/contracts/EthReceiver.sol +3 -1
- package/contracts/GasChecker.sol +4 -8
- package/contracts/OnlyWethReceiver.sol +20 -0
- package/contracts/Permitable.sol +7 -2
- package/contracts/libraries/AddressArray.sol +23 -17
- package/contracts/libraries/AddressSet.sol +5 -3
- package/contracts/libraries/RevertReasonParser.sol +6 -4
- package/contracts/libraries/UniERC20.sol +12 -6
- package/dist/src/asserts.d.ts +3 -0
- package/dist/src/asserts.js +33 -0
- package/dist/src/asserts.js.map +1 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +5 -5
- package/dist/src/index.js.map +1 -0
- package/dist/src/permit.d.ts +79 -0
- package/dist/src/permit.js +98 -0
- package/dist/src/permit.js.map +1 -0
- package/dist/src/prelude.d.ts +20 -0
- package/dist/src/prelude.js +32 -0
- package/dist/src/prelude.js.map +1 -0
- package/dist/src/profileEVM.d.ts +9 -0
- package/dist/src/profileEVM.js +122 -0
- package/dist/src/profileEVM.js.map +1 -0
- package/dist/src/utils.d.ts +14 -0
- package/dist/src/utils.js +58 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +14 -16
- package/utils/contract.hbs +69 -0
- package/utils/solidity-docgen-helpers.js +31 -0
|
@@ -4,8 +4,10 @@ pragma solidity ^0.8.0;
|
|
|
4
4
|
pragma abicoder v1;
|
|
5
5
|
|
|
6
6
|
abstract contract EthReceiver {
|
|
7
|
+
error EthDepositRejected();
|
|
8
|
+
|
|
7
9
|
receive() external payable {
|
|
8
10
|
// solhint-disable-next-line avoid-tx-origin
|
|
9
|
-
|
|
11
|
+
if (msg.sender == tx.origin) revert EthDepositRejected();
|
|
10
12
|
}
|
|
11
13
|
}
|
package/contracts/GasChecker.sol
CHANGED
|
@@ -3,17 +3,13 @@
|
|
|
3
3
|
pragma solidity ^0.8.0;
|
|
4
4
|
pragma abicoder v1;
|
|
5
5
|
|
|
6
|
-
import "@openzeppelin/contracts/utils/Strings.sol";
|
|
7
|
-
|
|
8
6
|
contract GasChecker {
|
|
9
|
-
|
|
7
|
+
error GasCostDiffers(uint256 expected, uint256 actual);
|
|
10
8
|
|
|
11
|
-
modifier checkGasCost(uint256
|
|
9
|
+
modifier checkGasCost(uint256 expected) {
|
|
12
10
|
uint256 gas = gasleft();
|
|
13
11
|
_;
|
|
14
|
-
gas -= gasleft();
|
|
15
|
-
if (
|
|
16
|
-
require (gas == expectedGasCost, string(abi.encodePacked("Gas cost differs: expected ", expectedGasCost.toString(), ", actual: ", gas.toString())));
|
|
17
|
-
}
|
|
12
|
+
unchecked { gas -= gasleft(); }
|
|
13
|
+
if (expected > 0 && gas != expected) revert GasCostDiffers(expected, gas);
|
|
18
14
|
}
|
|
19
15
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity ^0.8.0;
|
|
4
|
+
pragma abicoder v1;
|
|
5
|
+
|
|
6
|
+
abstract contract OnlyWethReceiver {
|
|
7
|
+
error EthDepositRejected();
|
|
8
|
+
|
|
9
|
+
// solhint-disable-next-line var-name-mixedcase
|
|
10
|
+
address internal immutable _WETH;
|
|
11
|
+
|
|
12
|
+
constructor(address weth) {
|
|
13
|
+
_WETH = weth;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
receive() external payable {
|
|
17
|
+
// solhint-disable-next-line avoid-tx-origin
|
|
18
|
+
if (msg.sender != _WETH) revert EthDepositRejected();
|
|
19
|
+
}
|
|
20
|
+
}
|
package/contracts/Permitable.sol
CHANGED
|
@@ -8,7 +8,6 @@ import "./interfaces/IDaiLikePermit.sol";
|
|
|
8
8
|
|
|
9
9
|
contract Permitable {
|
|
10
10
|
error BadPermitLength();
|
|
11
|
-
error PermitFailed();
|
|
12
11
|
|
|
13
12
|
function _permit(address token, bytes calldata permit) internal virtual {
|
|
14
13
|
if (permit.length > 0) {
|
|
@@ -23,7 +22,13 @@ contract Permitable {
|
|
|
23
22
|
} else {
|
|
24
23
|
revert BadPermitLength();
|
|
25
24
|
}
|
|
26
|
-
if (!success)
|
|
25
|
+
if (!success) {
|
|
26
|
+
// bubble up revert reason from permit call
|
|
27
|
+
assembly { // solhint-disable-line no-inline-assembly
|
|
28
|
+
returndatacopy(0, 0, returndatasize())
|
|
29
|
+
revert(0, returndatasize())
|
|
30
|
+
}
|
|
31
|
+
}
|
|
27
32
|
}
|
|
28
33
|
}
|
|
29
34
|
}
|
|
@@ -35,33 +35,39 @@ library AddressArray {
|
|
|
35
35
|
if (len > output.length) revert OutputArrayTooSmall();
|
|
36
36
|
if (len > 0) {
|
|
37
37
|
output[0] = address(uint160(lengthAndFirst));
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
unchecked {
|
|
39
|
+
for (uint i = 1; i < len; i++) {
|
|
40
|
+
output[i] = address(uint160(self._raw[i]));
|
|
41
|
+
}
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
return output;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
function push(Data storage self, address account) internal returns(uint256) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
unchecked {
|
|
49
|
+
uint256 lengthAndFirst = self._raw[0];
|
|
50
|
+
uint256 len = lengthAndFirst >> 160;
|
|
51
|
+
if (len == 0) {
|
|
52
|
+
self._raw[0] = (1 << 160) + uint160(account);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
self._raw[0] = lengthAndFirst + (1 << 160);
|
|
56
|
+
self._raw[len] = uint160(account);
|
|
57
|
+
}
|
|
58
|
+
return len + 1;
|
|
54
59
|
}
|
|
55
|
-
return len + 1;
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
function pop(Data storage self) internal {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
unchecked {
|
|
64
|
+
uint256 lengthAndFirst = self._raw[0];
|
|
65
|
+
uint256 len = lengthAndFirst >> 160;
|
|
66
|
+
if (len == 0) revert PopFromEmptyArray();
|
|
67
|
+
self._raw[len - 1] = 0;
|
|
68
|
+
if (len > 1) {
|
|
69
|
+
self._raw[0] = lengthAndFirst - (1 << 160);
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
}
|
|
67
73
|
|
|
@@ -39,9 +39,11 @@ library AddressSet {
|
|
|
39
39
|
return false;
|
|
40
40
|
}
|
|
41
41
|
if (index < s.items.length()) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
unchecked {
|
|
43
|
+
address lastItem = s.items.at(s.items.length() - 1);
|
|
44
|
+
s.items.set(index - 1, lastItem);
|
|
45
|
+
s.lookup[lastItem] = index;
|
|
46
|
+
}
|
|
45
47
|
}
|
|
46
48
|
s.items.pop();
|
|
47
49
|
delete s.lookup[item];
|
|
@@ -16,6 +16,8 @@ library RevertReasonParser {
|
|
|
16
16
|
using StringUtil for uint256;
|
|
17
17
|
using StringUtil for bytes;
|
|
18
18
|
|
|
19
|
+
error InvalidRevertReason();
|
|
20
|
+
|
|
19
21
|
bytes4 constant private _ERROR_SELECTOR = bytes4(keccak256("Error(string)"));
|
|
20
22
|
bytes4 constant private _PANIC_SELECTOR = bytes4(keccak256("Panic(uint256)"));
|
|
21
23
|
|
|
@@ -42,8 +44,8 @@ library RevertReasonParser {
|
|
|
42
44
|
because of that we can't check for equality and instead check
|
|
43
45
|
that string length + extra 68 bytes is less than overall data length
|
|
44
46
|
*/
|
|
45
|
-
|
|
46
|
-
return string
|
|
47
|
+
if (data.length < 68 + bytes(reason).length) revert InvalidRevertReason();
|
|
48
|
+
return string.concat(prefix, "Error(", reason, ")");
|
|
47
49
|
}
|
|
48
50
|
// 36 = 4-byte selector + 32 bytes integer
|
|
49
51
|
else if (selector == _PANIC_SELECTOR && data.length == 36) {
|
|
@@ -53,8 +55,8 @@ library RevertReasonParser {
|
|
|
53
55
|
// 36 = 32 bytes data length + 4-byte selector
|
|
54
56
|
code := mload(add(data, 36))
|
|
55
57
|
}
|
|
56
|
-
return string
|
|
58
|
+
return string.concat(prefix, "Panic(", code.toHex(), ")");
|
|
57
59
|
}
|
|
58
|
-
return string
|
|
60
|
+
return string.concat(prefix, "Unknown(", data.toHex(), ")");
|
|
59
61
|
}
|
|
60
62
|
}
|
|
@@ -13,6 +13,10 @@ library UniERC20 {
|
|
|
13
13
|
using SafeMath for uint256;
|
|
14
14
|
using SafeERC20 for IERC20;
|
|
15
15
|
|
|
16
|
+
error NotEnoughValue();
|
|
17
|
+
error FromIsNotSender();
|
|
18
|
+
error ToIsNotThis();
|
|
19
|
+
|
|
16
20
|
IERC20 private constant _ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
|
|
17
21
|
IERC20 private constant _ZERO_ADDRESS = IERC20(address(0));
|
|
18
22
|
|
|
@@ -41,9 +45,9 @@ library UniERC20 {
|
|
|
41
45
|
function uniTransferFrom(IERC20 token, address payable from, address to, uint256 amount) internal {
|
|
42
46
|
if (amount > 0) {
|
|
43
47
|
if (isETH(token)) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
if (msg.value < amount) revert NotEnoughValue();
|
|
49
|
+
if (from != msg.sender) revert FromIsNotSender();
|
|
50
|
+
if (to != address(this)) revert ToIsNotThis();
|
|
47
51
|
if (msg.value > amount) {
|
|
48
52
|
// Return remainder if exist
|
|
49
53
|
from.transfer(msg.value.sub(amount));
|
|
@@ -91,7 +95,7 @@ library UniERC20 {
|
|
|
91
95
|
if (success && data.length >= 96) {
|
|
92
96
|
(uint256 offset, uint256 len) = abi.decode(data, (uint256, uint256));
|
|
93
97
|
if (offset == 0x20 && len > 0 && len <= 256) {
|
|
94
|
-
return
|
|
98
|
+
return abi.decode(data, (string));
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
101
|
|
|
@@ -103,8 +107,10 @@ library UniERC20 {
|
|
|
103
107
|
|
|
104
108
|
if (len > 0) {
|
|
105
109
|
bytes memory result = new bytes(len);
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
unchecked {
|
|
111
|
+
for (uint i = 0; i < len; i++) {
|
|
112
|
+
result[i] = data[i];
|
|
113
|
+
}
|
|
108
114
|
}
|
|
109
115
|
return string(result);
|
|
110
116
|
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertRoughlyEqualValues = exports.toBNExtended = void 0;
|
|
4
|
+
const prelude_1 = require("./prelude");
|
|
5
|
+
function toBNExtended(value) {
|
|
6
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
7
|
+
return (0, prelude_1.toBN)(value);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
exports.toBNExtended = toBNExtended;
|
|
12
|
+
function assertRoughlyEqualValues(expected, actual, relativeDiff) {
|
|
13
|
+
let expectedBN = toBNExtended(expected);
|
|
14
|
+
let actualBN = toBNExtended(actual);
|
|
15
|
+
if (expectedBN.isNeg() !== actualBN.isNeg()) {
|
|
16
|
+
(0, prelude_1.expect)(actualBN).to.be.bignumber.equal(expectedBN, 'Values are of different sign');
|
|
17
|
+
}
|
|
18
|
+
expectedBN = expectedBN.abs();
|
|
19
|
+
actualBN = actualBN.abs();
|
|
20
|
+
let multiplerNumerator = relativeDiff;
|
|
21
|
+
let multiplerDenominator = (0, prelude_1.toBN)('1');
|
|
22
|
+
while (!Number.isInteger(multiplerNumerator)) {
|
|
23
|
+
multiplerDenominator = multiplerDenominator.mul((0, prelude_1.toBN)('10'));
|
|
24
|
+
multiplerNumerator *= 10;
|
|
25
|
+
}
|
|
26
|
+
const diff = expectedBN.sub(actualBN).abs();
|
|
27
|
+
const treshold = expectedBN.mul((0, prelude_1.toBN)(multiplerNumerator.toString())).div(multiplerDenominator);
|
|
28
|
+
if (!diff.lte(treshold)) {
|
|
29
|
+
(0, prelude_1.expect)(actualBN).to.be.bignumber.equal(expectedBN, `${actual} != ${expected} with ${relativeDiff} precision`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.assertRoughlyEqualValues = assertRoughlyEqualValues;
|
|
33
|
+
//# sourceMappingURL=asserts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asserts.js","sourceRoot":"","sources":["../../src/asserts.ts"],"names":[],"mappings":";;;AAAA,uCAAyC;AAGzC,SAAgB,YAAY,CAAE,KAA2B;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QACxD,OAAO,IAAA,cAAI,EAAC,KAAK,CAAC,CAAC;KACtB;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AALD,oCAKC;AAED,SAAgB,wBAAwB,CAAE,QAA8B,EAAE,MAA4B,EAAE,YAAoB;IACxH,IAAI,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACxC,IAAI,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,UAAU,CAAC,KAAK,EAAE,KAAK,QAAQ,CAAC,KAAK,EAAE,EAAE;QACzC,IAAA,gBAAM,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,8BAA8B,CAAC,CAAC;KACtF;IAED,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;IAC9B,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,kBAAkB,GAAG,YAAY,CAAC;IACtC,IAAI,oBAAoB,GAAG,IAAA,cAAI,EAAC,GAAG,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE;QAC1C,oBAAoB,GAAG,oBAAoB,CAAC,GAAG,CAAC,IAAA,cAAI,EAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,kBAAkB,IAAI,EAAE,CAAC;KAC5B;IACD,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,IAAA,cAAI,EAAC,kBAAkB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAC/F,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;QACrB,IAAA,gBAAM,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,QAAQ,SAAS,YAAY,YAAY,CAAC,CAAC;KACjH;AACL,CAAC;AArBD,4DAqBC"}
|
package/dist/src/index.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// created from 'create-ts-index'
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
tslib_1.__exportStar(require("./asserts"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./permit"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./prelude"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./profileEVM"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./utils"), exports);
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AAAA,iCAAiC;;;AAEjC,oDAA0B;AAC1B,mDAAyB;AACzB,oDAA0B;AAC1B,uDAA6B;AAC7B,kDAAwB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { MessageTypes, SignTypedDataVersion, TypedMessage } from '@metamask/eth-sig-util';
|
|
2
|
+
import { Token } from './utils';
|
|
3
|
+
export declare const TypedDataVersion = SignTypedDataVersion.V4;
|
|
4
|
+
export declare const defaultDeadline: string;
|
|
5
|
+
export declare const EIP712Domain: {
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
}[];
|
|
9
|
+
export declare const Permit: {
|
|
10
|
+
name: string;
|
|
11
|
+
type: string;
|
|
12
|
+
}[];
|
|
13
|
+
export declare const DaiLikePermit: {
|
|
14
|
+
name: string;
|
|
15
|
+
type: string;
|
|
16
|
+
}[];
|
|
17
|
+
export declare function trim0x(bigNumber: BN | string): string;
|
|
18
|
+
export declare function cutSelector(data: string): string;
|
|
19
|
+
export declare function domainSeparator(name: string, version: string, chainId: string, verifyingContract: string): string;
|
|
20
|
+
export declare function buildData(name: string, version: string, chainId: number, verifyingContract: string, owner: string, spender: string, value: string, nonce: string, deadline?: string): {
|
|
21
|
+
readonly primaryType: "Permit";
|
|
22
|
+
readonly types: {
|
|
23
|
+
readonly EIP712Domain: {
|
|
24
|
+
name: string;
|
|
25
|
+
type: string;
|
|
26
|
+
}[];
|
|
27
|
+
readonly Permit: {
|
|
28
|
+
name: string;
|
|
29
|
+
type: string;
|
|
30
|
+
}[];
|
|
31
|
+
};
|
|
32
|
+
readonly domain: {
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly version: string;
|
|
35
|
+
readonly chainId: number;
|
|
36
|
+
readonly verifyingContract: string;
|
|
37
|
+
};
|
|
38
|
+
readonly message: {
|
|
39
|
+
readonly owner: string;
|
|
40
|
+
readonly spender: string;
|
|
41
|
+
readonly value: string;
|
|
42
|
+
readonly nonce: string;
|
|
43
|
+
readonly deadline: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export declare function buildDataLikeDai(name: string, version: string, chainId: number, verifyingContract: string, holder: string, spender: string, nonce: string, allowed: boolean, expiry?: string): {
|
|
47
|
+
readonly primaryType: "Permit";
|
|
48
|
+
readonly types: {
|
|
49
|
+
readonly EIP712Domain: {
|
|
50
|
+
name: string;
|
|
51
|
+
type: string;
|
|
52
|
+
}[];
|
|
53
|
+
readonly Permit: {
|
|
54
|
+
name: string;
|
|
55
|
+
type: string;
|
|
56
|
+
}[];
|
|
57
|
+
};
|
|
58
|
+
readonly domain: {
|
|
59
|
+
readonly name: string;
|
|
60
|
+
readonly version: string;
|
|
61
|
+
readonly chainId: number;
|
|
62
|
+
readonly verifyingContract: string;
|
|
63
|
+
};
|
|
64
|
+
readonly message: {
|
|
65
|
+
readonly holder: string;
|
|
66
|
+
readonly spender: string;
|
|
67
|
+
readonly nonce: string;
|
|
68
|
+
readonly expiry: string;
|
|
69
|
+
readonly allowed: boolean;
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
export interface PermittableToken extends Token {
|
|
73
|
+
nonces(owner: string, txDetails?: Truffle.TransactionDetails): Promise<BN>;
|
|
74
|
+
name(txDetails?: Truffle.TransactionDetails): Promise<string>;
|
|
75
|
+
}
|
|
76
|
+
export declare function signWithPk<T extends MessageTypes>(privateKey: string, data: TypedMessage<T>): string;
|
|
77
|
+
export declare function getPermit(owner: string, ownerPrivateKey: string, permitContract: PermittableToken, tokenVersion: string, chainId: number, spender: string, value: string, deadline?: string): Promise<string>;
|
|
78
|
+
export declare function getPermitLikeDai(holder: string, holderPrivateKey: string, permitContract: PermittableToken, tokenVersion: string, chainId: number, spender: string, allowed: boolean, expiry?: string): Promise<string>;
|
|
79
|
+
export declare function withTarget(target: BN | string, data: BN | string): string;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.withTarget = exports.getPermitLikeDai = exports.getPermit = exports.signWithPk = exports.buildDataLikeDai = exports.buildData = exports.domainSeparator = exports.cutSelector = exports.trim0x = exports.DaiLikePermit = exports.Permit = exports.EIP712Domain = exports.defaultDeadline = exports.TypedDataVersion = void 0;
|
|
4
|
+
const eth_sig_util_1 = require("@metamask/eth-sig-util");
|
|
5
|
+
const ethereumjs_util_1 = require("ethereumjs-util");
|
|
6
|
+
const prelude_1 = require("./prelude");
|
|
7
|
+
exports.TypedDataVersion = eth_sig_util_1.SignTypedDataVersion.V4;
|
|
8
|
+
exports.defaultDeadline = prelude_1.constants.MAX_UINT256;
|
|
9
|
+
exports.EIP712Domain = [
|
|
10
|
+
{ name: 'name', type: 'string' },
|
|
11
|
+
{ name: 'version', type: 'string' },
|
|
12
|
+
{ name: 'chainId', type: 'uint256' },
|
|
13
|
+
{ name: 'verifyingContract', type: 'address' },
|
|
14
|
+
];
|
|
15
|
+
exports.Permit = [
|
|
16
|
+
{ name: 'owner', type: 'address' },
|
|
17
|
+
{ name: 'spender', type: 'address' },
|
|
18
|
+
{ name: 'value', type: 'uint256' },
|
|
19
|
+
{ name: 'nonce', type: 'uint256' },
|
|
20
|
+
{ name: 'deadline', type: 'uint256' },
|
|
21
|
+
];
|
|
22
|
+
exports.DaiLikePermit = [
|
|
23
|
+
{ name: 'holder', type: 'address' },
|
|
24
|
+
{ name: 'spender', type: 'address' },
|
|
25
|
+
{ name: 'nonce', type: 'uint256' },
|
|
26
|
+
{ name: 'expiry', type: 'uint256' },
|
|
27
|
+
{ name: 'allowed', type: 'bool' },
|
|
28
|
+
];
|
|
29
|
+
function trim0x(bigNumber) {
|
|
30
|
+
const s = bigNumber.toString();
|
|
31
|
+
if (s.startsWith('0x')) {
|
|
32
|
+
return s.substring(2);
|
|
33
|
+
}
|
|
34
|
+
return s;
|
|
35
|
+
}
|
|
36
|
+
exports.trim0x = trim0x;
|
|
37
|
+
function cutSelector(data) {
|
|
38
|
+
const hexPrefix = '0x';
|
|
39
|
+
return hexPrefix + data.substr(hexPrefix.length + 8);
|
|
40
|
+
}
|
|
41
|
+
exports.cutSelector = cutSelector;
|
|
42
|
+
function domainSeparator(name, version, chainId, verifyingContract) {
|
|
43
|
+
return '0x' + eth_sig_util_1.TypedDataUtils.hashStruct('EIP712Domain', { name, version, chainId, verifyingContract }, { EIP712Domain: exports.EIP712Domain }, exports.TypedDataVersion).toString('hex');
|
|
44
|
+
}
|
|
45
|
+
exports.domainSeparator = domainSeparator;
|
|
46
|
+
function buildData(name, version, chainId, verifyingContract, owner, spender, value, nonce, deadline = exports.defaultDeadline) {
|
|
47
|
+
return {
|
|
48
|
+
primaryType: 'Permit',
|
|
49
|
+
types: { EIP712Domain: exports.EIP712Domain, Permit: exports.Permit },
|
|
50
|
+
domain: { name, version, chainId, verifyingContract },
|
|
51
|
+
message: { owner, spender, value, nonce, deadline },
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
exports.buildData = buildData;
|
|
55
|
+
function buildDataLikeDai(name, version, chainId, verifyingContract, holder, spender, nonce, allowed, expiry = exports.defaultDeadline) {
|
|
56
|
+
return {
|
|
57
|
+
primaryType: 'Permit',
|
|
58
|
+
types: { EIP712Domain: exports.EIP712Domain, Permit: exports.DaiLikePermit },
|
|
59
|
+
domain: { name, version, chainId, verifyingContract },
|
|
60
|
+
message: { holder, spender, nonce, expiry, allowed },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
exports.buildDataLikeDai = buildDataLikeDai;
|
|
64
|
+
function signWithPk(privateKey, data) {
|
|
65
|
+
return (0, eth_sig_util_1.signTypedData)({ privateKey: Buffer.from(trim0x(privateKey), 'hex'), data, version: exports.TypedDataVersion });
|
|
66
|
+
}
|
|
67
|
+
exports.signWithPk = signWithPk;
|
|
68
|
+
/*
|
|
69
|
+
* @param permitContract The contract object with ERC20Permit type and token address for which the permit creating.
|
|
70
|
+
*/
|
|
71
|
+
async function getPermit(owner, ownerPrivateKey, permitContract, tokenVersion, chainId, spender, value, deadline = exports.defaultDeadline) {
|
|
72
|
+
const nonce = await permitContract.nonces(owner);
|
|
73
|
+
const name = await permitContract.name();
|
|
74
|
+
const data = buildData(name, tokenVersion, chainId, permitContract.address, owner, spender, value, nonce.toString(), deadline);
|
|
75
|
+
const signature = signWithPk(ownerPrivateKey, data);
|
|
76
|
+
const { v, r, s } = (0, ethereumjs_util_1.fromRpcSig)(signature);
|
|
77
|
+
const permitCall = permitContract.contract.methods.permit(owner, spender, value, deadline, v, r, s).encodeABI();
|
|
78
|
+
return cutSelector(permitCall);
|
|
79
|
+
}
|
|
80
|
+
exports.getPermit = getPermit;
|
|
81
|
+
/*
|
|
82
|
+
* @param permitContract The contract object with ERC20PermitLikeDai type and token address for which the permit creating.
|
|
83
|
+
*/
|
|
84
|
+
async function getPermitLikeDai(holder, holderPrivateKey, permitContract, tokenVersion, chainId, spender, allowed, expiry = exports.defaultDeadline) {
|
|
85
|
+
const nonce = await permitContract.nonces(holder);
|
|
86
|
+
const name = await permitContract.name();
|
|
87
|
+
const data = buildDataLikeDai(name, tokenVersion, chainId, permitContract.address, holder, spender, nonce.toString(), allowed, expiry);
|
|
88
|
+
const signature = signWithPk(holderPrivateKey, data);
|
|
89
|
+
const { v, r, s } = (0, ethereumjs_util_1.fromRpcSig)(signature);
|
|
90
|
+
const permitCall = permitContract.contract.methods.permit(holder, spender, nonce, expiry, allowed, v, r, s).encodeABI();
|
|
91
|
+
return cutSelector(permitCall);
|
|
92
|
+
}
|
|
93
|
+
exports.getPermitLikeDai = getPermitLikeDai;
|
|
94
|
+
function withTarget(target, data) {
|
|
95
|
+
return target.toString() + trim0x(data);
|
|
96
|
+
}
|
|
97
|
+
exports.withTarget = withTarget;
|
|
98
|
+
//# sourceMappingURL=permit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permit.js","sourceRoot":"","sources":["../../src/permit.ts"],"names":[],"mappings":";;;AAAA,yDAAyH;AACzH,qDAA6C;AAE7C,uCAAsC;AAGzB,QAAA,gBAAgB,GAAG,mCAAoB,CAAC,EAAE,CAAC;AAC3C,QAAA,eAAe,GAAG,mBAAS,CAAC,WAAW,CAAC;AAExC,QAAA,YAAY,GAAG;IACxB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;IAChC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE;IACnC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IACpC,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE;CACjD,CAAC;AAEW,QAAA,MAAM,GAAG;IAClB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;IAClC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IACpC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;IAClC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;IAClC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;CACxC,CAAC;AAEW,QAAA,aAAa,GAAG;IACzB,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;IACnC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;IACpC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;IAClC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;IACnC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;CACpC,CAAC;AAEF,SAAgB,MAAM,CAAE,SAAsB;IAC1C,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC/B,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE;QACpB,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;KACzB;IACD,OAAO,CAAC,CAAC;AACb,CAAC;AAND,wBAMC;AAED,SAAgB,WAAW,CAAE,IAAY;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC;IACvB,OAAO,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACzD,CAAC;AAHD,kCAGC;AAED,SAAgB,eAAe,CAAE,IAAY,EAAE,OAAe,EAAE,OAAe,EAAE,iBAAyB;IACtG,OAAO,IAAI,GAAG,6BAAc,CAAC,UAAU,CACnC,cAAc,EACd,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAC7C,EAAE,YAAY,EAAZ,oBAAY,EAAE,EAChB,wBAAgB,CACnB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC;AAPD,0CAOC;AAED,SAAgB,SAAS,CACrB,IAAY,EACZ,OAAe,EACf,OAAe,EACf,iBAAyB,EACzB,KAAa,EACb,OAAe,EACf,KAAa,EACb,KAAa,EACb,WAAmB,uBAAe;IAElC,OAAO;QACH,WAAW,EAAE,QAAQ;QACrB,KAAK,EAAE,EAAE,YAAY,EAAZ,oBAAY,EAAE,MAAM,EAAN,cAAM,EAAE;QAC/B,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE;QACrD,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE;KAC7C,CAAC;AACf,CAAC;AAjBD,8BAiBC;AAED,SAAgB,gBAAgB,CAC5B,IAAY,EACZ,OAAe,EACf,OAAe,EACf,iBAAyB,EACzB,MAAc,EACd,OAAe,EACf,KAAa,EACb,OAAgB,EAChB,SAAiB,uBAAe;IAEhC,OAAO;QACH,WAAW,EAAE,QAAQ;QACrB,KAAK,EAAE,EAAE,YAAY,EAAZ,oBAAY,EAAE,MAAM,EAAE,qBAAa,EAAE;QAC9C,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE;QACrD,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE;KAC9C,CAAC;AACf,CAAC;AAjBD,4CAiBC;AAOD,SAAgB,UAAU,CAA0B,UAAkB,EAAE,IAAqB;IACzF,OAAO,IAAA,4BAAa,EAAC,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,wBAAgB,EAAE,CAAC,CAAC;AAClH,CAAC;AAFD,gCAEC;AAED;;GAEG;AACI,KAAK,UAAU,SAAS,CAC3B,KAAa,EACb,eAAuB,EACvB,cAAgC,EAChC,YAAoB,EACpB,OAAe,EACf,OAAe,EACf,KAAa,EACb,QAAQ,GAAG,uBAAe;IAE1B,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC/H,MAAM,SAAS,GAAG,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IACpD,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAA,4BAAU,EAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IAChH,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC;AAjBD,8BAiBC;AAED;;GAEG;AACI,KAAK,UAAU,gBAAgB,CAClC,MAAc,EACd,gBAAwB,EACxB,cAAgC,EAChC,YAAoB,EACpB,OAAe,EACf,OAAe,EACf,OAAgB,EAChB,MAAM,GAAG,uBAAe;IAExB,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACvI,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAA,4BAAU,EAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;IACxH,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC;AAjBD,4CAiBC;AAED,SAAgB,UAAU,CAAE,MAAmB,EAAE,IAAiB;IAC9D,OAAO,MAAM,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAFD,gCAEC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Assertion, AssertionError, assert, expect, config, should } from 'chai';
|
|
2
|
+
import 'chai-bn';
|
|
3
|
+
import { toBN } from 'web3-utils';
|
|
4
|
+
import BN from 'bn.js';
|
|
5
|
+
export declare const constants: {
|
|
6
|
+
readonly ZERO_ADDRESS: "0x0000000000000000000000000000000000000000";
|
|
7
|
+
readonly EEE_ADDRESS: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
8
|
+
readonly ZERO_BYTES32: "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
9
|
+
readonly MAX_UINT256: string;
|
|
10
|
+
readonly MAX_INT256: string;
|
|
11
|
+
readonly MIN_INT256: string;
|
|
12
|
+
};
|
|
13
|
+
export { toBN, };
|
|
14
|
+
export declare type Time = {
|
|
15
|
+
increaseTo: (target: string | number | BN) => Promise<BN>;
|
|
16
|
+
latest: () => Promise<BN>;
|
|
17
|
+
};
|
|
18
|
+
export declare const time: Time;
|
|
19
|
+
export declare function ether(n: string): BN;
|
|
20
|
+
export { Assertion, AssertionError, assert, expect, config, should, };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.should = exports.config = exports.expect = exports.assert = exports.AssertionError = exports.Assertion = exports.ether = exports.time = exports.toBN = exports.constants = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chai_1 = tslib_1.__importStar(require("chai"));
|
|
6
|
+
Object.defineProperty(exports, "Assertion", { enumerable: true, get: function () { return chai_1.Assertion; } });
|
|
7
|
+
Object.defineProperty(exports, "AssertionError", { enumerable: true, get: function () { return chai_1.AssertionError; } });
|
|
8
|
+
Object.defineProperty(exports, "assert", { enumerable: true, get: function () { return chai_1.assert; } });
|
|
9
|
+
Object.defineProperty(exports, "expect", { enumerable: true, get: function () { return chai_1.expect; } });
|
|
10
|
+
Object.defineProperty(exports, "config", { enumerable: true, get: function () { return chai_1.config; } });
|
|
11
|
+
Object.defineProperty(exports, "should", { enumerable: true, get: function () { return chai_1.should; } });
|
|
12
|
+
require("chai-bn");
|
|
13
|
+
const chai_as_promised_1 = tslib_1.__importDefault(require("chai-as-promised"));
|
|
14
|
+
const web3_utils_1 = require("web3-utils");
|
|
15
|
+
Object.defineProperty(exports, "toBN", { enumerable: true, get: function () { return web3_utils_1.toBN; } });
|
|
16
|
+
chai_1.default.use(chai_as_promised_1.default);
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
18
|
+
const { time: timeImpl } = require('@openzeppelin/test-helpers');
|
|
19
|
+
exports.constants = {
|
|
20
|
+
ZERO_ADDRESS: '0x0000000000000000000000000000000000000000',
|
|
21
|
+
EEE_ADDRESS: '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
|
|
22
|
+
ZERO_BYTES32: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
23
|
+
MAX_UINT256: (0, web3_utils_1.toBN)('2').pow((0, web3_utils_1.toBN)('256')).sub((0, web3_utils_1.toBN)('1')).toString(),
|
|
24
|
+
MAX_INT256: (0, web3_utils_1.toBN)('2').pow((0, web3_utils_1.toBN)('255')).sub((0, web3_utils_1.toBN)('1')).toString(),
|
|
25
|
+
MIN_INT256: (0, web3_utils_1.toBN)('2').pow((0, web3_utils_1.toBN)('255')).mul((0, web3_utils_1.toBN)('-1')).toString(),
|
|
26
|
+
};
|
|
27
|
+
exports.time = timeImpl;
|
|
28
|
+
function ether(n) {
|
|
29
|
+
return (0, web3_utils_1.toBN)((0, web3_utils_1.toWei)(n, 'ether'));
|
|
30
|
+
}
|
|
31
|
+
exports.ether = ether;
|
|
32
|
+
//# sourceMappingURL=prelude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prelude.js","sourceRoot":"","sources":["../../src/prelude.ts"],"names":[],"mappings":";;;;AAAA,qDAAuF;AAqCnF,0FArCW,gBAAS,OAqCX;AACT,+FAtCsB,qBAAc,OAsCtB;AACd,uFAvCsC,aAAM,OAuCtC;AACN,uFAxC8C,aAAM,OAwC9C;AACN,uFAzCsD,aAAM,OAyCtD;AACN,uFA1C8D,aAAM,OA0C9D;AAzCV,mBAAiB;AACjB,gFAA8C;AAC9C,2CAAyC;AAiBrC,qFAjBK,iBAAI,OAiBL;AAfR,cAAI,CAAC,GAAG,CAAC,0BAAc,CAAC,CAAC;AACzB,8DAA8D;AAC9D,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAAC;AAEpD,QAAA,SAAS,GAAG;IACrB,YAAY,EAAE,4CAA4C;IAC1D,WAAW,EAAE,4CAA4C;IACzD,YAAY,EAAE,oEAAoE;IAClF,WAAW,EAAE,IAAA,iBAAI,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAA,iBAAI,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAA,iBAAI,EAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjE,UAAU,EAAE,IAAA,iBAAI,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAA,iBAAI,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAA,iBAAI,EAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE;IAChE,UAAU,EAAE,IAAA,iBAAI,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAA,iBAAI,EAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAA,iBAAI,EAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC3D,CAAC;AAaE,QAAA,IAAI,GAAS,QAAQ,CAAC;AAEnC,SAAgB,KAAK,CAAE,CAAS;IAC5B,OAAO,IAAA,iBAAI,EAAC,IAAA,kBAAK,EAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AACnC,CAAC;AAFD,sBAEC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { PathLike, promises as fs } from 'fs';
|
|
3
|
+
export declare const gasspectOptionsDefault: {
|
|
4
|
+
minOpGasCost: number;
|
|
5
|
+
args: boolean;
|
|
6
|
+
res: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function profileEVM(txHash: string, instruction: string[], optionalTraceFile?: PathLike | fs.FileHandle): Promise<number[]>;
|
|
9
|
+
export declare function gasspectEVM(txHash: string, gasspectOptions?: Record<string, unknown>, optionalTraceFile?: PathLike | fs.FileHandle): Promise<string[]>;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.gasspectEVM = exports.profileEVM = exports.gasspectOptionsDefault = void 0;
|
|
4
|
+
const util_1 = require("util");
|
|
5
|
+
const fs_1 = require("fs");
|
|
6
|
+
const prelude_1 = require("./prelude");
|
|
7
|
+
exports.gasspectOptionsDefault = {
|
|
8
|
+
minOpGasCost: 300,
|
|
9
|
+
args: false,
|
|
10
|
+
res: false, // return operations results
|
|
11
|
+
};
|
|
12
|
+
function _normalizeOp(ops, i) {
|
|
13
|
+
if (ops[i].op === 'STATICCALL') {
|
|
14
|
+
ops[i].gasCost = ops[i].gasCost - ops[i + 1].gas;
|
|
15
|
+
if (ops[i].stack.length > 8 && ops[i].stack[ops[i].stack.length - 8] === '0000000000000000000000000000000000000000000000000000000000000001') {
|
|
16
|
+
ops[i].op = 'STATICCALL-ECRECOVER';
|
|
17
|
+
}
|
|
18
|
+
else if (ops[i].stack.length > 8 && ops[i].stack[ops[i].stack.length - 8] <= '00000000000000000000000000000000000000000000000000000000000000FF') {
|
|
19
|
+
ops[i].op = 'STATICCALL-' + ops[i].stack[ops[i].stack.length - 8].substr(62, 2);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
ops[i].args = [
|
|
23
|
+
'0x' + ops[i].stack[ops[i].stack.length - 2].substr(24),
|
|
24
|
+
'0x' + (ops[i].memory || []).join('').substr(2 * (0, prelude_1.toBN)(ops[i].stack[ops[i].stack.length - 3]).toNumber(), 2 * (0, prelude_1.toBN)(ops[i].stack[ops[i].stack.length - 4]).toNumber()),
|
|
25
|
+
];
|
|
26
|
+
if (ops[i].gasCost === 100) {
|
|
27
|
+
ops[i].op += '_R';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (['CALL', 'DELEGATECALL', 'CALLCODE'].indexOf(ops[i].op) !== -1) {
|
|
32
|
+
ops[i].args = [
|
|
33
|
+
'0x' + ops[i].stack[ops[i].stack.length - 2].substr(24),
|
|
34
|
+
'0x' + (ops[i].memory || []).join('').substr(2 * (0, prelude_1.toBN)(ops[i].stack[ops[i].stack.length - 4]).toNumber(), 2 * (0, prelude_1.toBN)(ops[i].stack[ops[i].stack.length - 5]).toNumber()),
|
|
35
|
+
];
|
|
36
|
+
ops[i].gasCost = ops[i].gasCost - ops[i + 1].gas;
|
|
37
|
+
ops[i].res = ops[i + 1].stack[ops[i + 1].stack.length - 1];
|
|
38
|
+
if (ops[i].gasCost === 100) {
|
|
39
|
+
ops[i].op += '_R';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (['RETURN', 'REVERT', 'INVALID'].indexOf(ops[i].op) !== -1) {
|
|
43
|
+
ops[i].gasCost = 3;
|
|
44
|
+
}
|
|
45
|
+
if (['SSTORE', 'SLOAD'].indexOf(ops[i].op) !== -1) {
|
|
46
|
+
ops[i].args = [
|
|
47
|
+
'0x' + ops[i].stack[ops[i].stack.length - 1],
|
|
48
|
+
];
|
|
49
|
+
if (ops[i].op === 'SSTORE') {
|
|
50
|
+
ops[i].args.push('0x' + ops[i].stack[ops[i].stack.length - 2]);
|
|
51
|
+
}
|
|
52
|
+
if (ops[i].gasCost === 100) {
|
|
53
|
+
ops[i].op += '_R';
|
|
54
|
+
}
|
|
55
|
+
if (ops[i].gasCost === 20000) {
|
|
56
|
+
ops[i].op += '_I';
|
|
57
|
+
}
|
|
58
|
+
if (ops[i].op.startsWith('SLOAD')) {
|
|
59
|
+
ops[i].res = ops[i + 1].stack[ops[i + 1].stack.length - 1];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (ops[i].op === 'EXTCODESIZE') {
|
|
63
|
+
ops[i].args = [
|
|
64
|
+
'0x' + ops[i].stack[ops[i].stack.length - 1].substr(24),
|
|
65
|
+
];
|
|
66
|
+
ops[i].res = ops[i + 1].stack[ops[i + 1].stack.length - 1];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function profileEVM(txHash, instruction, optionalTraceFile) {
|
|
70
|
+
if (!web3.currentProvider || typeof web3.currentProvider === 'string' || !web3.currentProvider.send) {
|
|
71
|
+
throw new Error('Unsupported provider');
|
|
72
|
+
}
|
|
73
|
+
const trace = await (0, util_1.promisify)(web3.currentProvider.send.bind(web3.currentProvider))({
|
|
74
|
+
jsonrpc: '2.0',
|
|
75
|
+
method: 'debug_traceTransaction',
|
|
76
|
+
params: [txHash, {}],
|
|
77
|
+
id: new Date().getTime(),
|
|
78
|
+
});
|
|
79
|
+
const str = JSON.stringify(trace);
|
|
80
|
+
if (optionalTraceFile) {
|
|
81
|
+
await fs_1.promises.writeFile(optionalTraceFile, str);
|
|
82
|
+
}
|
|
83
|
+
return instruction.map(instr => {
|
|
84
|
+
return str.split('"' + instr.toUpperCase() + '"').length - 1;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
exports.profileEVM = profileEVM;
|
|
88
|
+
async function gasspectEVM(txHash, gasspectOptions = {}, optionalTraceFile) {
|
|
89
|
+
const options = { ...exports.gasspectOptionsDefault, ...gasspectOptions };
|
|
90
|
+
if (!web3.currentProvider || typeof web3.currentProvider === 'string' || !web3.currentProvider.send) {
|
|
91
|
+
throw new Error('Unsupported provider');
|
|
92
|
+
}
|
|
93
|
+
const trace = await (0, util_1.promisify)(web3.currentProvider.send.bind(web3.currentProvider))({
|
|
94
|
+
jsonrpc: '2.0',
|
|
95
|
+
method: 'debug_traceTransaction',
|
|
96
|
+
params: [txHash, {}],
|
|
97
|
+
id: new Date().getTime(),
|
|
98
|
+
});
|
|
99
|
+
const ops = trace === null || trace === void 0 ? void 0 : trace.result.structLogs;
|
|
100
|
+
const traceAddress = [0, -1];
|
|
101
|
+
for (const [i, op] of ops.entries()) {
|
|
102
|
+
op.traceAddress = traceAddress.slice(0, traceAddress.length - 1);
|
|
103
|
+
_normalizeOp(ops, i);
|
|
104
|
+
if (op.depth + 2 > traceAddress.length) {
|
|
105
|
+
traceAddress[traceAddress.length - 1] += 1;
|
|
106
|
+
traceAddress.push(-1);
|
|
107
|
+
}
|
|
108
|
+
if (op.depth + 2 < traceAddress.length) {
|
|
109
|
+
traceAddress.pop();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const result = ops.filter(op => op.gasCost > options.minOpGasCost).map(op => op.traceAddress.join('-') + '-' + op.op +
|
|
113
|
+
(options.args ? '(' + (op.args || []).join(',') + ')' : '') +
|
|
114
|
+
(options.res ? (op.res ? ':0x' + op.res : '') : '') +
|
|
115
|
+
' = ' + op.gasCost);
|
|
116
|
+
if (optionalTraceFile) {
|
|
117
|
+
await fs_1.promises.writeFile(optionalTraceFile, JSON.stringify(result));
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
exports.gasspectEVM = gasspectEVM;
|
|
122
|
+
//# sourceMappingURL=profileEVM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profileEVM.js","sourceRoot":"","sources":["../../src/profileEVM.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { constants } from './prelude';
|
|
3
|
+
export declare function timeIncreaseTo(seconds: number | string | BN): Promise<void>;
|
|
4
|
+
export interface Token extends Truffle.ContractInstance {
|
|
5
|
+
balanceOf(account: string, txDetails?: Truffle.TransactionDetails): Promise<BN>;
|
|
6
|
+
}
|
|
7
|
+
export declare function trackReceivedTokenAndTx<T extends unknown[], U extends Truffle.AnyEvent>(token: Token | {
|
|
8
|
+
address: typeof constants.ZERO_ADDRESS;
|
|
9
|
+
} | {
|
|
10
|
+
address: typeof constants.EEE_ADDRESS;
|
|
11
|
+
}, wallet: string, txPromise: (...args: T) => Promise<Truffle.TransactionResponse<U>>, ...args: T): Promise<readonly [import("bn.js"), Truffle.TransactionResponse<U>]>;
|
|
12
|
+
export declare function fixSignature(signature: string): string;
|
|
13
|
+
export declare function signMessage(signer: string, messageHex?: string): Promise<string>;
|
|
14
|
+
export declare function countInstructions(txHash: string, instructions: string[]): Promise<number[]>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.countInstructions = exports.signMessage = exports.fixSignature = exports.trackReceivedTokenAndTx = exports.timeIncreaseTo = void 0;
|
|
4
|
+
const util_1 = require("util");
|
|
5
|
+
const prelude_1 = require("./prelude");
|
|
6
|
+
async function timeIncreaseTo(seconds) {
|
|
7
|
+
const delay = 1000 - new Date().getMilliseconds();
|
|
8
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
9
|
+
await prelude_1.time.increaseTo(seconds);
|
|
10
|
+
}
|
|
11
|
+
exports.timeIncreaseTo = timeIncreaseTo;
|
|
12
|
+
async function trackReceivedTokenAndTx(token, wallet, txPromise, ...args) {
|
|
13
|
+
const [balanceFunc, isETH] = 'balanceOf' in token
|
|
14
|
+
? [() => token.balanceOf(wallet), false]
|
|
15
|
+
: [async () => (0, prelude_1.toBN)(await web3.eth.getBalance(wallet)), true];
|
|
16
|
+
const preBalance = await balanceFunc();
|
|
17
|
+
const txResult = await txPromise(...args);
|
|
18
|
+
const txFees = (wallet.toLowerCase() === txResult.receipt.from.toLowerCase() && isETH)
|
|
19
|
+
? (0, prelude_1.toBN)(txResult.receipt.gasUsed).mul((0, prelude_1.toBN)(txResult.receipt.effectiveGasPrice))
|
|
20
|
+
: (0, prelude_1.toBN)('0');
|
|
21
|
+
const postBalance = await balanceFunc();
|
|
22
|
+
return [postBalance.sub(preBalance).add(txFees), txResult];
|
|
23
|
+
}
|
|
24
|
+
exports.trackReceivedTokenAndTx = trackReceivedTokenAndTx;
|
|
25
|
+
function fixSignature(signature) {
|
|
26
|
+
// in geth its always 27/28, in ganache its 0/1. Change to 27/28 to prevent
|
|
27
|
+
// signature malleability if version is 0/1
|
|
28
|
+
// see https://github.com/ethereum/go-ethereum/blob/v1.8.23/internal/ethapi/api.go#L465
|
|
29
|
+
let v = parseInt(signature.slice(130, 132), 16);
|
|
30
|
+
if (v < 27) {
|
|
31
|
+
v += 27;
|
|
32
|
+
}
|
|
33
|
+
const vHex = v.toString(16);
|
|
34
|
+
return signature.slice(0, 130) + vHex;
|
|
35
|
+
}
|
|
36
|
+
exports.fixSignature = fixSignature;
|
|
37
|
+
// signs message in node (ganache auto-applies "Ethereum Signed Message" prefix)
|
|
38
|
+
async function signMessage(signer, messageHex = '0x') {
|
|
39
|
+
return fixSignature(await web3.eth.sign(messageHex, signer));
|
|
40
|
+
}
|
|
41
|
+
exports.signMessage = signMessage;
|
|
42
|
+
async function countInstructions(txHash, instructions) {
|
|
43
|
+
if (!web3.currentProvider || typeof web3.currentProvider === 'string' || !web3.currentProvider.send) {
|
|
44
|
+
throw new Error('Unsupported provider');
|
|
45
|
+
}
|
|
46
|
+
const trace = await (0, util_1.promisify)(web3.currentProvider.send.bind(web3.currentProvider))({
|
|
47
|
+
jsonrpc: '2.0',
|
|
48
|
+
method: 'debug_traceTransaction',
|
|
49
|
+
params: [txHash, {}],
|
|
50
|
+
id: new Date().getTime(),
|
|
51
|
+
});
|
|
52
|
+
const str = JSON.stringify(trace);
|
|
53
|
+
return instructions.map(instr => {
|
|
54
|
+
return str.split('"' + instr.toUpperCase() + '"').length - 1;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
exports.countInstructions = countInstructions;
|
|
58
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1inch/solidity-utils",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.12",
|
|
4
4
|
"main": "dist/src/index.js",
|
|
5
5
|
"types": "dist/src/index.d.ts",
|
|
6
6
|
"repository": {
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"lint:ts:fix": "eslint . --fix --ext .ts",
|
|
21
21
|
"lint:sol": "solhint --max-warnings 0 \"contracts/**/*.sol\"",
|
|
22
22
|
"lint:sol:fix": "solhint --max-warnings 0 \"contracts/**/*.sol\" --fix",
|
|
23
|
-
"test": "hardhat test",
|
|
23
|
+
"test": "hardhat test --parallel",
|
|
24
|
+
"test:ci": "hardhat test",
|
|
24
25
|
"typecheck": "tsc --noEmit --skipLibCheck",
|
|
25
26
|
"typechain": "hardhat typechain"
|
|
26
27
|
},
|
|
@@ -33,41 +34,38 @@
|
|
|
33
34
|
"chai-as-promised": "7.1.1",
|
|
34
35
|
"chai-bn": "0.3.1",
|
|
35
36
|
"ethereumjs-util": "7.1.4",
|
|
36
|
-
"web3-utils": "1.7.
|
|
37
|
+
"web3-utils": "1.7.1"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"@nomiclabs/hardhat-
|
|
40
|
-
"@nomiclabs/hardhat-truffle5": "2.0.4",
|
|
40
|
+
"@nomiclabs/hardhat-truffle5": "2.0.5",
|
|
41
41
|
"@nomiclabs/hardhat-web3": "2.0.0",
|
|
42
|
-
"@typechain/hardhat": "
|
|
42
|
+
"@typechain/hardhat": "6.0.0",
|
|
43
43
|
"@typechain/truffle-v5": "7.0.0",
|
|
44
44
|
"@types/chai": "4.3.0",
|
|
45
45
|
"@types/chai-as-promised": "7.1.5",
|
|
46
46
|
"@types/mocha": "9.1.0",
|
|
47
|
-
"@types/node": "17.0.
|
|
48
|
-
"@typescript-eslint/eslint-plugin": "5.
|
|
49
|
-
"@typescript-eslint/parser": "5.
|
|
47
|
+
"@types/node": "17.0.23",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "5.18.0",
|
|
49
|
+
"@typescript-eslint/parser": "5.18.0",
|
|
50
50
|
"create-ts-index": "^1.14.0",
|
|
51
51
|
"cross-spawn": "7.0.3",
|
|
52
52
|
"dotenv": "16.0.0",
|
|
53
|
-
"eslint": "8.
|
|
53
|
+
"eslint": "8.12.0",
|
|
54
54
|
"eslint-config-standard": "16.0.3",
|
|
55
|
-
"eslint-plugin-import": "2.
|
|
55
|
+
"eslint-plugin-import": "2.26.0",
|
|
56
56
|
"eslint-plugin-node": "11.1.0",
|
|
57
57
|
"eslint-plugin-promise": "6.0.0",
|
|
58
58
|
"eslint-plugin-standard": "5.0.0",
|
|
59
59
|
"eslint-plugin-typescript": "0.14.0",
|
|
60
|
-
"hardhat": "2.
|
|
61
|
-
"hardhat-deploy": "0.10.5",
|
|
60
|
+
"hardhat": "2.9.3",
|
|
62
61
|
"hardhat-gas-reporter": "1.0.8",
|
|
63
62
|
"rimraf": "3.0.2",
|
|
64
63
|
"shx": "0.3.4",
|
|
65
|
-
"solc": "0.8.11",
|
|
66
64
|
"solhint": "3.3.7",
|
|
67
65
|
"solidity-coverage": "0.7.20",
|
|
68
|
-
"ts-node": "10.
|
|
66
|
+
"ts-node": "10.7.0",
|
|
69
67
|
"typechain": "7.0.0",
|
|
70
|
-
"typescript": "4.
|
|
68
|
+
"typescript": "4.6.3"
|
|
71
69
|
},
|
|
72
70
|
"bin": {
|
|
73
71
|
"solidity-utils-docify": "utils/docify.utils.js"
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# {{{name}}}
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
{{{natspec.title}}}
|
|
5
|
+
{{{natspec.userdoc}}}
|
|
6
|
+
{{{natspec.devdoc}}}
|
|
7
|
+
|
|
8
|
+
{{#if (withoutFirstElement inheritance)}}
|
|
9
|
+
## Derives
|
|
10
|
+
{{/if}}
|
|
11
|
+
{{#each (withoutFirstElement inheritance)}}
|
|
12
|
+
{{#if (getRelativeDocPath name source.contractsDir source.solcOutput.sources)}}
|
|
13
|
+
- [{{name}}]({{getRelativeDocPath name source.contractsDir source.solcOutput.sources}})
|
|
14
|
+
{{else}}
|
|
15
|
+
- {{name}}
|
|
16
|
+
{{/if}}
|
|
17
|
+
{{/each}}
|
|
18
|
+
|
|
19
|
+
{{#if ownFunctions}}
|
|
20
|
+
## Functions
|
|
21
|
+
{{/if}}
|
|
22
|
+
{{#ownFunctions}}
|
|
23
|
+
### {{name}}
|
|
24
|
+
```solidity
|
|
25
|
+
function {{name}}(
|
|
26
|
+
{{#args}}
|
|
27
|
+
{{type}} {{name}}{{#if @last}}{{else}},{{/if}}
|
|
28
|
+
{{/args}}
|
|
29
|
+
) {{visibility}}{{#if outputs}} returns ({{outputs}}){{/if}}
|
|
30
|
+
```
|
|
31
|
+
{{#if natspec.userdoc}}{{natspec.userdoc}}{{/if}}
|
|
32
|
+
{{#if natspec.devdoc}}{{natspec.devdoc}}{{/if}}
|
|
33
|
+
{{#if args}}
|
|
34
|
+
#### Parameters:
|
|
35
|
+
| Name | Type | Description |
|
|
36
|
+
| :--- | :--- | :------------------------------------------------------------------- |
|
|
37
|
+
{{#args}}
|
|
38
|
+
|`{{name}}` | {{type}} | {{#with (lookup ../natspec.params @index)~}} {{ removeNewlines description }} {{/with}}
|
|
39
|
+
{{/args}}{{/if}}
|
|
40
|
+
{{#if natspec.returns}}
|
|
41
|
+
#### Return Values:
|
|
42
|
+
| Name | Type | Description |
|
|
43
|
+
| :----------------------------- | :------------ | :--------------------------------------------------------------------------- |
|
|
44
|
+
{{#natspec.returns}}
|
|
45
|
+
|`{{param}}`| {{#lookup ../outputs.types @index}}{{/lookup}} | {{{removeNewlines description}}}
|
|
46
|
+
{{/natspec.returns}}{{/if}}
|
|
47
|
+
{{/ownFunctions}}
|
|
48
|
+
{{#if ownEvents}}
|
|
49
|
+
## Events
|
|
50
|
+
{{/if}}
|
|
51
|
+
{{#ownEvents}}
|
|
52
|
+
### {{name}}
|
|
53
|
+
```solidity
|
|
54
|
+
event {{name}}(
|
|
55
|
+
{{#args}}
|
|
56
|
+
{{type}} {{name}}{{#if @last}}{{else}},{{/if}}
|
|
57
|
+
{{/args}}
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
{{#if natspec.userdoc}}{{natspec.userdoc}}{{/if}}
|
|
61
|
+
{{#if natspec.devdoc}}{{natspec.devdoc}}{{/if}}
|
|
62
|
+
{{#if args}}
|
|
63
|
+
#### Parameters:
|
|
64
|
+
| Name | Type | Description |
|
|
65
|
+
| :--- | :--- | :------------------------------------------------------------------- |
|
|
66
|
+
{{#args}}
|
|
67
|
+
|`{{name}}` | {{type}} | {{#with (lookup ../natspec.params @index)~}} {{ removeNewlines description }} {{/with}}
|
|
68
|
+
{{/args}}{{/if}}
|
|
69
|
+
{{/ownEvents}}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
removeNewlines (str) {
|
|
3
|
+
return str.replace(/\r?\n/g, ' ');
|
|
4
|
+
},
|
|
5
|
+
withoutFirstElement (arr) {
|
|
6
|
+
return arr.splice(1);
|
|
7
|
+
},
|
|
8
|
+
getRelativeDocPath (contractName, contractsDir, sources) {
|
|
9
|
+
function getRelativePath (contractPath) {
|
|
10
|
+
if (contractPath){
|
|
11
|
+
if (contractPath.startsWith(contractsDir)) {
|
|
12
|
+
return contractPath.substr(contractsDir.length + 1).replace('.sol', '.md');
|
|
13
|
+
}
|
|
14
|
+
if (contractPath.startsWith('@openzeppelin')) {
|
|
15
|
+
const regexMatch = contractPath.match(/@openzeppelin\/contracts\/(.+)\/([^/]+)\.sol/);
|
|
16
|
+
return `https://docs.openzeppelin.com/contracts/3.x/api/${regexMatch[1]}#${regexMatch[2]}`;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const sourcesKeys = Object.keys(sources);
|
|
23
|
+
const contractPath = sourcesKeys.find(x => x.includes(contractName));
|
|
24
|
+
|
|
25
|
+
if (!contractPath){
|
|
26
|
+
console.log('WARNING: file ' + contractName + '.sol not found in source files.');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return getRelativePath(contractPath);
|
|
30
|
+
},
|
|
31
|
+
};
|