-
Notifications
You must be signed in to change notification settings - Fork 121
/
Copy path11_holograph_factory_tests.ts
317 lines (278 loc) · 11 KB
/
11_holograph_factory_tests.ts
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
import { generateRandomSalt, PreTest } from './utils';
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
import { expect } from 'chai';
import { ethers } from 'hardhat';
import setup from './utils';
import {
Signature,
StrictECDSA,
generateInitCode,
generateErc20Config,
generateErc721Config,
} from '../scripts/utils/helpers';
import { ALREADY_DEPLOYED_ERROR_MSG, INVALID_SIGNATURE_ERROR_MSG, ONLY_ADMIN_ERROR_MSG } from './utils/error_constants';
import { ConfigureEvents } from '../scripts/utils/events';
describe('Holograph Factory Contract', async () => {
let chain1: PreTest;
let chain2: PreTest;
let Mock: any;
let mock: any;
let accounts: SignerWithAddress[];
let deployer: SignerWithAddress;
let owner: SignerWithAddress;
let nonOwner: SignerWithAddress;
let mockSigner: SignerWithAddress;
let chainId: number;
let configObj: any;
let erc20Config: any;
let erc20ConfigHash: string;
let erc20ConfigHashBytes: any;
let signature: Signature;
before(async () => {
chain1 = await setup();
chain2 = await setup(true);
accounts = await ethers.getSigners();
deployer = accounts[0];
owner = accounts[1];
nonOwner = accounts[2];
chainId = (await ethers.provider.getNetwork()).chainId;
Mock = await ethers.getContractFactory('Mock');
mock = await Mock.deploy();
await mock.deployed();
mockSigner = await ethers.getSigner(mock.address);
configObj = await generateErc20Config(
chain1.network,
chain1.deployer.address,
'hToken',
chain1.network.tokenName + ' (Holographed #' + chain1.network.holographId.toString() + ')',
'h' + chain1.network.tokenSymbol,
chain1.network.tokenName + ' (Holographed #' + chain1.network.holographId.toString() + ')',
'1',
18,
ConfigureEvents([]),
generateInitCode(['address', 'uint16'], [chain1.deployer.address, 0]),
chain1.salt
);
erc20Config = configObj.erc20Config;
erc20ConfigHash = configObj.erc20ConfigHash;
erc20ConfigHashBytes = configObj.erc20ConfigHashBytes;
let hTokenErc20Address = await chain1.registry.getHolographedHashAddress(erc20ConfigHash);
hTokenErc20Address = await chain1.registry.getHolographedHashAddress(erc20ConfigHash);
let sig = await chain1.deployer.signMessage(erc20ConfigHashBytes);
signature = StrictECDSA({
r: '0x' + sig.substring(2, 66),
s: '0x' + sig.substring(66, 130),
v: '0x' + sig.substring(130, 132),
} as Signature);
});
describe('init():', async () => {
// Contracts are initialized in the PreTest setup
it('should fail if already initialized', async () => {
const initCode = generateInitCode(
['address', 'address'],
[chain1.holographFactory.address, chain1.holographRegistry.address]
);
await expect(chain1.holographFactory.connect(deployer).init(initCode)).to.be.revertedWith(
'HOLOGRAPH: already initialized'
);
});
});
describe('deployHolographableContract()', async () => {
it('should fail with invalid signature if config is incorrect', async () => {
await expect(
chain1.holographFactory.connect(deployer).deployHolographableContract(erc20Config, signature, owner.address)
).to.be.revertedWith(INVALID_SIGNATURE_ERROR_MSG);
});
it('should fail contract was already deployed', async () => {
await expect(
chain1.factory.deployHolographableContract(erc20Config, signature, chain1.deployer.address)
).to.be.revertedWith(ALREADY_DEPLOYED_ERROR_MSG);
});
it('should fail contract was already deployed', async () => {
await expect(
chain1.factory.deployHolographableContract(erc20Config, signature, chain1.deployer.address)
).to.be.revertedWith(ALREADY_DEPLOYED_ERROR_MSG);
});
it('should fail with invalid signature if signature.r is incorrect', async () => {
signature.r = `0x${'00'.repeat(32)}`;
await expect(
chain1.holographFactory.connect(deployer).deployHolographableContract(erc20Config, signature, owner.address)
).to.be.revertedWith(INVALID_SIGNATURE_ERROR_MSG);
});
it('should fail with invalid signature if signature.s is incorrect', async () => {
signature.s = `0x${'00'.repeat(32)}`;
await expect(
chain1.holographFactory.connect(deployer).deployHolographableContract(erc20Config, signature, owner.address)
).to.be.revertedWith(INVALID_SIGNATURE_ERROR_MSG);
});
it('should fail with invalid signature if signature.v is incorrect', async () => {
signature.v = `0x${'00'.repeat(32)}`;
await expect(
chain1.holographFactory.connect(deployer).deployHolographableContract(erc20Config, signature, owner.address)
).to.be.revertedWith(INVALID_SIGNATURE_ERROR_MSG);
});
it('should fail with invalid signature if signer is incorrect', async () => {
await expect(
chain1.factory.deployHolographableContract(erc20Config, signature, nonOwner.address)
).to.be.revertedWith(INVALID_SIGNATURE_ERROR_MSG);
});
it('Should allow external contract to call fn');
it('should fail to allow inherited contract to call fn');
});
describe(`bridgeIn()`, async () => {
it('should return the expected selector from the input payload', async () => {
let { erc721Config, erc721ConfigHashBytes } = await generateErc721Config(
chain1.network,
chain1.deployer.address,
'SampleERC721',
'Sample ERC721 Contract (' + chain1.hre.networkName + ')',
'SMPLR',
1000,
generateRandomSalt(),
generateInitCode(['address'], [chain1.deployer.address]),
generateRandomSalt()
);
let sig = await chain1.deployer.signMessage(erc721ConfigHashBytes);
signature = StrictECDSA({
r: '0x' + sig.substring(2, 66),
s: '0x' + sig.substring(66, 130),
v: '0x' + sig.substring(130, 132),
} as Signature);
const payload = generateInitCode(
['tuple(bytes32,uint32,bytes32,bytes,bytes)', 'tuple(bytes32,bytes32,uint8)', 'address'],
[
[
erc721Config.contractType,
erc721Config.chainType,
erc721Config.salt,
erc721Config.byteCode,
erc721Config.initCode,
],
[signature.r, signature.s, signature.v],
deployer.address,
]
);
const selector = await chain1.factory.connect(deployer).callStatic.bridgeIn(chainId, payload);
expect(selector).to.equal('0x08a1eb20');
});
it('should revert if payload data is invalid', async () => {
let { erc721ConfigHashBytes } = await generateErc721Config(
chain1.network,
chain1.deployer.address,
'SampleERC721',
'Sample ERC721 Contract (' + chain1.hre.networkName + ')',
'SMPLR',
1000,
generateRandomSalt(),
generateInitCode(['address'], [chain1.deployer.address]),
generateRandomSalt()
);
let sig = await chain1.deployer.signMessage(erc721ConfigHashBytes);
signature = StrictECDSA({
r: '0x' + sig.substring(2, 66),
s: '0x' + sig.substring(66, 130),
v: '0x' + sig.substring(130, 132),
} as Signature);
const payload = '0x' + '00'.repeat(32);
await expect(chain1.factory.connect(deployer).bridgeIn(chainId, payload)).to.be.reverted;
});
});
describe('bridgeOut()', async () => {
it('should return selector and payload', async function () {
let { erc721Config } = await generateErc721Config(
chain1.network,
chain1.deployer.address,
'SampleERC721',
'Sample ERC721 Contract (' + chain1.hre.networkName + ')',
'SMPLR',
1000,
`0x${'00'.repeat(32)}`,
generateInitCode(['address'], [chain1.deployer.address]),
chain1.salt
);
let sig = await chain1.deployer.signMessage(erc20ConfigHashBytes);
signature = StrictECDSA({
r: '0x' + sig.substring(2, 66),
s: '0x' + sig.substring(66, 130),
v: '0x' + sig.substring(130, 132),
} as Signature);
const payload = generateInitCode(
['tuple(bytes32,uint32,bytes32,bytes,bytes)', 'tuple(bytes32,bytes32,uint8)', 'address'],
[
[
erc721Config.contractType,
erc721Config.chainType,
erc721Config.salt,
erc721Config.byteCode,
erc721Config.initCode,
],
[signature.r, signature.s, signature.v],
deployer.address,
]
);
const selector = await chain1.factory.connect(owner).bridgeOut(1, deployer.address, payload);
expect(selector[0]).to.equal('0xb7e03661');
});
});
describe('setHolograph() / getHolograph()', async () => {
it('should allow admin to alter _holographSlot', async () => {
await chain1.holographFactory.setHolograph(chain1.holograph.address);
const _holographSlot = await chain1.holographFactory.getHolograph();
expect(_holographSlot).to.equal(chain1.holograph.address);
});
it('should fail to allow owner to alter _holographSlot', async () => {
await expect(chain1.holographFactory.connect(nonOwner).setHolograph(chain1.holograph.address)).to.be.revertedWith(
ONLY_ADMIN_ERROR_MSG
);
});
it('should fail to allow non-owner to alter _holographSlot', async () => {
await expect(
chain1.holographFactory.connect(nonOwner).setHolograph(chain1.holographRegistry.address)
).to.be.revertedWith(ONLY_ADMIN_ERROR_MSG);
});
});
describe('setRegistry() / getRegistry()', async () => {
it('should allow admin to alter _registrySlot', async () => {
await chain1.holographFactory.setRegistry(chain1.holographRegistry.address);
const _registrySlot = await chain1.holographFactory.getRegistry();
expect(_registrySlot).to.equal(chain1.holographRegistry.address);
});
it('should fail to allow owner to alter _registrySlot', async () => {
await expect(
chain1.holographFactory.connect(nonOwner).setRegistry(chain1.holographRegistry.address)
).to.be.revertedWith(ONLY_ADMIN_ERROR_MSG);
});
it('should fail to allow non-owner to alter _registrySlot', async () => {
await expect(
chain1.holographFactory.connect(nonOwner).setRegistry(chain1.holographRegistry.address)
).to.be.revertedWith(ONLY_ADMIN_ERROR_MSG);
});
});
describe.skip('_isContract()', async () => {
it('should not be callable', async () => {
// await expect(chain1.holographFactory._isContract()).to.be.throw;
});
});
describe.skip('_verifySigner()', async () => {
it('should not be callable');
});
describe(`receive()`, async () => {
it('should revert', async () => {
await expect(
deployer.sendTransaction({
to: chain1.holographFactory.address,
value: 1,
})
).to.be.reverted;
});
});
describe(`fallback()`, async () => {
it('should revert', async () => {
await expect(
deployer.sendTransaction({
to: chain1.holographFactory.address,
})
).to.be.reverted;
});
});
});