Merge branch 'master' into fix/reference-of-rbac-usage
This commit is contained in:
40
contracts/examples/SimpleSavingsWallet.sol
Normal file
40
contracts/examples/SimpleSavingsWallet.sol
Normal file
@ -0,0 +1,40 @@
|
||||
pragma solidity ^0.4.11;
|
||||
|
||||
import "../ownership/Heritable.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title SimpleSavingsWallet
|
||||
* @dev Simplest form of savings wallet whose ownership can be claimed by a heir
|
||||
* if owner dies.
|
||||
* In this example, we take a very simple savings wallet providing two operations
|
||||
* (to send and receive funds) and extend its capabilities by making it Heritable.
|
||||
* The account that creates the contract is set as owner, who has the authority to
|
||||
* choose an heir account. Heir account can reclaim the contract ownership in the
|
||||
* case that the owner dies.
|
||||
*/
|
||||
contract SimpleSavingsWallet is Heritable {
|
||||
|
||||
event Sent(address indexed payee, uint256 amount, uint256 balance);
|
||||
event Received(address indexed payer, uint256 amount, uint256 balance);
|
||||
|
||||
|
||||
function SimpleSavingsWallet(uint256 _heartbeatTimeout) Heritable(_heartbeatTimeout) public {}
|
||||
|
||||
/**
|
||||
* @dev wallet can receive funds.
|
||||
*/
|
||||
function () public payable {
|
||||
Received(msg.sender, msg.value, this.balance);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev wallet can send funds
|
||||
*/
|
||||
function sendTo(address payee, uint256 amount) public onlyOwner {
|
||||
require(payee != 0 && payee != address(this));
|
||||
require(amount > 0);
|
||||
payee.transfer(amount);
|
||||
Sent(payee, amount, this.balance);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import "../ownership/Ownable.sol";
|
||||
import "../token/ERC20Basic.sol";
|
||||
import "../token/ERC20/ERC20Basic.sol";
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import "../token/StandardToken.sol";
|
||||
import "../token/DetailedERC20.sol";
|
||||
import "../token/ERC20/DetailedERC20.sol";
|
||||
|
||||
|
||||
contract DetailedERC20Mock is StandardToken, DetailedERC20 {
|
||||
|
||||
@ -4,20 +4,19 @@ pragma solidity ^0.4.18;
|
||||
import "../token/BasicToken.sol";
|
||||
|
||||
|
||||
contract ERC23ContractInterface {
|
||||
contract ERC223ContractInterface {
|
||||
function tokenFallback(address _from, uint256 _value, bytes _data) external;
|
||||
}
|
||||
|
||||
contract ERC223TokenMock is BasicToken {
|
||||
|
||||
contract ERC23TokenMock is BasicToken {
|
||||
|
||||
function ERC23TokenMock(address initialAccount, uint256 initialBalance) public {
|
||||
function ERC223TokenMock(address initialAccount, uint256 initialBalance) public {
|
||||
balances[initialAccount] = initialBalance;
|
||||
totalSupply = initialBalance;
|
||||
}
|
||||
|
||||
// ERC23 compatible transfer function (except the name)
|
||||
function transferERC23(address _to, uint256 _value, bytes _data) public
|
||||
// ERC223 compatible transfer function (except the name)
|
||||
function transferERC223(address _to, uint256 _value, bytes _data) public
|
||||
returns (bool success)
|
||||
{
|
||||
transfer(_to, _value);
|
||||
@ -26,7 +25,7 @@ contract ERC23TokenMock is BasicToken {
|
||||
is_contract := not(iszero(extcodesize(_to)))
|
||||
}
|
||||
if (is_contract) {
|
||||
ERC23ContractInterface receiver = ERC23ContractInterface(_to);
|
||||
ERC223ContractInterface receiver = ERC223ContractInterface(_to);
|
||||
receiver.tokenFallback(msg.sender, _value, _data);
|
||||
}
|
||||
return true;
|
||||
@ -1,7 +1,7 @@
|
||||
pragma solidity ^0.4.13;
|
||||
|
||||
|
||||
import "../token/ERC827Token.sol";
|
||||
import "../token/ERC827/ERC827Token.sol";
|
||||
|
||||
|
||||
// mock class using ERC827 Token
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import "../token/ERC20.sol";
|
||||
import "../token/SafeERC20.sol";
|
||||
import "../token/ERC20/ERC20.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
|
||||
|
||||
contract ERC20FailingMock is ERC20 {
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import "./Ownable.sol";
|
||||
import "../token/ERC20Basic.sol";
|
||||
import "../token/SafeERC20.sol";
|
||||
import "../token/ERC20/ERC20Basic.sol";
|
||||
import "../token/ERC20/SafeERC20.sol";
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -6,14 +6,14 @@ import "./CanReclaimToken.sol";
|
||||
/**
|
||||
* @title Contracts that should not own Tokens
|
||||
* @author Remco Bloemen <remco@2π.com>
|
||||
* @dev This blocks incoming ERC23 tokens to prevent accidental loss of tokens.
|
||||
* @dev This blocks incoming ERC223 tokens to prevent accidental loss of tokens.
|
||||
* Should tokens (any ERC20Basic compatible) end up in the contract, it allows the
|
||||
* owner to reclaim the tokens.
|
||||
*/
|
||||
contract HasNoTokens is CanReclaimToken {
|
||||
|
||||
/**
|
||||
* @dev Reject all ERC23 compatible tokens
|
||||
* @dev Reject all ERC223 compatible tokens
|
||||
* @param from_ address The address that is transferring the tokens
|
||||
* @param value_ uint256 the amount of the specified token
|
||||
* @param data_ Bytes The data passed from the caller.
|
||||
|
||||
99
contracts/ownership/Heritable.sol
Normal file
99
contracts/ownership/Heritable.sol
Normal file
@ -0,0 +1,99 @@
|
||||
pragma solidity ^0.4.11;
|
||||
|
||||
|
||||
import "./Ownable.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @title Heritable
|
||||
* @dev The Heritable contract provides ownership transfer capabilities, in the
|
||||
* case that the current owner stops "heartbeating". Only the heir can pronounce the
|
||||
* owner's death.
|
||||
*/
|
||||
contract Heritable is Ownable {
|
||||
address public heir;
|
||||
|
||||
// Time window the owner has to notify they are alive.
|
||||
uint256 public heartbeatTimeout;
|
||||
|
||||
// Timestamp of the owner's death, as pronounced by the heir.
|
||||
uint256 public timeOfDeath;
|
||||
|
||||
event HeirChanged(address indexed owner, address indexed newHeir);
|
||||
event OwnerHeartbeated(address indexed owner);
|
||||
event OwnerProclaimedDead(address indexed owner, address indexed heir, uint256 timeOfDeath);
|
||||
event HeirOwnershipClaimed(address indexed previousOwner, address indexed newOwner);
|
||||
|
||||
|
||||
/**
|
||||
* @dev Throw an exception if called by any account other than the heir's.
|
||||
*/
|
||||
modifier onlyHeir() {
|
||||
require(msg.sender == heir);
|
||||
_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notice Create a new Heritable Contract with heir address 0x0.
|
||||
* @param _heartbeatTimeout time available for the owner to notify they are alive,
|
||||
* before the heir can take ownership.
|
||||
*/
|
||||
function Heritable(uint256 _heartbeatTimeout) public {
|
||||
setHeartbeatTimeout(_heartbeatTimeout);
|
||||
}
|
||||
|
||||
function setHeir(address newHeir) public onlyOwner {
|
||||
require(newHeir != owner);
|
||||
heartbeat();
|
||||
HeirChanged(owner, newHeir);
|
||||
heir = newHeir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev set heir = 0x0
|
||||
*/
|
||||
function removeHeir() public onlyOwner {
|
||||
heartbeat();
|
||||
heir = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Heir can pronounce the owners death. To claim the ownership, they will
|
||||
* have to wait for `heartbeatTimeout` seconds.
|
||||
*/
|
||||
function proclaimDeath() public onlyHeir {
|
||||
require(ownerLives());
|
||||
OwnerProclaimedDead(owner, heir, timeOfDeath);
|
||||
timeOfDeath = now;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Owner can send a heartbeat if they were mistakenly pronounced dead.
|
||||
*/
|
||||
function heartbeat() public onlyOwner {
|
||||
OwnerHeartbeated(owner);
|
||||
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;
|
||||
}
|
||||
|
||||
function setHeartbeatTimeout(uint256 newHeartbeatTimeout) internal onlyOwner {
|
||||
require(ownerLives());
|
||||
heartbeatTimeout = newHeartbeatTimeout;
|
||||
}
|
||||
|
||||
function ownerLives() internal view returns (bool) {
|
||||
return timeOfDeath == 0;
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
|
||||
import "./ERC20Basic.sol";
|
||||
import "./ERC20/ERC20Basic.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
pragma solidity ^0.4.13;
|
||||
|
||||
|
||||
import "./ERC20.sol";
|
||||
import "../ERC20/ERC20.sol";
|
||||
|
||||
|
||||
/**
|
||||
@ -1,7 +1,7 @@
|
||||
pragma solidity ^0.4.13;
|
||||
|
||||
import "./ERC827.sol";
|
||||
import "./StandardToken.sol";
|
||||
import "../StandardToken.sol";
|
||||
|
||||
/**
|
||||
@title ERC827, an extension of ERC20 token standard
|
||||
@ -2,7 +2,7 @@ pragma solidity ^0.4.18;
|
||||
|
||||
|
||||
import "./BasicToken.sol";
|
||||
import "./ERC20.sol";
|
||||
import "./ERC20/ERC20.sol";
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import "./ERC20Basic.sol";
|
||||
import "../token/SafeERC20.sol";
|
||||
import "./ERC20/SafeERC20.sol";
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
pragma solidity ^0.4.18;
|
||||
|
||||
import "./ERC20Basic.sol";
|
||||
import "./SafeERC20.sol";
|
||||
import "./ERC20/ERC20Basic.sol";
|
||||
import "./ERC20/SafeERC20.sol";
|
||||
import "../ownership/Ownable.sol";
|
||||
import "../math/SafeMath.sol";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user