Skip to content

Commit

Permalink
#48
Browse files Browse the repository at this point in the history
  • Loading branch information
enkogu committed Dec 23, 2018
1 parent c834e60 commit 42d50ea
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 183 deletions.
18 changes: 9 additions & 9 deletions contracts/SplitterBase.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pragma solidity ^0.4.23;

import "zeppelin-solidity/contracts/ownership/Ownable.sol";
import "./interfaces/IWeiReceiver.sol";
import "./interfaces/IReceiver.sol";
import "./interfaces/ITable.sol";

/**
Expand All @@ -14,7 +14,7 @@ contract SplitterBase {
bool isTableSplitter;
uint[] outputs;
address[] addresses;
IWeiReceiver.Type childrenType;
IReceiver.Type childrenType;
}

struct FlowBuffer {
Expand Down Expand Up @@ -44,16 +44,16 @@ contract SplitterBase {

function addChildToSplitter(Splitter storage _s, uint _id, address _addr) internal {
emit SplitterBaseAddChild(_id, _addr);
IWeiReceiver.Type childType;
IReceiver.Type childType;

if(_s.isTableSplitter) {
childType = ITable(address(this)).getReceiverTypeAt(_id);
} else {
childType = IWeiReceiver(_addr).getReceiverType();
}

if((_s.childrenType != IWeiReceiver.Type.Splitter)
&&(childType != IWeiReceiver.Type.Splitter)) {
if((_s.childrenType != IReceiver.Type.Splitter)
&&(childType != IReceiver.Type.Splitter)) {
require(_s.childrenType == childType);
} else {
_s.childrenType = childType;
Expand Down Expand Up @@ -154,7 +154,7 @@ contract SplitterBase {
function constructSplitter(bool _isTableSplitter) internal view returns(Splitter s) {
uint[] memory emptyOutputs;
address[] memory emptyAddresses;
return Splitter(true, _isTableSplitter, emptyOutputs, emptyAddresses, IWeiReceiver.Type.Splitter);
return Splitter(true, _isTableSplitter, emptyOutputs, emptyAddresses, IReceiver.Type.Splitter);
}

function _modifyFlow(FlowBuffer _b) internal pure returns(FlowBuffer) {
Expand All @@ -179,8 +179,8 @@ contract SplitterBase {
}

if((b.i+1) < getChildrenCount(_s)) {
if((getReceiverTypeBase(_s, b.i) == IWeiReceiver.Type.Relative)
&& (getReceiverTypeBase(_s, (b.i + 1)) == IWeiReceiver.Type.Relative)) {
if((getReceiverTypeBase(_s, b.i) == IReceiver.Type.Relative)
&& (getReceiverTypeBase(_s, (b.i + 1)) == IReceiver.Type.Relative)) {
b.relSeqQ = true;
}
}
Expand All @@ -189,7 +189,7 @@ contract SplitterBase {
return b;
}

function getReceiverTypeBase(Splitter _s, uint _childNum) internal view returns(IWeiReceiver.Type t) {
function getReceiverTypeBase(Splitter _s, uint _childNum) internal view returns(IReceiver.Type t) {
if(_s.isTableSplitter) {
t = ITable(address(this)).getReceiverTypeAt(_s.outputs[_childNum]);
} else {
Expand Down
166 changes: 166 additions & 0 deletions contracts/TableBase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
pragma solidity ^0.4.23;

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

import "./ExpenseBase.sol";
import "./SplitterBase.sol";

/**
* @title TableBase
* @dev contract for WeiTable and ERC20Table
*/
contract TableBase is ExpenseBase, SplitterBase, Ownable {
uint public nodesCount = 0;

event NodeAdded(uint _eId, IReceiver.Type _eType);
event FundNeed(uint _eId, uint _inputWei, uint need);
event FundStart(uint _eId, uint _totalWeiNeeded);

event NodeConnected(uint _splitterId, uint _childId);
event NodeFlushTo(uint _eId, address _to, uint _balance);
event SplitterNeeded(uint _eId, uint _needed, uint _total, uint _currentFlow);

mapping(uint=>IReceiver.Type) nodesType;
mapping(uint=>ExpenseBase.Expense) expenses;
mapping(uint=>SplitterBase.Splitter) splitters;

modifier isCorrectId(uint _eId) {
require(_eId <= (nodesCount - 1));
_;
}

function getLastNodeId() public returns(uint) {
if(nodesCount == 0) {
return 0;
} else {
return nodesCount - 1;
}
}

function getPartsPerMillionAt(uint _eId) public view isCorrectId(_eId) returns(uint ppm) {
ppm = expenses[_eId].partsPerMillion;
}

function isNeedsAt(uint _eId) public view isCorrectId(_eId) returns(bool) {
if(isExpenseAt(_eId)) {
return isExpenseNeeds(expenses[_eId]);
}else {
return isSplitterNeeds(splitters[_eId]);
}
}

function getMinNeededAt(uint _eId, uint _currentFlow) public view isCorrectId(_eId) returns(uint) {
if(isExpenseAt(_eId)) {
return getExpenseMinNeeded(expenses[_eId], _currentFlow);
}else {
return getSplitterMinNeeded(splitters[_eId], _currentFlow);
}
}

function getTotalNeededAt(uint _eId, uint _currentFlow) public view isCorrectId(_eId) returns(uint) {
if(isExpenseAt(_eId)) {
return getExpenseTotalNeeded(expenses[_eId], _currentFlow);
} else {
return getSplitterTotalNeeded(splitters[_eId], _currentFlow);
}
}

function balanceAt(uint _eId) public view isCorrectId(_eId) returns(uint) {
return expenses[_eId].balance;
}

// -------------------- public SCHEME FUNCTIONS --------------------
function addAbsoluteExpense(uint128 _totalWeiNeeded, uint128 _minWeiAmount, bool _isPeriodic, bool _isSlidingAmount, uint32 _periodHours) public onlyOwner {
emit NodeAdded(nodesCount, IReceiver.Type.Absolute);
expenses[nodesCount] = constructExpense(_totalWeiNeeded, _minWeiAmount, 0, _periodHours, _isSlidingAmount, _isPeriodic);
nodesType[nodesCount] = IReceiver.Type.Absolute;
nodesCount += 1;
}

function addRelativeExpense(uint32 _partsPerMillion, bool _isPeriodic, bool _isSlidingAmount, uint32 _periodHours) public onlyOwner {
emit NodeAdded(nodesCount, IReceiver.Type.Relative);
expenses[nodesCount] = constructExpense(0, 0, _partsPerMillion, _periodHours, _isSlidingAmount, _isPeriodic);
nodesType[nodesCount] = IReceiver.Type.Relative;
nodesCount += 1;
}

function addSplitter() public onlyOwner {
splitters[nodesCount] = constructSplitter(true);
emit NodeAdded(nodesCount, IReceiver.Type.Splitter);
nodesType[nodesCount] = IReceiver.Type.Splitter;
nodesCount += 1;
}

function addChildAt(uint _splitterId, uint _childId) public onlyOwner {
// Splitter s = splitters[_splitterId];
// addChildToSplitter(s, _childId, address(0));
// splitters[_splitterId] = s;
if((splitters[_splitterId].childrenType != IReceiver.Type.Splitter)
&& (getReceiverTypeAt(_childId) != IReceiver.Type.Splitter)) {
require(getReceiverTypeAt(_childId) == splitters[_splitterId].childrenType);
} else {
splitters[_splitterId].childrenType = getReceiverTypeAt(_childId);
}
emit NodeConnected(_splitterId, _childId);
splitters[_splitterId].outputs.push(_childId);
}

// -------------------- public CONTROL FUNCTIONS --------------------
function getReceiverTypeAt(uint _eId) public isCorrectId(_eId) returns(IReceiver.Type nodeType) {
if(isExpenseAt(_eId)) {
if(expenses[_eId].partsPerMillion > 0) {
nodeType = IReceiver.Type.Relative;
} else {
nodeType = IReceiver.Type.Absolute;
}
} else {
nodeType = IReceiver.Type.Splitter;
}
}

function isExpenseAt(uint _eId) public isCorrectId(_eId) returns(bool isExpense) {
isExpense = (IReceiver.Type.Splitter != nodesType[_eId]);
}

function isSplitterAt(uint _eId) public isCorrectId(_eId) returns(bool isSplitter) {
isSplitter = (IReceiver.Type.Splitter == nodesType[_eId]);
}

function openAt(uint _eId) public onlyOwner isCorrectId(_eId) {
if(isExpenseAt(_eId)) {
openExpense(expenses[_eId]);
}else {
openSplitter(splitters[_eId]);
}
}

function closeAt(uint _eId) public onlyOwner isCorrectId(_eId) {
if(isExpenseAt(_eId)) {
closeExpense(expenses[_eId]);
}else {
closeSplitter(splitters[_eId]);
}
}

function isOpenAt(uint _eId) public view isCorrectId(_eId) returns(bool) {
if(isExpenseAt(_eId)) {
return expenses[_eId].isOpen;
}else {
return splitters[_eId].isOpen;
}
}

function getChildrenCountAt(uint _eId) public view isCorrectId(_eId) returns(uint) {
require(isSplitterAt(_eId));
return splitters[_eId].outputs.length;
}

function getChildIdAt(uint _eId, uint _index) public view isCorrectId(_eId) returns(uint) {
require(isSplitterAt(_eId));
require(splitters[_eId].outputs.length > _index);
return splitters[_eId].outputs[_index];
}

}
Loading

0 comments on commit 42d50ea

Please sign in to comment.