parent
8967b3d0ce
commit
ae4e92d3b8
@ -1,85 +0,0 @@ |
||||
pragma solidity ^0.4.8; |
||||
|
||||
contract Will is Ownable { |
||||
|
||||
uint256 timeBeforeRelease; //Time in seconds remaining for the relase to the heirs |
||||
uint256 lastPingTime; //Last time the owner interacted with the contract |
||||
address[] heirAddress; |
||||
|
||||
|
||||
//The weight of a heir changes how much of the funds he deserves. If all |
||||
//heirs have a weitgh of 1(defualt value) the funds are shared equally between |
||||
//all of them. If on heir has a weight of 2 and the other has a weight of 1, the |
||||
//first one gets 2/3 of the funds while the other gets 1/3. |
||||
mapping(address => uint256) heirs; |
||||
|
||||
|
||||
Will(uint256 _timeBeforeRelease) Onwable(){ |
||||
timeBeforeRelease = _timeBeforeRelease; |
||||
lastPingTime = now; |
||||
} |
||||
|
||||
function ping() onlyOwner { |
||||
_; |
||||
} |
||||
|
||||
function getHeirWeigth(address heir) constant returns(uint256){ |
||||
return heirs[heir]; |
||||
} |
||||
|
||||
function getHeirsAddress(uint _index) constant returns(address){ |
||||
return heirAddress[_index]; |
||||
} |
||||
|
||||
function getHeirCount() constant returns(uint){ |
||||
returns heirAddress.length; |
||||
} |
||||
|
||||
function addHeir(address heir, uint256 weight) onlyOwner{ |
||||
if (heirs[heir] != 0) throw; |
||||
heirs[heir] = weight; |
||||
heirAddress.push(heir); |
||||
} |
||||
|
||||
function changeHeirWeight(address _heir, uint256 weitgh) onlyOwner{ |
||||
|
||||
} |
||||
|
||||
//Quite expensive operation, but hopefully I won't be needed much in a lifetime ;) |
||||
function removeHeir(address heir) onlyOwner{ |
||||
heirs[heir] = 0; |
||||
for(uint i = 0; i < getHeirCount(); i++){ |
||||
if(getHeirsAddress(i) == heir){ |
||||
//copy the last address into the 'deleted spot', so there won't be a gap in the array. |
||||
heirAddress[i] = getHeirsAddress(getHeirCount() - 1); |
||||
delete heirAddress[getHeirsAddress(getHeirCount() - 1)]; |
||||
} |
||||
} |
||||
} |
||||
|
||||
function changeMaximumPingInterval(uint256 _seconds) onlyOwner { |
||||
timeBeforeRelease = _seconds; |
||||
} |
||||
|
||||
modifier onlyOwner() { |
||||
if (msg.sender != owner) { |
||||
throw; |
||||
} |
||||
_; |
||||
lastPingTime = now; |
||||
} |
||||
|
||||
function claim() { |
||||
if (lastPingTime < timeBeforeRelease) throw; |
||||
//get sum of weigths |
||||
uint memory total = 0; |
||||
uint memory balance = this.balance |
||||
for(uint i =0; i < getHeirCount(); i++){ |
||||
total += heirs[getHeirsAddress(i)]; |
||||
} |
||||
//release fund to heirs |
||||
for(uint i =0; i < getHeirCount(); i++){ |
||||
getHeirsAddress(i).transfer((heirs[getHeirsAddress(i)] / total) * balance) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,63 @@ |
||||
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); |
||||
} |
||||
} |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,90 @@ |
||||
const assertJump = require('./helpers/assertJump'); |
||||
const timer = require('./helpers/timer'); |
||||
var Will = artifacts.require("../contracts/ownership/Will.sol"); |
||||
|
||||
contract('Will', function(accounts) { |
||||
let will; |
||||
let owner; |
||||
let address; |
||||
|
||||
beforeEach(async function() { |
||||
will = await Will.new(); |
||||
owner = await will.owner(); |
||||
address = await will.address; |
||||
}); |
||||
|
||||
describe("should ping correctly", async () => { |
||||
let lastPing = 0; |
||||
it("should ping on creation", function() { |
||||
return will.getLastPingTime().then(function (ping){ |
||||
assert.isTrue(ping > 0); |
||||
lastPing = ping; |
||||
}) |
||||
}); |
||||
|
||||
it("Should ping on 'onlyOwner' modifier", async ()=> { |
||||
will.ping({from: owner}) |
||||
await timer(10); |
||||
let newPing = await will.getLastPingTime(); |
||||
assert.isTrue(newPing > lastPing); |
||||
lastPing = newPing; |
||||
}); |
||||
}); |
||||
|
||||
it("should be able to change ping interval", async () => { |
||||
let initialInterval = await will.maxPingInterval(); |
||||
will.changeMaxPingInterval(1, {from: owner}); |
||||
let newInt = 86400 //seconds in a day
|
||||
let newInterval = await will.maxPingInterval(); |
||||
assert.isTrue(newInterval == 86400); |
||||
}); |
||||
|
||||
it("should be able to receive ether", async function(){ |
||||
let startBalance = await web3.eth.getBalance(address).toNumber(); |
||||
await will.deposit.sendTransaction({ |
||||
from: owner, |
||||
to: address, |
||||
value: web3.toWei('5', 'ether') |
||||
}); |
||||
let finishBalance = await web3.eth.getBalance(address).toNumber(); |
||||
assert.isTrue(startBalance < finishBalance); |
||||
}); |
||||
|
||||
it("should be able to add heir", async () => { |
||||
let initialHeirCount = await will.getHeirCount(); |
||||
await will.addHeir(accounts[2], {from: owner}); |
||||
let newCount = await will.getHeirCount(); |
||||
assert.equal(newCount, 1); |
||||
}) |
||||
|
||||
it("shouldn't be claimable if it is within ping timeframe", async () => { |
||||
try{ |
||||
await will.claimHeirtage(); |
||||
}catch(err){ |
||||
return assertJump(err); |
||||
} |
||||
}) |
||||
|
||||
it("should tranfer funds among heirs when claimable", async () => { |
||||
await will.deposit.sendTransaction({ |
||||
from: owner, |
||||
to: address, |
||||
value: web3.toWei('5', 'ether') |
||||
}); |
||||
let willInitialBalance = await web3.eth.getBalance(address).toNumber(); |
||||
let heirOneInitialBalance = await web3.eth.getBalance(accounts[2]).toNumber(); |
||||
let heirTwoInitialBalance = await web3.eth.getBalance(accounts[3]).toNumber(); |
||||
await will.addHeir(accounts[2], {from: owner}); |
||||
await will.addHeir(accounts[3], {from: owner}); |
||||
await timer(259200); //wait for ping expiration
|
||||
await will.claimHeirtage({from: accounts[5]}); |
||||
let willFinalBalance = await web3.eth.getBalance(address).toNumber(); |
||||
let heirOneFinalBalance = await web3.eth.getBalance(accounts[2]).toNumber(); |
||||
let heirTwoFinalBalance = await web3.eth.getBalance(accounts[3]).toNumber(); |
||||
let gains = (heirOneFinalBalance - heirOneInitialBalance) + (heirTwoFinalBalance - heirTwoInitialBalance) |
||||
assert.equal(heirOneFinalBalance, heirTwoFinalBalance); |
||||
assert.isTrue(willFinalBalance == 0); |
||||
assert.equal(gains, willInitialBalance); |
||||
}) |
||||
|
||||
}); |
Loading…
Reference in new issue