UNPKG

mixbytes-solidity

Version:

Generic solidity smart-contracts

221 lines (167 loc) 9.83 kB
'use strict'; // testrpc has to be run as testrpc -u 0 -u 1 -u 2 -u 3 import {expectThrow} from 'openzeppelin-solidity/test/helpers/expectThrow'; const multiowned = artifacts.require("./multiowned.sol"); const l = console.log; contract('multiowned', function(accounts) { async function freshInstance(required=2) { return multiowned.new([accounts[0], accounts[1], accounts[2]], required, {from: accounts[0]}); } function skipHexPrefix(str) { return str.match(/^0[xX]/) ? str.substring(2) : str; } function paddedArg(str) { // pad to bytes32 return str.padStart(64, '0'); } const changeOwnerSelector = skipHexPrefix(web3.sha3('changeOwner(address,address)')).substring(0, 8); // Make calldata for changeOwner function and get its hash, which is used as an operation key function makeChangeOwnerOpHash(_from, _to) { /* requires web3 1.0+ web3.eth.abi.encodeFunctionCall({"constant":false, "inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}], "name":"changeOwner", "outputs":[], "payable":false,"stateMutability":"nonpayable","type":"function" }, [accounts[1], accounts[3]]); */ return web3.sha3(changeOwnerSelector + paddedArg(skipHexPrefix(_from)) + paddedArg(skipHexPrefix(_to)), {encoding: 'hex'}); } async function getOwners(instance) { const totalOwners = (await instance.m_numOwners()).toNumber(); const calls = []; for (let i = 0; i < totalOwners; i++) calls.push(instance.getOwner(i)); return Promise.all(calls); } it("ctor check", async function() { await expectThrow(multiowned.new([accounts[0], accounts[1], accounts[2]], 20, {from: accounts[0]})); await expectThrow(multiowned.new([accounts[0], accounts[1], accounts[0]], 1, {from: accounts[0]})); await expectThrow(multiowned.new([accounts[0], accounts[1], 0], 1, {from: accounts[0]})); let instance = await multiowned.new([accounts[0]], 1, {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0]]); instance = await multiowned.new([accounts[0], accounts[1]], 2, {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1]]); instance = await freshInstance(); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]]); assert.deepEqual(await instance.getOwners(), [accounts[0], accounts[1], accounts[2]]); }); it("changeOwner check", async function() { const instance = await freshInstance(1); await expectThrow(instance.changeOwner(accounts[1], accounts[3], {from: accounts[3]})); await expectThrow(instance.changeOwner('0x0000000000000000000000000000000000000012', accounts[3], {from: accounts[0]})); await expectThrow(instance.changeOwner(accounts[1], accounts[2], {from: accounts[0]})); await instance.changeOwner(accounts[1], accounts[3], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[3], accounts[2]]); }); it("double-signed changeOwner check", async function() { const instance = await freshInstance(); // first signature await instance.changeOwner(accounts[1], accounts[3], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); // makes no sense to sign again, accounts[0]! await instance.changeOwner(accounts[1], accounts[3], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); // second signature await instance.changeOwner(accounts[1], accounts[3], {from: accounts[2]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[3], accounts[2]], 'owners has been changed'); }); it("addOwner check", async function() { const instance = await freshInstance(1); await expectThrow(instance.addOwner(accounts[3], {from: accounts[3]})); await expectThrow(instance.addOwner(accounts[1], {from: accounts[0]})); await instance.addOwner(accounts[3], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2], accounts[3]]); }); it("removeOwner check", async function() { const instance = await freshInstance(1); await expectThrow(instance.removeOwner(accounts[1], {from: accounts[3]})); await expectThrow(instance.removeOwner(accounts[3], {from: accounts[0]})); await instance.removeOwner(accounts[1], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[2]]); }); it("isOwner check", async function() { const instance = await freshInstance(); assert(await instance.isOwner(accounts[0])); assert(await instance.isOwner(accounts[1])); assert(await instance.isOwner(accounts[2])); assert(false === (await instance.isOwner(accounts[3]))); assert(false === (await instance.isOwner('0x12'))); }); it("amIOwner check", async function() { const instance = await freshInstance(); assert(await instance.amIOwner({from: accounts[0]})); assert(await instance.amIOwner({from: accounts[1]})); assert(await instance.amIOwner({from: accounts[2]})); await expectThrow(instance.amIOwner({from: accounts[3]})); await expectThrow(instance.amIOwner({from: '0x0000000000000000000000000000000000000012'})); }); it("changeRequirement check", async function() { const instance = await freshInstance(1); await expectThrow(instance.changeRequirement(2, {from: accounts[3]})); await expectThrow(instance.changeRequirement(0, {from: accounts[0]})); await expectThrow(instance.changeRequirement(4, {from: accounts[0]})); await instance.changeRequirement(3, {from: accounts[0]}); assert.equal(await instance.m_multiOwnedRequired(), 3); }); it("revoke check", async function() { const instance = await freshInstance(); // first signature await instance.changeOwner(accounts[1], accounts[3], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); const opHash = makeChangeOwnerOpHash(accounts[1], accounts[3]); assert(await instance.hasConfirmed(opHash, accounts[0])); assert(! await instance.hasConfirmed(opHash, accounts[2])); // revoke-confirm await instance.revoke(opHash, {from: accounts[0]}); await instance.changeOwner(accounts[1], accounts[3], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); assert(await instance.hasConfirmed(opHash, accounts[0])); assert(! await instance.hasConfirmed(opHash, accounts[2])); await expectThrow(instance.revoke(opHash, {from: accounts[3]})); // revoke await instance.revoke(opHash, {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); assert(! await instance.hasConfirmed(opHash, accounts[0])); assert(! await instance.hasConfirmed(opHash, accounts[2])); // second signature (but first was revoked!) await instance.changeOwner(accounts[1], accounts[3], {from: accounts[2]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); assert(! await instance.hasConfirmed(opHash, accounts[0])); assert(await instance.hasConfirmed(opHash, accounts[2])); }); it("complex (3 sigs required) check", async function() { const instance = await freshInstance(3); const opHash = makeChangeOwnerOpHash(accounts[1], accounts[3]); // first signature await instance.changeOwner(accounts[1], accounts[3], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); await instance.changeOwner(accounts[1], accounts[3], {from: accounts[1]}); assert(await instance.hasConfirmed(opHash, accounts[0])); assert(await instance.hasConfirmed(opHash, accounts[1])); assert(! await instance.hasConfirmed(opHash, accounts[2])); await instance.revoke(opHash, {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); assert(! await instance.hasConfirmed(opHash, accounts[0])); assert(await instance.hasConfirmed(opHash, accounts[1])); assert(! await instance.hasConfirmed(opHash, accounts[2])); // second signature (but first was revoked!) await instance.changeOwner(accounts[1], accounts[3], {from: accounts[2]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[1], accounts[2]], 'owners are the same'); assert(! await instance.hasConfirmed(opHash, accounts[0])); assert(await instance.hasConfirmed(opHash, accounts[1])); assert(await instance.hasConfirmed(opHash, accounts[2])); // finally changing owner await instance.changeOwner(accounts[1], accounts[3], {from: accounts[0]}); assert.deepEqual(await getOwners(instance), [accounts[0], accounts[3], accounts[2]]); }); });