mirror of
https://github.com/status-im/snt-gas-relay.git
synced 2025-02-28 05:30:28 +00:00
- Fixing typo in Identity.sol
- Reorganizing javascript files used in tests - Cleaned up unit tests - Created identityUtils.js to encode function calls sent in execute();
This commit is contained in:
parent
3c4f2ab7d1
commit
5ee487a48a
@ -138,7 +138,7 @@ contract Identity is ERC725, ERC735 {
|
||||
}
|
||||
}
|
||||
|
||||
function setMininumApprovalsByKeyType(
|
||||
function setMinimumApprovalsByKeyType(
|
||||
uint256 _type,
|
||||
uint8 _minimumApprovals
|
||||
)
|
||||
|
@ -1,4 +1,5 @@
|
||||
const TestUtils = require("./TestUtils.js")
|
||||
const TestUtils = require("../utils/testUtils.js")
|
||||
const idUtils = require("../utils/identityUtils.js")
|
||||
const web3EthAbi = require("web3-eth-abi");
|
||||
|
||||
const Identity = artifacts.require("./identity/Identity.sol");
|
||||
@ -27,15 +28,18 @@ contract('IdentityFactory', function(accounts) {
|
||||
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[0])),
|
||||
1,
|
||||
idUtils.purposes.MANAGEMENT,
|
||||
identity.address + ".getKeyPurpose("+accounts[0]+") is not MANAGEMENT_KEY")
|
||||
});
|
||||
|
||||
|
||||
it("Registers a updated identity contract", async() => {
|
||||
const infoHash = "0xbbb";
|
||||
updatedIdentityKernel = await UpdatedIdentityKernel.new({from: accounts[0]});
|
||||
let tx = await identityFactory.setKernel(updatedIdentityKernel.address, "0xbbb");
|
||||
assert.strictEqual(tx.logs[0].event, "NewKernel");
|
||||
await identityFactory.setKernel(updatedIdentityKernel.address, infoHash);
|
||||
|
||||
const newKernel = await TestUtils.listenForEvent(identityFactory.NewKernel());
|
||||
assert(newKernel.infohash, infoHash, "Infohash is not correct");
|
||||
});
|
||||
|
||||
|
||||
@ -58,16 +62,12 @@ contract('IdentityFactory', function(accounts) {
|
||||
|
||||
|
||||
it("Updates an identity to the latest version", async() => {
|
||||
let functionPayload = web3EthAbi.encodeFunctionCall({
|
||||
name: 'updateUpdatableInstance',
|
||||
type: 'function',
|
||||
inputs: [{
|
||||
type: 'address',
|
||||
name: '_kernel'
|
||||
}]
|
||||
}, [updatedIdentityKernel.address]);
|
||||
|
||||
let tx1 = await identity.execute(identity.address, 0, functionPayload, {from: accounts[0]} );
|
||||
let tx1 = await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.updateUpdatableInstance(updatedIdentityKernel.address),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
assert.strictEqual(tx1.logs[tx1.logs.length - 1].event, "Executed");
|
||||
|
||||
// Calling function available in updated identity kernel
|
||||
@ -75,7 +75,6 @@ contract('IdentityFactory', function(accounts) {
|
||||
let tx2 = await updatedIdentity1.test({from: accounts[0]});
|
||||
|
||||
assert.strictEqual(tx2.logs[tx2.logs.length - 1].event, "TestFunctionExecuted");
|
||||
|
||||
assert.equal(
|
||||
tx2.logs[tx2.logs.length - 1].args.minApprovalsByManagementKeys.toString(10),
|
||||
1,
|
||||
|
208
test/identity.js
208
test/identity.js
@ -1,4 +1,7 @@
|
||||
const TestUtils = require("./TestUtils.js")
|
||||
const TestUtils = require("../utils/testUtils.js")
|
||||
const web3EthAbi = require("web3-eth-abi");
|
||||
const idUtils = require('../utils/identityUtils.js');
|
||||
|
||||
const Identity = artifacts.require("./identity/Identity.sol");
|
||||
|
||||
contract('Identity', function(accounts) {
|
||||
@ -9,129 +12,200 @@ contract('Identity', function(accounts) {
|
||||
identity = await Identity.new({from: accounts[0]})
|
||||
})
|
||||
|
||||
|
||||
describe("Identity()", () => {
|
||||
it("initialize with msg.sender as management key", async () => {
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[0])),
|
||||
1,
|
||||
idUtils.purposes.MANAGEMENT,
|
||||
identity.address + ".getKeyPurpose("+accounts[0]+") is not MANAGEMENT_KEY")
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe("addKey(address _key, uint256 _type)", () => {
|
||||
|
||||
it("MANAGEMENT_KEY add a new address as ACTION_KEY", async () => {
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[1]), 2, 1, {from: accounts[0]})
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[1], idUtils.purposes.ACTION, idUtils.types.ADDRESS),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[1])),
|
||||
2,
|
||||
idUtils.purposes.ACTION,
|
||||
identity.address+".getKeyPurpose("+accounts[1]+") is not ACTION_KEY")
|
||||
});
|
||||
|
||||
|
||||
it("should not add key by non manager", async () => {
|
||||
try {
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[1]), 1, 1, {from: accounts[2]})
|
||||
}catch(e){
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[1], idUtils.purposes.MANAGEMENT, idUtils.types.ADDRESS),
|
||||
{from: accounts[2]}
|
||||
);
|
||||
assert.fail('should have reverted before');
|
||||
} catch(error) {
|
||||
TestUtils.assertJump(error);
|
||||
}
|
||||
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[1])),
|
||||
0,
|
||||
idUtils.purposes.NONE,
|
||||
identity.address+".getKeyPurpose("+accounts[1]+") is not correct")
|
||||
});
|
||||
|
||||
it("should not add key type 1 by actor", async () => {
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[2]), 2, 1, {from: accounts[0]})
|
||||
try {
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[1]), 1, 1, {from: accounts[2]})
|
||||
} catch(e){
|
||||
}
|
||||
it("should not add key type 1 by actor", async () => {
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[2], idUtils.purposes.ACTION, idUtils.types.ADDRESS),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[1], idUtils.purposes.MANAGEMENT, idUtils.types.ADDRESS),
|
||||
{from: accounts[2]}
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[1])),
|
||||
0,
|
||||
idUtils.purposes.NONE,
|
||||
identity.address+".getKeyType("+accounts[1]+") is not correct")
|
||||
});
|
||||
|
||||
|
||||
|
||||
it("fire KeyAdded(address indexed key, uint256 indexed type)", async () => {
|
||||
identity.addKey(TestUtils.addressToBytes32(accounts[1]), 2, 1, {from: accounts[0]})
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[1], idUtils.purposes.MANAGEMENT, idUtils.types.ADDRESS),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
const keyAdded = await TestUtils.listenForEvent(identity.KeyAdded())
|
||||
assert(keyAdded.key, TestUtils.addressToBytes32(accounts[1]), "Key is not correct")
|
||||
assert(keyAdded.keyType, 2, "Type is not correct")
|
||||
assert(keyAdded.keyType, idUtils.types.ADDRESS, "Type is not correct")
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe("removeKey(address _key, uint256 _type)", () => {
|
||||
it("MANAGEMENT_KEY should remove a key", async () => {
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[1], idUtils.purposes.MANAGEMENT, idUtils.types.ADDRESS),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
it("MANAGEMENT_KEY should removes a key", async () => {
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[1]), 1, 1, {from: accounts[0]})
|
||||
await identity.removeKey(TestUtils.addressToBytes32(accounts[0]), 1, {from: accounts[1]})
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[0])),
|
||||
0,
|
||||
identity.address+".getKeyPurpose("+accounts[0]+") is not 0")
|
||||
});
|
||||
|
||||
|
||||
it("other key should not removes a key", async () => {
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[1]), 1, 1, {from: accounts[0]})
|
||||
try {
|
||||
await identity.removeKey(TestUtils.addressToBytes32(accounts[1]), 1, {from: accounts[2]})
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.removeKey(accounts[1], idUtils.purposes.MANAGEMENT),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[1])),
|
||||
1,
|
||||
idUtils.purposes.NONE,
|
||||
identity.address+".getKeyPurpose("+accounts[1]+") is not 0")
|
||||
});
|
||||
|
||||
it("other key should not removes a key", async () => {
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[1], idUtils.purposes.MANAGEMENT, idUtils.types.ADDRESS),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
try {
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.removeKey(accounts[1], idUtils.purposes.MANAGEMENT),
|
||||
{from: accounts[2]}
|
||||
);
|
||||
assert.fail('should have reverted before');
|
||||
} catch(error) {
|
||||
TestUtils.assertJump(error);
|
||||
}
|
||||
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[1])),
|
||||
idUtils.purposes.MANAGEMENT,
|
||||
identity.address+".getKeyPurpose("+accounts[1]+") is not 0")
|
||||
});
|
||||
|
||||
it("actor key should not remove key", async () => {
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[1]), 2, 1, {from: accounts[0]})
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[2]), 2, 1, {from: accounts[0]})
|
||||
try {
|
||||
await identity.removeKey(TestUtils.addressToBytes32(accounts[1]), 1, {from: accounts[2]})
|
||||
}catch (e) {
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[1], idUtils.purposes.ACTION, idUtils.types.ADDRESS),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[2], idUtils.purposes.ACTION, idUtils.types.ADDRESS),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.removeKey(accounts[1], idUtils.purposes.ACTION),
|
||||
{from: accounts[2]}
|
||||
);
|
||||
|
||||
}
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[1])),
|
||||
2,
|
||||
idUtils.purposes.ACTION,
|
||||
identity.address+".getKeyType("+accounts[1]+") is not 0")
|
||||
});
|
||||
|
||||
|
||||
it("MANAGEMENT_KEY should not remove itself MANAGEMENT_KEY when there is no other MANAGEMENT_KEY", async () => {
|
||||
let assertJump = (error) => {
|
||||
assert.isAbove(error.message.search('revert'), -1, 'Revert should happen');
|
||||
}
|
||||
try {
|
||||
await identity.removeKey(TestUtils.addressToBytes32(accounts[0]), 1, {from: accounts[0]});
|
||||
assert.fail('should have reverted before');
|
||||
} catch(error) {
|
||||
assertJump(error);
|
||||
}
|
||||
|
||||
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.removeKey(accounts[0], idUtils.purposes.MANAGEMENT),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
assert.equal(
|
||||
await identity.getKeyPurpose(TestUtils.addressToBytes32(accounts[0])),
|
||||
idUtils.purposes.MANAGEMENT,
|
||||
identity.address+".getKeyType("+accounts[0]+") is not 1")
|
||||
});
|
||||
|
||||
it("fire KeyRemoved(address indexed key, uint256 indexed type)", async () => {
|
||||
await identity.addKey(TestUtils.addressToBytes32(accounts[1]), 2, 1,{from: accounts[0]})
|
||||
identity.removeKey(TestUtils.addressToBytes32(accounts[1]), 2, {from: accounts[0]})
|
||||
const keyRemoved = await TestUtils.listenForEvent(identity.KeyRemoved())
|
||||
assert(keyRemoved.key, TestUtils.addressToBytes32(accounts[1]), "Key is not correct")
|
||||
assert(keyRemoved.keyType, 2, "Type is not correct")
|
||||
});
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.addKey(accounts[1], idUtils.purposes.ACTION, idUtils.types.ADDRESS),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
await identity.execute(
|
||||
identity.address,
|
||||
0,
|
||||
idUtils.encode.removeKey(accounts[1], idUtils.purposes.ACTION),
|
||||
{from: accounts[0]}
|
||||
);
|
||||
|
||||
const keyRemoved = await TestUtils.listenForEvent(identity.KeyRemoved());
|
||||
assert(keyRemoved.key, TestUtils.addressToBytes32(accounts[1]), "Key is not correct");
|
||||
assert(keyRemoved.keyType, idUtils.types.ADDRESS, "Type is not correct");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
/*
|
||||
describe("getKeyPurpose(address _key)", () => {
|
||||
|
||||
it("should start only with initializer as only key", async () => {
|
||||
@ -259,5 +333,5 @@ contract('Identity', function(accounts) {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
*/
|
||||
});
|
||||
|
@ -1,9 +1,9 @@
|
||||
const TestUtils = require("./TestUtils.js")
|
||||
const TestUtils = require("../utils/testUtils.js")
|
||||
var ethUtils = require('ethereumjs-util')
|
||||
|
||||
const Identity = artifacts.require("./identity/Identity.sol");
|
||||
|
||||
contract('Identity', function(accounts) {
|
||||
contract('Identity - Extended Functionality', function(accounts) {
|
||||
|
||||
let identity;
|
||||
|
||||
|
133
utils/identityUtils.js
Normal file
133
utils/identityUtils.js
Normal file
@ -0,0 +1,133 @@
|
||||
const web3EthAbi = require("web3-eth-abi");
|
||||
|
||||
const _types = {
|
||||
ADDRESS: 0,
|
||||
ECDSA: 1,
|
||||
RSA: 2
|
||||
}
|
||||
|
||||
const _purposes = {
|
||||
MANAGEMENT: 1,
|
||||
ACTION: 2,
|
||||
CLAIM_SIGNER: 3,
|
||||
ENCRYPTION: 4,
|
||||
|
||||
NONE: 0
|
||||
}
|
||||
|
||||
const hexToBytes32 = (input) => {
|
||||
input = input.replace(/^0x/i,'');
|
||||
const stringed = "0000000000000000000000000000000000000000000000000000000000000000" + input;
|
||||
return "0x" + stringed.substring(stringed.length - 64, stringed.length);
|
||||
}
|
||||
|
||||
const _addKey = function(key, purpose, type){
|
||||
if(!/^(0x)?[0-9a-f]{0,64}$/i.test(key))
|
||||
throw new Error('Key "'+ key +'" is not a valid hex string');
|
||||
|
||||
if (Object.values(_purposes).indexOf(purpose) == -1)
|
||||
throw new Error('Purpose "'+ purpose +'" is not a valid purpose');
|
||||
|
||||
if (Object.values(_types).indexOf(type) == -1)
|
||||
throw new Error('Type "'+ type +'" is not a valid type');
|
||||
|
||||
return web3EthAbi.encodeFunctionCall({
|
||||
name: 'addKey',
|
||||
type: 'function',
|
||||
inputs: [{
|
||||
type: 'bytes32',
|
||||
name: '_key'
|
||||
},{
|
||||
type: 'uint256',
|
||||
name: '_purpose'
|
||||
},{
|
||||
type: 'uint256',
|
||||
name: '_type'
|
||||
}]
|
||||
}, [hexToBytes32(key), purpose, type]);
|
||||
}
|
||||
|
||||
const _removeKey = function(key, purpose){
|
||||
if(!/^(0x)?[0-9a-f]{0,64}$/i.test(key))
|
||||
throw new Error('Key "'+ key +'" is not a valid hex string');
|
||||
|
||||
if (Object.values(_purposes).indexOf(purpose) == -1)
|
||||
throw new Error('Purpose "'+ purpose +'" is not a valid purpose');
|
||||
|
||||
return web3EthAbi.encodeFunctionCall({
|
||||
name: 'removeKey',
|
||||
type: 'function',
|
||||
inputs: [{
|
||||
type: 'bytes32',
|
||||
name: '_key'
|
||||
},{
|
||||
type: 'uint256',
|
||||
name: '_purpose'
|
||||
}]
|
||||
}, [hexToBytes32(key), purpose]);
|
||||
}
|
||||
|
||||
|
||||
const _setMinimumApprovalsByKeyType = function(type, minimumApprovals) {
|
||||
|
||||
if (Object.values(_types).indexOf(type) == -1)
|
||||
throw new Error('Type "'+ type +'" is not a valid type');
|
||||
|
||||
// TODO valdate minimumApprovals
|
||||
|
||||
return web3EthAbi.encodeFunctionCall({
|
||||
name: 'setMinimumApprovalsByKeyType',
|
||||
type: 'function',
|
||||
inputs: [{
|
||||
type: 'uint256',
|
||||
name: '_type'
|
||||
},{
|
||||
type: 'uint8',
|
||||
name: '_minimumApprovals'
|
||||
}]
|
||||
}, arguments);
|
||||
}
|
||||
|
||||
|
||||
const _setupRecovery = function(address){
|
||||
if(!/^(0x)?[0-9a-f]{0,40}$/i.test(address))
|
||||
throw new Error('Address "'+ address +'" is not a valid Ethereum address.');
|
||||
|
||||
return web3EthAbi.encodeFunctionCall({
|
||||
name: 'setupRecovery',
|
||||
type: 'function',
|
||||
inputs: [{
|
||||
type: 'address',
|
||||
name: '_recoveryContract'
|
||||
}]
|
||||
}, [address]);
|
||||
}
|
||||
|
||||
const _updateUpdatableInstance = function(address){
|
||||
if(!/^(0x)?[0-9a-f]{0,40}$/i.test(address))
|
||||
throw new Error('Address "'+ address +'" is not a valid Ethereum address.');
|
||||
|
||||
return web3EthAbi.encodeFunctionCall({
|
||||
name: 'updateUpdatableInstance',
|
||||
type: 'function',
|
||||
inputs: [{
|
||||
type: 'address',
|
||||
name: '_kernel'
|
||||
}]
|
||||
}, [address]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
types: _types,
|
||||
purposes: _purposes,
|
||||
encode: {
|
||||
addKey: _addKey,
|
||||
removeKey: _removeKey,
|
||||
setMinimumApprovalsByKeyType: _setMinimumApprovalsByKeyType,
|
||||
setupRecovery: _setupRecovery,
|
||||
updateUpdatableInstance: _updateUpdatableInstance
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user