Skip to content

Commit

Permalink
Init project with OwnableWithGuardian contract
Browse files Browse the repository at this point in the history
  • Loading branch information
gjgd committed Nov 9, 2018
0 parents commit 1ed09f0
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/
node_modules/
23 changes: 23 additions & 0 deletions contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma solidity ^0.4.23;

contract Migrations {
address public owner;
uint public last_completed_migration;

constructor() public {
owner = msg.sender;
}

modifier restricted() {
if (msg.sender == owner) _;
}

function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}

function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
78 changes: 78 additions & 0 deletions contracts/OwnableWithGuardian.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
pragma solidity ^0.4.24;

import "zeppelin-solidity/contracts/ownership/Ownable.sol";

/**
* @title OwnableWithGuardian
* @dev OwnableWithGuardian is an extension of the standard Ownable pattern that provides a trustless
* mechanism for recovering the ownership of a contract in the event of a loss of private keys
*/
contract OwnableWithGuardian is Ownable {
address public guardian;

// Challenge period's length is roughly one week
uint public CHALLENGE_PERIOD_LENGTH = 5760 * 7;
uint public endOfChallengePeriod;

event OwnershipRecoveryInitiated();

/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyGuardian() {
require(msg.sender == guardian);
_;
}

/**
* @dev Allows the current guardian to start an ownership recovery procedure
* This starts a challenge period of length CHALLENGE_PERIOD_LENGTH
* after which the guardian will be able to call recoverOwnership
*/
function initiateOwnershipRecovery() external onlyGuardian {
endOfChallengePeriod = block.number + CHALLENGE_PERIOD_LENGTH;
emit OwnershipRecoveryInitiated();
}

/**
* @dev Allows the current guardian to transfer ownership to a new address
* after the challenge period is over.
* The assumption is that if the owner hasn't called cancelOwnershipRecovery
* at this point, it means he lost his private keys and trusts that the guardian
* will give him ownership back on his _newOwner address
* @param _newOwner The new address of the owner
* (or the address of the new owner...)
*/
function recoverOwnership(address _newOwner) external onlyGuardian {
require(
endOfChallengePeriod > 0,
'Cannot call recoverOwnership before initiateOwnershipRecovery()'
);
require(
block.number >= endOfChallengePeriod,
'Cannot call recoverOwnership before the end of the challenge period'
);
// Reset challenge period so that recoverOwnership cannot be called
// without calling initiateOwnershipRecovery again
endOfChallengePeriod = 0;
// This method is from the Ownable contract
_transferOwnership(_newOwner);
}

/**
* @dev Allows the current owner to nominate a guardian for the contract
* @param _guardian The address of the guardian
*/
function setGuardian(address _guardian) external onlyOwner {
guardian = _guardian;
}

/**
* @dev Allows the current owner to cancel an ownership recovery procedure
* if owner is still in control of his private keys
*/
function cancelOwnershipRecovery() external onlyOwner {
// Reset challenge period so that recoverOwnership cannot be called
endOfChallengePeriod = 0;
}
}
7 changes: 7 additions & 0 deletions migrations/1_initial_migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const Migrations = artifacts.require("./Migrations.sol");
const OwnableWithGuardian = artifacts.require("./OwnableWithGuardian.sol");

module.exports = function(deployer) {
deployer.deploy(Migrations);
deployer.deploy(OwnableWithGuardian);
};
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "contract-guardian",
"version": "1.0.0",
"description": "",
"main": "truffle-config.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "truffle test"
},
"author": "[email protected]",
"dependencies": {
"zeppelin-solidity": "^1.12.0"
}
}
9 changes: 9 additions & 0 deletions truffle-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
networks: {
local: {
host: 'localhost',
port: 8545,
network_id: '*',
}
}
};
9 changes: 9 additions & 0 deletions truffle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
networks: {
local: {
host: 'localhost',
port: 8545,
network_id: '*',
}
}
};

0 comments on commit 1ed09f0

Please sign in to comment.