Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixes
  • Loading branch information
azavalla committed Nov 30, 2017
commit 12f9b120e812816752d38b8675776685a811284c
24 changes: 15 additions & 9 deletions contracts/ownership/Inheritable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ import './Ownable.sol';
contract Inheritable is Ownable {
address public heir;

// Time window the owner has to notify she is alive.
// Time window the owner has to notify they are alive.
uint public heartbeatTimeout;

// Timestamp of the owner's death, as pronounced by the heir.
uint public timeOfDeath;


event OwnerPronouncedDead(address indexed owner, address indexed heir, uint indexed timeOfDeath);
event HeirChanged(address indexed owner, address indexed newHeir);
event OwnerHeartbeated(address indexed owner);
event OwnerPronouncedDead(address indexed owner, address indexed heir, uint timeOfDeath);


/**
Expand All @@ -34,22 +36,25 @@ contract Inheritable is Ownable {

/**
* @notice Create a new Inheritable Contract with heir address 0x0.
* @param _heartbeatTimeout time available for the owner to notify she's alive,
* @param _heartbeatTimeout time available for the owner to notify they are alive,
* before the heir can take ownership.
*/
function Inheritable(uint _heartbeatTimeout) public {
heartbeatTimeout = _heartbeatTimeout;
}

function setHeir(address newHeir) public onlyOwner {
heartbeat();
HeirChanged(owner, newHeir);
heir = newHeir;
}

/**
* @dev set heir = 0x0
*/
function removeHeir() public onlyOwner {
delete(heir);
heartbeat();
heir = 0;
}

function setHeartbeatTimeout(uint newHeartbeatTimeout) public onlyOwner {
Expand All @@ -58,20 +63,21 @@ contract Inheritable is Ownable {
}

/**
* @dev Heir can pronounce the owners death. To inherit the ownership, he will
* @dev Heir can pronounce the owners death. To inherit the ownership, they will
* have to wait for `heartbeatTimeout` seconds.
*/
function pronounceDeath() public onlyHeir {
require(ownerLives());
timeOfDeath = now;
OwnerPronouncedDead(owner, heir, timeOfDeath);
timeOfDeath = now;
}

/**
* @dev Owner can send a heartbeat if she was mistakenly pronounced dead.
* @dev Owner can send a heartbeat if they were mistakenly pronounced dead.
*/
function heartbeat() public onlyOwner {
delete(timeOfDeath);
OwnerHeartbeated(owner);
timeOfDeath = 0;
}

/**
Expand All @@ -82,7 +88,7 @@ contract Inheritable is Ownable {
require(now >= timeOfDeath + heartbeatTimeout);
OwnershipTransferred(owner, heir);
owner = heir;
delete(timeOfDeath);
timeOfDeath = 0;
}

function ownerLives() internal returns (bool) {
Expand Down
32 changes: 25 additions & 7 deletions test/Inheritable.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ contract('Inheritable', function(accounts) {
assert.isTrue(heir === NULL_ADDRESS)
})

it('owner can set heartbeatTimeout only if she\'s alive', async function() {
it('owner can set heartbeatTimeout only if they are alive', async function() {
const newTimeout = 41414141
await inheritable.setHeartbeatTimeout(newTimeout, {from: owner})

Expand Down Expand Up @@ -127,13 +127,31 @@ contract('Inheritable', function(accounts) {
}
})

it('should log owner dead and ownership transfer', async function() {
it('should log events appropriately', async function() {
const heir = accounts[1]
await inheritable.setHeir(heir, {from: owner})
const { logs } = await inheritable.pronounceDeath({from: heir})
const event = logs.find(e => e.event === 'OwnerPronouncedDead')

assert.isTrue(event.args.owner === owner)
assert.isTrue(event.args.heir === heir)
const setHeirLogs = (await inheritable.setHeir(heir, {from: owner})).logs
const setHeirEvent = setHeirLogs.find(e => e.event === 'HeirChanged')

assert.isTrue(setHeirEvent.args.owner === owner)
assert.isTrue(setHeirEvent.args.newHeir === heir)

const heartbeatLogs = (await inheritable.heartbeat({from: owner})).logs
const heartbeatEvent = heartbeatLogs.find(e => e.event === 'OwnerHeartbeated')

assert.isTrue(heartbeatEvent.args.owner === owner)

const pronounceDeathLogs = (await inheritable.pronounceDeath({from: heir})).logs
const ownerDeadEvent = pronounceDeathLogs.find(e => e.event === 'OwnerPronouncedDead')

assert.isTrue(ownerDeadEvent.args.owner === owner)
assert.isTrue(ownerDeadEvent.args.heir === heir)

const inheritLogs = (await inheritable.inherit({from: heir})).logs
const ownershipTransferredEvent = inheritLogs.find(e => e.event === 'OwnershipTransferred')

assert.isTrue(ownershipTransferredEvent.args.previousOwner === owner)
assert.isTrue(ownershipTransferredEvent.args.newOwner === heir)

})
})