github.com/codingfuture/orig-energi3@v0.8.4/energi/contracts/test/Gen2Migration.spec.js (about) 1 // Copyright 2019 The Energi Core Authors 2 // This file is part of the Energi Core library. 3 // 4 // The Energi Core library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The Energi Core library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Energi Governance system is the fundamental part of Energi Core. 18 19 'use strict'; 20 21 const Gen2Migration = artifacts.require('Gen2Migration'); 22 const MockGen2Migration = artifacts.require('MockGen2Migration'); 23 const MockGen2MigrationBlacklist = artifacts.require('MockGen2MigrationBlacklist'); 24 const MockProxy = artifacts.require('MockProxy'); 25 const BlacklistRegistryV1 = artifacts.require('BlacklistRegistryV1'); 26 27 const common = require('./common'); 28 const ethjs = require('ethereumjs-util'); 29 30 contract("Gen2Migration", async accounts => { 31 let orig; 32 let blacklist_registry; 33 34 before(async () => { 35 const blacklist_proxy = await MockProxy.new(); 36 37 orig = await MockGen2Migration.new( 38 blacklist_proxy.address, common.chain_id, accounts[0]); 39 40 blacklist_registry = await BlacklistRegistryV1.deployed(); 41 blacklist_registry = await MockGen2MigrationBlacklist.new( 42 blacklist_proxy.address, await blacklist_registry.mnregistry_proxy(), 43 orig.address, await blacklist_registry.compensation_fund(), 44 accounts[9], 45 { gas: "10000000" }); 46 await blacklist_proxy.setImpl(blacklist_registry.address); 47 }); 48 49 after(async () => { 50 await Gen2Migration.new( 51 blacklist_registry.address, common.chain_id, common.migration_signer); 52 }); 53 54 // Primary stuff 55 //--- 56 const { toBN, toWei } = web3.utils; 57 58 const acc1 = web3.eth.accounts.create(); 59 const acc2 = web3.eth.accounts.create(); 60 const acc3 = web3.eth.accounts.create(); 61 const owner1 = acc1.address; 62 const owner2 = acc2.address; 63 const owner3 = acc3.address; 64 const dst = accounts[1]; 65 66 const bal1 = toBN(toWei('100', 'ether')); 67 const bal2 = toBN(toWei('200', 'ether')); 68 const bal3 = toBN(toWei('300', 'ether')); 69 70 const ecsign = (acc, hash) => { 71 const sig = ethjs.ecsign( 72 toBN(hash).toArrayLike(Buffer), 73 toBN(acc.privateKey).toArrayLike(Buffer) 74 ); 75 return [sig.v, '0x'+sig.r.toString('hex'), '0x'+sig.s.toString('hex')]; 76 }; 77 78 it('should correctly reflect itemCount()', async () => { 79 await orig.setCoins([ 80 owner1, 81 owner2, 82 owner3, 83 ], [ 84 bal1, 85 bal2, 86 bal3, 87 ], [], { value: bal1.add(bal2).add(bal3) }); 88 89 expect((await orig.itemCount()).toString()).equal(toBN(3).toString()); 90 91 const c = await orig.coins(1); 92 expect(c.amount.toString()).equal(bal2.toString()); 93 expect(toBN(c.owner).toString()).equal(toBN(owner2).toString()); 94 }); 95 96 it('should correctly create hashToSign()', async () => { 97 const hash = await orig.hashToSign(dst); 98 const reqhash = web3.utils.soliditySha3( 99 dst, 100 "||Energi Gen 2 migration claim||", 101 toBN(common.chain_id) 102 ); 103 expect(hash.toString()).equal(reqhash.toString()); 104 }); 105 106 it('should refuse to claim() on invalid item ID', async () => { 107 try { 108 await orig.verifyClaim(4, dst, 0, '0x00', '0x00'); 109 assert.fail('It must fail'); 110 } catch (e) { 111 assert.match(e.message, /Invalid ID/); 112 } 113 }); 114 115 it('should refuse to claim() on invalid signature', async () => { 116 try { 117 await orig.verifyClaim(1, dst, 0, '0x00', '0x00'); 118 assert.fail('It must fail'); 119 } catch (e) { 120 assert.match(e.message, /Invalid signature/); 121 } 122 }); 123 124 it('should refuse to blacklistClaim() on invalid ID', async() => { 125 try { 126 await orig.blacklistClaim(3, dst); 127 assert.fail('It must fail'); 128 } catch (e) { 129 assert.match(e.message, /Invalid ID/); 130 } 131 }); 132 133 it('should refuse to blacklistClaim() on invalid owner', async() => { 134 try { 135 await orig.blacklistClaim(1, owner3); 136 assert.fail('It must fail'); 137 } catch (e) { 138 assert.match(e.message, /Invalid Owner/); 139 } 140 }); 141 142 it('should verifyClaim()', async () => { 143 const hash = await orig.hashToSign(dst); 144 await orig.verifyClaim(1, dst, ...ecsign(acc2, hash)); 145 }); 146 147 it('should refuse claim() to claim blacklisted', async () => { 148 await blacklist_registry.setBlacklisted(owner2, true); 149 150 try { 151 const hash = await orig.hashToSign(dst); 152 await orig.claim(1, dst, ...ecsign(acc2, hash), common.zerofee_callopts); 153 assert.fail('It must fail'); 154 } catch (e) { 155 assert.match(e.message, /Owner is blacklisted/); 156 } finally { 157 await blacklist_registry.setBlacklisted(owner2, false); 158 } 159 }); 160 161 it('should claim()', async () => { 162 const bal_before = await web3.eth.getBalance(dst); 163 164 const hash = await orig.hashToSign(dst); 165 await orig.claim(1, dst, ...ecsign(acc2, hash), common.zerofee_callopts); 166 167 const bal_after = await web3.eth.getBalance(dst); 168 expect(toBN(bal_after).sub(toBN(bal_before)).toString()).equal(bal2.toString()); 169 170 const evt = await orig.getPastEvents('Migrated', common.evt_last_block); 171 expect(evt).lengthOf(1); 172 common.stringifyBN(web3, evt[0].args); 173 expect(evt[0].args).deep.include({ 174 '0': '1', 175 '1': dst, 176 '2': bal2.toString(), 177 '__length__': 3, 178 'item_id': '1', 179 'destination': dst, 180 'amount': bal2.toString() 181 }); 182 }); 183 184 it('should refuse to claim() again', async () => { 185 const hash = await orig.hashToSign(dst); 186 187 try { 188 await orig.claim(1, dst, ...ecsign(acc2, hash), common.zerofee_callopts); 189 assert.fail('It must fail'); 190 } catch (e) { 191 assert.match(e.message, /Already spent/); 192 } 193 194 const evt = await orig.getPastEvents('Migrated', common.evt_last_block); 195 expect(evt).lengthOf(0); 196 }); 197 198 it('should refuse to blacklistClaim() on spent', async() => { 199 try { 200 await orig.blacklistClaim(1, owner2); 201 assert.fail('It must fail'); 202 } catch (e) { 203 assert.match(e.message, /Already spent/); 204 } 205 }); 206 207 it('should claim() another account', async () => { 208 const hash = await orig.hashToSign(dst); 209 await orig.claim(0, dst, ...ecsign(acc1, hash), common.zerofee_callopts); 210 }); 211 212 it('should refuse to blacklistClaim() not by blacklist', async() => { 213 try { 214 await orig.blacklistClaim(2, owner3); 215 assert.fail('It must fail'); 216 } catch (e) { 217 assert.match(e.message, /Not blacklist registry/); 218 } 219 }); 220 221 it('should refuse claim() on hard blacklist', async () => { 222 try { 223 await orig.setCoins([ 224 owner1, 225 owner2, 226 owner3, 227 ], [ 228 bal1, 229 bal2, 230 bal3, 231 ], [ owner3 ]); 232 233 const hash = await orig.hashToSign(dst); 234 await orig.claim(2, dst, ...ecsign(acc3, hash), common.zerofee_callopts); 235 assert.fail('It must fail'); 236 } catch (e) { 237 assert.match(e.message, /Owner is hard blacklisted/); 238 } 239 }); 240 241 it('should allow to blacklistClaim() by Blacklist', async() => { 242 const fund = await blacklist_registry.compensation_fund(); 243 const bal_before = await web3.eth.getBalance(fund); 244 await blacklist_registry.drainMigration(2, owner3); 245 const bal_after = await web3.eth.getBalance(fund); 246 expect(toBN(bal_after).sub(toBN(bal_before)).toString()).equal(bal3.toString()); 247 }); 248 249 it('should signerAddress()', async () => { 250 const signer = await orig.signerAddress(); 251 expect(signer).equal(accounts[0]); 252 }); 253 254 it('should totalAmount()', async () => { 255 const total = await orig.totalAmount(); 256 expect(total.toString()).equal(bal1.add(bal2).add(bal3).toString()); 257 }); 258 259 // Safety & Cleanup 260 //--- 261 it('should refuse to accept funds', async () => { 262 try { 263 await orig.send(web3.utils.toWei('1', "ether")); 264 assert.fail("It must fail"); 265 } catch (e) { 266 assert.match(e.message, /Not supported/); 267 } 268 }); 269 });