Skip to content

Commit

Permalink
improving test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
Noah Zinsmeister committed Nov 1, 2018
1 parent 72875cd commit c7c6be4
Show file tree
Hide file tree
Showing 7 changed files with 304 additions and 31 deletions.
8 changes: 6 additions & 2 deletions contracts/IdentityRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,12 @@ contract IdentityRegistry is SignatureVerifier {
/// @param check If true, ensures that the address has an Identity, if false, vice versa.
/// @return true if the associated status is equal to check, false otherwise.
modifier _hasIdentity(address _address, bool check) {
if (check && !hasIdentity(_address)) require(false, "The passed address does not have an identity.");
if (!check && hasIdentity(_address)) require(false, "The passed address has an identity.");
if (hasIdentity(_address) != check) {
if (check)
require(false, "The passed address does not have an identity but should.");
else
require(false, "The passed address has an identity but should not.");
}
_;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ contract ERC725RegistryResolver {
require(einTo725[ein] == address(0), "You already have a 725");

ClaimHolder claim = new ClaimHolder();
require(claim.addKey(keccak256(abi.encodePacked(msg.sender)), 1, 1), "Failed to add key.");
// TODO: change this if addKey implementation changes s.t. it can return false
claim.addKey(keccak256(abi.encodePacked(msg.sender)), 1, 1);

einTo725[ein] = claim;
return(claim);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"buidl": "rm -rf build/ && npx truffle compile",
"chain": "npx ganache-cli --port 8545 --seed hydro",
"test": "npx truffle test --network development",
"cover": "rm -f coverage.json && rm -rf coverage && npx solidity-coverage",
"cover": "rm -f scTopics && rm -f coverage.json && rm -rf coverage && npx solidity-coverage",
"chain-cover": "npx testrpc-sc --port 8555 -l 0xfffffffffff -g 0x01 --allowUnlimitedContractSize --seed hydro",
"test-cover": "npx truffle test --network coverage"
},
Expand Down
189 changes: 176 additions & 13 deletions test/IdentityRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const Web3 = require('web3')
const web3 = new Web3(Web3.givenProvider || 'http://localhost:8545')

const { sign, verifyIdentity, timeTravel, defaultErrorMessage } = require('./common')

const { getAddress, getSignature } = require('./signatures.js')
const IdentityRegistry = artifacts.require('./IdentityRegistry.sol')

const privateKeys = [
Expand Down Expand Up @@ -49,7 +49,7 @@ contract('Testing Identity', function (accounts) {
.catch(error => {
if (error.message !== defaultErrorMessage) {
assert.include(
error.message, 'The passed address does not have an identity.', 'wrong rejection reason'
error.message, 'The passed address does not have an identity but should.', 'wrong rejection reason'
)
}
})
Expand Down Expand Up @@ -305,23 +305,83 @@ contract('Testing Identity', function (accounts) {
}
})

it('provider can add other addresses -- FAIL too many', async function () {
const maxAddresses = await instances.IdentityRegistry.maxAssociatedAddresses.call()
for (let i = 0; i < maxAddresses; i++) {
const timestamp = Math.round(new Date() / 1000) - 1
const permissionStringApproving = web3.utils.soliditySha3(
'0x19', '0x00', instances.IdentityRegistry.address,
'I authorize adding this address to my Identity.',
identity.identity, getAddress(i), timestamp
)

const permissionString = web3.utils.soliditySha3(
'0x19', '0x00', instances.IdentityRegistry.address,
'I authorize being added to this Identity.',
identity.identity, getAddress(i), timestamp
)

const permissionApproving = await sign(
permissionStringApproving, identity.associatedAddresses[0].address, identity.associatedAddresses[0].private
)
const permission = await getSignature(permissionString, i)

if (i !== maxAddresses - 1) {
await instances.IdentityRegistry.addAddressDelegated(
identity.associatedAddresses[0].address, getAddress(i),
[permissionApproving.v, permission.v],
[permissionApproving.r, permission.r],
[permissionApproving.s, permission.s],
[timestamp, timestamp],
{ from: identity.providers[0].address }
)
} else {
await instances.IdentityRegistry.addAddressDelegated(
identity.associatedAddresses[0].address, getAddress(i),
[permissionApproving.v, permission.v],
[permissionApproving.r, permission.r],
[permissionApproving.s, permission.s],
[timestamp, timestamp],
{ from: identity.providers[0].address }
)
.then(() => assert.fail('able to set address', 'transaction should fail'))
.catch(error => assert.include(
error.message, 'Too many addresses.', 'wrong rejection reason'
))
}
}

// clean up by removing address
for (let i = 0; i < maxAddresses - 1; i++) {
const timestamp = Math.round(new Date() / 1000) - 1
const permissionString = web3.utils.soliditySha3(
'0x19', '0x00', instances.IdentityRegistry.address,
'I authorize removing this address from my Identity.',
identity.identity, getAddress(i), timestamp
)

const permission = await getSignature(permissionString, i)

await instances.IdentityRegistry.removeAddressDelegated(
getAddress(i), permission.v, permission.r, permission.s, timestamp,
{ from: identity.providers[0].address }
)
}
})

it('provider can add other addresses', async function () {
for (const address of [identity.associatedAddresses[1], identity.associatedAddresses[2], accountsPrivate[5]]) {
const timestamp = Math.round(new Date() / 1000) - 1
const permissionStringApproving = web3.utils.soliditySha3(
'0x19', '0x00', instances.IdentityRegistry.address,
'I authorize adding this address to my Identity.',
identity.identity,
address.address,
timestamp
identity.identity, address.address, timestamp
)

const permissionString = web3.utils.soliditySha3(
'0x19', '0x00', instances.IdentityRegistry.address,
'I authorize being added to this Identity.',
identity.identity,
address.address,
timestamp
identity.identity, address.address, timestamp
)

const permissionApproving = await sign(
Expand Down Expand Up @@ -357,7 +417,7 @@ contract('Testing Identity', function (accounts) {
}
})

it('provider can remove addresses -- not provider', async function () {
it('provider can remove addresses -- FAIL not provider', async function () {
const address = accountsPrivate[5]
const timestamp = Math.round(new Date() / 1000) - 1
const permissionString = web3.utils.soliditySha3(
Expand All @@ -380,7 +440,7 @@ contract('Testing Identity', function (accounts) {
))
})

it('provider can remove addresses -- signature', async function () {
it('provider can remove addresses -- FAIL signature', async function () {
const address = accountsPrivate[5]
const timestamp = Math.round(new Date() / 1000) - 1
const permissionString = web3.utils.soliditySha3(
Expand Down Expand Up @@ -429,16 +489,27 @@ contract('Testing Identity', function (accounts) {
})
})

it('identity can add a provider', async function () {
const provider = accountsPrivate[6]

const provider = accountsPrivate[6]
it('identity can add a provider itself', async function () {
await Promise.all(identity.associatedAddresses.map(({ address }) => {
return instances.IdentityRegistry.addProviders.call(
[provider.address],
{ from: address }
)
}))
})

it('provider can add a provider for -- FAIL', async function () {
await instances.IdentityRegistry.addProvidersFor(
identity.identity, [provider.address], { from: accounts[0] }
)
.then(() => assert.fail('should not be able to add a provider from a non-provider', 'transaction should fail'))
.catch(error => assert.include(
error.message, 'The identity has not set the passed provider.', 'wrong rejection reason'
))
})

it('provider can add a provider for', async function () {
await instances.IdentityRegistry.addProvidersFor(
identity.identity, [provider.address], { from: identity.providers[0].address }
)
Expand Down Expand Up @@ -515,6 +586,25 @@ contract('Testing Identity', function (accounts) {
let futureNewAssociatedAddressPermission
const twoWeeks = 60 * 60 * 24 * 14

it('Could recover', async function () {
const newAssociatedAddress = accountsPrivate[9]
const timestamp = Math.round(new Date() / 1000) - 1
const permissionString = web3.utils.soliditySha3(
'0x19', '0x00', instances.IdentityRegistry.address,
'I authorize being added to this Identity via recovery.',
identity.identity, newAssociatedAddress.address, timestamp
)
const newAssociatedAddressPermission = await sign(
permissionString, newAssociatedAddress.address, newAssociatedAddress.private
)

await instances.IdentityRegistry.triggerRecovery.call(
identity.identity, newAssociatedAddress.address,
newAssociatedAddressPermission.v, newAssociatedAddressPermission.r, newAssociatedAddressPermission.s, timestamp,
{ from: identity.recoveryAddress.address }
)
})

it('Can trigger change in recovery address', async function () {
newRecoveryAddress = accountsPrivate[8]

Expand Down Expand Up @@ -600,6 +690,37 @@ contract('Testing Identity', function (accounts) {
})
})

it('Recently removed recovery address can trigger recovery -- FAIL signature', async function () {
instances.IdentityRegistry
.RecoveryTriggered()
.once('data', event => {
oldAssociatedAddresses = event.returnValues.oldAssociatedAddresses
})

await instances.IdentityRegistry.triggerRecovery(
identity.identity, newAssociatedAddress.address,
0, futureNewAssociatedAddressPermission.r,
futureNewAssociatedAddressPermission.s, futureTimestamp,
{ from: newRecoveryAddress.address }
)
.then(() => assert.fail('recovery was triggered', 'transaction should fail'))
.catch(error => assert.include(
error.message, 'Permission denied.', 'wrong rejection reason'
))
})

it('Cannot trigger poison pill', async function () {
await instances.IdentityRegistry.triggerPoisonPill.call(identity.identity, [], [], true, { from: accounts[0] })
.then(() => assert.fail('old recovery address triggered recovery', 'transaction should fail'))
.catch(error => {
if (error.message !== defaultErrorMessage) {
assert.include(
error.message, 'Recovery has not recently been triggered.', 'wrong rejection reason'
)
}
})
})

it('Recently removed recovery address can trigger recovery', async function () {
instances.IdentityRegistry
.RecoveryTriggered()
Expand All @@ -621,6 +742,28 @@ contract('Testing Identity', function (accounts) {
resolvers: []
})
})

it('Recently removed recovery address can trigger recovery -- FAIL too soon', async function () {
const newAssociatedAddress = accountsPrivate[8]
const timestamp = Math.round(new Date() / 1000) + twoWeeks - 1
const permissionString = web3.utils.soliditySha3(
'0x19', '0x00', instances.IdentityRegistry.address,
'I authorize being added to this Identity via recovery.',
identity.identity, newAssociatedAddress.address, timestamp
)
const newAssociatedAddressPermission = await sign(
permissionString, newAssociatedAddress.address, newAssociatedAddress.private
)

await instances.IdentityRegistry.triggerRecovery(
identity.identity, newAssociatedAddress.address,
newAssociatedAddressPermission.v, newAssociatedAddressPermission.r,
newAssociatedAddressPermission.s, timestamp,
{ from: newRecoveryAddress.address }
)
.then(() => assert.fail('recovery was triggered after recently recovering', 'transaction should fail'))
.catch(error => assert.include(error.message, 'Cannot trigger recovery yet.', 'wrong rejection reason'))
})
})

describe('Testing Poison Pill', function () {
Expand All @@ -637,6 +780,26 @@ contract('Testing Identity', function (accounts) {
}))
})

it('Any of the recently removed address can trigger poison pill -- FAIL', async function () {
const indexOf = oldAssociatedAddresses.indexOf(oldAssociatedAddresses[0])
const firstChunk = oldAssociatedAddresses.slice(0, indexOf)
const lastChunk = oldAssociatedAddresses.slice(indexOf + 1)

await instances.IdentityRegistry.triggerPoisonPill.call(
identity.identity, firstChunk, lastChunk, true, { from: accounts[0] }
)
.then(() => assert.fail('recovery was triggered after recently recovering', 'transaction should fail'))
.catch(error => {
if (error.message !== defaultErrorMessage) {
assert.include(
error.message,
'Cannot activate the poison pill from an address that was not recently removed via recovery.',
'wrong rejection reason'
)
}
})
})

it('Triggering poison pill on an identity works as expected', async function () {
const indexOf = oldAssociatedAddresses.indexOf(identity.associatedAddresses[1].address)

Expand Down
Loading

0 comments on commit c7c6be4

Please sign in to comment.