From ebd40a58e4b8da54ee2c61cdfb84802c721afe69 Mon Sep 17 00:00:00 2001 From: JG Carvalho Date: Mon, 10 Jul 2017 19:34:39 -0300 Subject: [PATCH] Decoposing the scheme into three distincts contracts --- contracts/ownership/Will.sol | 63 ------------------- contracts/ownership/Will/Identity.sol | 47 ++++++++++++++ contracts/ownership/Will/LifeCheck.sol | 87 ++++++++++++++++++++++++++ contracts/ownership/Will/Will.sol | 72 +++++++++++++++++++++ 4 files changed, 206 insertions(+), 63 deletions(-) delete mode 100644 contracts/ownership/Will.sol create mode 100644 contracts/ownership/Will/Identity.sol create mode 100644 contracts/ownership/Will/LifeCheck.sol create mode 100644 contracts/ownership/Will/Will.sol diff --git a/contracts/ownership/Will.sol b/contracts/ownership/Will.sol deleted file mode 100644 index 65015e2d3..000000000 --- a/contracts/ownership/Will.sol +++ /dev/null @@ -1,63 +0,0 @@ -pragma solidity ^0.4.8; - -import "./Ownable.sol"; - -contract Will is Ownable{ - - uint public maxPingInterval = 2 days; - uint lastPingTime; - Heir[] heirs; - - modifier onlyOwner() { - if (msg.sender != owner) { - throw; - } - _; - lastPingTime = now; - } - - function Will(){ - lastPingTime = now; - } - - function getLastPingTime() constant returns(uint){ - return lastPingTime; - } - - function deposit() payable{ - } - - struct Heir{ - address addr; - uint id; - } - - function ping() onlyOwner returns(uint) { - return lastPingTime; - } - - - function getHeirCount() constant returns(uint) { - return heirs.length; - } - - function addHeir(address heir) onlyOwner returns(uint) { - uint id = getHeirCount(); - heirs.push(Heir({addr:heir, id:id})); - return id; - } - - function changeMaxPingInterval(uint _days) onlyOwner{ - maxPingInterval = _days * 1 days; - } - - function claimHeirtage(){ - uint timePassed = now - lastPingTime; - if (timePassed < maxPingInterval) throw; - uint share = this.balance/getHeirCount(); - for(uint i=0; i < getHeirCount(); i++){ - heirs[i].addr.transfer(share); - } - } - -} diff --git a/contracts/ownership/Will/Identity.sol b/contracts/ownership/Will/Identity.sol new file mode 100644 index 000000000..b4c584d2e --- /dev/null +++ b/contracts/ownership/Will/Identity.sol @@ -0,0 +1,47 @@ +pragma solidity ^0.4.11; + +import "../Ownable.sol"; +import "./LifeCheck.sol"; +import "./Will.sol"; + +contract Identity is Ownable{ + + address lifeCheck; + address will; + + modifier onlyInactive(){ + LifeCheck hc = LifeCheck(lifeCheck); + require(hc.checkState() == 1); + _; + } + + function deposit() payable returns(uint) { + return this.balance; + } + + function transfer(address to, uint amount) onlyOwner{ + to.transfer(amount); + } + + function releaseWill() onlyInactive { + Will wl = Will(will); + wl.unlock(); + wl.transfer(this.balance); + } + + function callLifeCheck(uint value, bytes data){ + lifeCheck.call.value(value)(data); + } + + function callWill(uint value, bytes data){ + will.call.value(value)(data); + } + + function changeWillAddress(address _will){ + will = _will; + } + + function changeLifeCheckAddress(address lf){ + lifeCheck = lf; + } +} diff --git a/contracts/ownership/Will/LifeCheck.sol b/contracts/ownership/Will/LifeCheck.sol new file mode 100644 index 000000000..a5919acf0 --- /dev/null +++ b/contracts/ownership/Will/LifeCheck.sol @@ -0,0 +1,87 @@ +pragma solidity ^0.4.11; + +import "./Identity.sol"; + +contract LifeCheck{ + + address identity; + uint public lastPing; + uint public pendingUntil; + States public state; + + enum States {Active, Inactive, Pending, Unclaimable} + + modifier atState(States _state) { + require(state == _state); + _; + } + + modifier onlyOwner(){ + require(msg.sender == identity ); + lastPing = now; + _; + } + + event ClaimCreated(address addr, uint date); + + function LifeCheck(address id){ + identity = id; + state = States.Active; + lastPing = now; + } + + function ping() onlyOwner{ + lastPing = now; + if(state == States.Pending){ + resolveClaim(); + } + } + + function createClaim() atState(States.Active){ + require(lastPing < now - 7 days); + state = States.Pending; + ClaimCreated(msg.sender, now); + } + + function resolveClaim() atState(States.Pending) returns(bool claimSuccessful){ + if(pendingUntil >= now){ + return false; + } + if(lastPing > now - 7 days) { + state = States.Active; + return false; + } + state = States.Inactive; + return true; + } + + function setAsUnclaimableFor(uint _days) onlyOwner { + if (state == States.Pending){ + resolveClaim(); + } + state = States.Unclaimable; + pendingUntil = now + _days * 1 days; + } + + function setAsActive() atState(States.Unclaimable) returns(bool success){ + if (msg.sender == identity){ + state = States.Active; + pendingUntil = now; + lastPing = now; + return true; + } else { + require(pendingUntil < now); + state = States.Active; + return true; + } + } + + function releaseWill() atState(States.Inactive){ + Identity id = Identity(identity); + id.releaseWill(); + } + + function checkState() constant returns(uint){ + return uint(state); + } +} diff --git a/contracts/ownership/Will/Will.sol b/contracts/ownership/Will/Will.sol new file mode 100644 index 000000000..baa133659 --- /dev/null +++ b/contracts/ownership/Will/Will.sol @@ -0,0 +1,72 @@ +pragma solidity ^0.4.11; + +import "./Identity.sol"; + +contract Will { + + address identity; + bool locked; + Beneficiary[] heirs; + address[] heirsAddresses; + mapping(address => uint) shares; + + struct Beneficiary { + address addr; + bytes32 name; + uint weight; + bool active; + } + + modifier onlyOwner(){ + require(msg.sender == identity); + _; + } + + modifier onlyUnlocked(){ + require(!locked); + _; + } + + function Will(address id){ + identity = id; + } + + function unlock() onlyOwner(){ + locked = false; + } + + function() payable {} + + function resolveDistributions() onlyUnlocked{ + uint weightSum = 0; + uint activeHeirsCount = 0; + for(uint i = 0; i < heirs.length; i++){ + if (heirs[i].active){ + weightSum = weightSum + heirs[1].weight; + activeHeirsCount = activeHeirsCount + 1; + } + } + for (uint j = 0; j < heirs.length; j++){ + if(heirs[j].active){ + shares[heirs[j].addr] = this.balance / weightSum * heirs[j].weight; + } + } + } + + function addBeneficiary(address addr, bytes32 name, uint weight){ + heirs.push(Beneficiary({addr:addr,name:name, weight:weight, active:true})); + } + + function removeBeneficiaryByAddress(address _addr){ + for(uint i = 0; i < heirs.length; i++){ + if(heirs[i].addr == _addr){ + heirs[i].active = false; + } + } + } + + function claim() onlyUnlocked { + require(shares[msg.sender] != 0); + msg.sender.transfer(shares[msg.sender]); + } +}