Skip to content
48 changes: 32 additions & 16 deletions contracts/ownership/Heritable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import "./Ownable.sol";
* owner's death.
*/
contract Heritable is Ownable {
address public heir;
address private heir_;

// Time window the owner has to notify they are alive.
uint256 public heartbeatTimeout;
uint256 private heartbeatTimeout_;

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

event HeirChanged(address indexed owner, address indexed newHeir);
event OwnerHeartbeated(address indexed owner);
Expand All @@ -29,7 +29,7 @@ contract Heritable is Ownable {
* @dev Throw an exception if called by any account other than the heir's.
*/
modifier onlyHeir() {
require(msg.sender == heir);
require(msg.sender == heir_);
_;
}

Expand All @@ -47,15 +47,31 @@ contract Heritable is Ownable {
require(newHeir != owner);
heartbeat();
HeirChanged(owner, newHeir);
heir = newHeir;
heir_ = newHeir;
}

/**
* @dev Use these getter functions to access the internal variables in
* an inherited contract.
*/
function heir() public view returns(address) {
return heir_;
}

function heartbeatTimeout() public view returns(uint256) {
return heartbeatTimeout_;
}

function timeOfDeath() public view returns(uint256) {
return timeOfDeath_;
}

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

/**
Expand All @@ -64,36 +80,36 @@ contract Heritable is Ownable {
*/
function proclaimDeath() public onlyHeir {
require(ownerLives());
OwnerProclaimedDead(owner, heir, timeOfDeath);
timeOfDeath = now;
OwnerProclaimedDead(owner, heir_, timeOfDeath_);
timeOfDeath_ = block.timestamp;
}

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

/**
* @dev Allows heir to transfer ownership only if heartbeat has timed out.
*/
function claimHeirOwnership() public onlyHeir {
require(!ownerLives());
require(now >= timeOfDeath + heartbeatTimeout);
OwnershipTransferred(owner, heir);
HeirOwnershipClaimed(owner, heir);
owner = heir;
timeOfDeath = 0;
require(block.timestamp >= timeOfDeath_ + heartbeatTimeout_);
OwnershipTransferred(owner, heir_);
HeirOwnershipClaimed(owner, heir_);
owner = heir_;
timeOfDeath_ = 0;
}

function setHeartbeatTimeout(uint256 newHeartbeatTimeout) internal onlyOwner {
require(ownerLives());
heartbeatTimeout = newHeartbeatTimeout;
heartbeatTimeout_ = newHeartbeatTimeout;
}

function ownerLives() internal view returns (bool) {
return timeOfDeath == 0;
return timeOfDeath_ == 0;
}
}