|
1 | 1 | const ethUtil = require('ethereumjs-util');
|
| 2 | +const ethAbi = require('ethereumjs-abi'); |
| 3 | +const Buffer = require('safe-buffer').Buffer; |
| 4 | +const utils = require('./utils'); |
2 | 5 |
|
3 |
| -const erc725CoreInterfaceID = '0xd202158d'; |
4 |
| -const erc725InterfaceID = '0xdc3d2a7b'; |
| 6 | +// bytes4(keccak256("isValidSignature(bytes32,bytes)") |
| 7 | +const ERC1271_METHOD_SIG = '1626ba7e'; |
5 | 8 |
|
6 | 9 | module.exports = class MockContract {
|
7 | 10 | constructor(options) {
|
8 |
| - this.isSupportsERC725CoreInterface = options.isSupportsERC725CoreInterface; |
9 |
| - this.isSupportsERC725Interface = options.isSupportsERC725Interface; |
10 |
| - this.actionableKey = options.actionableKey; |
11 |
| - this.errorOnIsSupportedContract = options.errorOnIsSupportedContract; |
12 |
| - this.errorOnKeyHasPurpose = options.errorOnKeyHasPurpose; |
| 11 | + this.authorizedKey = options.authorizedKey; |
| 12 | + this.address = options.address; |
| 13 | + this.errorIsValidSignature = options.errorIsValidSignature; |
13 | 14 | }
|
14 | 15 |
|
15 | 16 | static _true() {
|
16 |
| - return '0x0000000000000000000000000000000000000000000000000000000000000001'; |
| 17 | + return `0x${ERC1271_METHOD_SIG}00000000000000000000000000000000000000000000000000000000`; // a.k.a the "magic value". |
17 | 18 | }
|
18 | 19 |
|
19 | 20 | static _false(callback) {
|
20 | 21 | return '0x0000000000000000000000000000000000000000000000000000000000000000';
|
21 | 22 | }
|
22 | 23 |
|
| 24 | + // @param {String} methodCall |
| 25 | + // @param {String} methodParams |
| 26 | + // @return {String} |
23 | 27 | run(methodCall, methodParams) {
|
24 | 28 | switch (methodCall) {
|
25 |
| - case '01ffc9a7': |
26 |
| - return this._01ffc9a7(`0x${methodParams.substring(0, 4 * 2)}`); |
27 |
| - case 'd202158d': |
28 |
| - return this._d202158d(`0x${methodParams.substring(0, 32 * 2)}`); |
| 29 | + case ERC1271_METHOD_SIG: |
| 30 | + const [hash, signature] = ethAbi.rawDecode( |
| 31 | + ['bytes32', 'bytes'], |
| 32 | + Buffer.from(methodParams, 'hex'), |
| 33 | + ); |
| 34 | + |
| 35 | + return this._1626ba7e(hash, signature); |
29 | 36 | default:
|
30 | 37 | throw new Error(`Unexpected method ${methodCall}`);
|
31 | 38 | }
|
32 | 39 | }
|
33 | 40 |
|
34 |
| - // "isSupportedContract" method call |
35 |
| - _01ffc9a7(interfaceID) { |
36 |
| - if (this.errorOnIsSupportedContract) { |
37 |
| - throw new Error('isSupportedContract call returned an error'); |
38 |
| - } |
39 |
| - |
40 |
| - if ( |
41 |
| - this.isSupportsERC725CoreInterface && |
42 |
| - interfaceID === erc725CoreInterfaceID |
43 |
| - ) { |
44 |
| - return MockContract._true(); |
45 |
| - } |
46 |
| - |
47 |
| - if (this.isSupportsERC725Interface && interfaceID === erc725InterfaceID) { |
48 |
| - return MockContract._true(); |
| 41 | + // "isValidSignature" method call |
| 42 | + // @param {Buffer} hash |
| 43 | + // @param {Buffer} signature |
| 44 | + // @return {String} |
| 45 | + _1626ba7e(hash, signature) { |
| 46 | + if (this.errorIsValidSignature) { |
| 47 | + throw new Error('isValidSignature call returned an error'); |
49 | 48 | }
|
50 | 49 |
|
51 |
| - return MockContract._false(); |
52 |
| - } |
| 50 | + // Get the address of whoever signed this message |
| 51 | + const { v, r, s } = ethUtil.fromRpcSig(signature); |
| 52 | + const erc191MessageHash = utils.erc191MessageHash(hash, this.address); |
| 53 | + const recoveredKey = ethUtil.ecrecover(erc191MessageHash, v, r, s); |
| 54 | + const recoveredAddress = ethUtil.publicToAddress(recoveredKey); |
53 | 55 |
|
54 |
| - // "keyHasPurpose" method call |
55 |
| - _d202158d(key) { |
56 |
| - if (this.errorOnKeyHasPurpose) { |
57 |
| - throw new Error('keyHasPurpose call returned an error'); |
58 |
| - } |
| 56 | + const expectedAddress = ethUtil.publicToAddress(this.authorizedKey); |
59 | 57 |
|
60 |
| - if (key === ethUtil.bufferToHex(ethUtil.keccak(this.actionableKey))) { |
| 58 | + if (recoveredAddress.toString() === expectedAddress.toString()) { |
61 | 59 | return MockContract._true();
|
62 | 60 | }
|
63 | 61 |
|
|
0 commit comments