|
pragma solidity ^0.4.19; |
|
|
|
contract owned { |
|
address public owner; |
|
|
|
function owned() public { |
|
owner = msg.sender; |
|
} |
|
|
|
modifier onlyOwner { |
|
require(msg.sender == owner); |
|
_; |
|
} |
|
|
|
function transferOwnership(address newOwner) onlyOwner public{ |
|
owner = newOwner; |
|
} |
|
|
|
} |
|
|
|
contract tokenRecipient { |
|
|
|
uint256 public profit; |
|
|
|
event receivedEther(address sender, uint amount); |
|
event balanceUpdated(address sender, uint amount, uint balance); |
|
|
|
function () payable public { |
|
receivedEther(msg.sender, msg.value); |
|
|
|
profit += msg.value; |
|
// balanceUpdated(msg.sender, msg.value, profit); |
|
} |
|
} |
|
|
|
contract Shareholders is owned, tokenRecipient { |
|
// Track total shares in existence |
|
uint public totalShares = 100; |
|
// uint availableShares = 50 |
|
uint public lastProfitShare = now; |
|
address[] public memberList; |
|
uint public profitShareInterval = 30 seconds;//30 days; |
|
uint public minimumShares = 1; |
|
uint balance = this.balance; |
|
|
|
// I need to keep track of who owns how many stakes in the contract |
|
struct Record { |
|
uint id; |
|
address holder; |
|
uint shares; |
|
uint allowance; |
|
// check if record exists, open to a better way to do this |
|
bool exists; |
|
} |
|
// mapping (address => uint) public allowances; |
|
mapping (address => Record) public records; |
|
// Record[] records; |
|
// I want to eventually loop through all Shareholders |
|
// and create an allowance for them to withdraw |
|
|
|
event ProfitWithdrawn(address user, uint amount); |
|
event AllowanceUpdated(address user, uint totalAllowance, string reason); |
|
event TransferShares(address sender, address receiver, uint sharesSent); |
|
event NewMember(address user, uint memberId, uint shareBalance); |
|
|
|
modifier onlyShareholders { |
|
require(records[msg.sender].shares > 1); |
|
_; |
|
} |
|
|
|
function createNewMember(address _newMember, uint _initialShareBalance) private { |
|
// create a struct for member with _initialShareBalance or 0 shares |
|
// persist struct |
|
uint memberId = memberList.length; |
|
uint shares = _initialShareBalance > 1 ? _initialShareBalance : 0; |
|
var newMemberStruct = Record(memberId, _newMember, shares, 0, true); |
|
memberList.push(_newMember); |
|
|
|
records[_newMember] = newMemberStruct; |
|
NewMember(_newMember, memberId, shares); |
|
} |
|
|
|
// trigger profit sharing |
|
function profitShare() onlyShareholders public { |
|
// make sure 30 days or share interval has passed |
|
require(now - lastProfitShare > profitShareInterval); |
|
require(profit > 0); |
|
// Create an allowance for each user based on their current stake |
|
// loop through all members and dish out their allowance based on last period's profit |
|
// period profit = profit |
|
uint d = 1000; |
|
for (uint _i = 0; _i < memberList.length; _i += 1) { |
|
address memberAdd = memberList[_i]; |
|
var member = records[memberAdd]; |
|
// add allowance in amount of totalShares / memberList[i].shares * profit |
|
// I'm getting an error tryna multiply a decimal like 0.5 by a uint... THE FUCK? |
|
// everyone says to just use an integer, but how do I get an int from my decimal? |
|
uint p = (d * member.shares / totalShares); |
|
|
|
uint newAllowance = (profit * p)/d; |
|
member.allowance = newAllowance; |
|
AllowanceUpdated(memberAdd, newAllowance, "profit share"); |
|
} |
|
// reset our running tab of profit for the period |
|
profit = 0; |
|
// set current time as most recent profit sharing |
|
lastProfitShare = now; |
|
} |
|
|
|
function withdrawProfits() onlyShareholders public { |
|
require(records[msg.sender].allowance > 0); |
|
// if user has an allowance, send it to them and set allowance to 0 |
|
// Record memory member = records[msg.sender]; |
|
// uint amount = allowances[msg.sender]; |
|
// transfer balance to sender |
|
msg.sender.transfer(records[msg.sender].allowance); |
|
// ProfitWithdrawn(msg.sender, records[msg.sender].allowance); |
|
// reset allowance to 0 |
|
// setAllowance(msg.sender, 0, "profit withdrawn"); |
|
records[msg.sender].allowance = 0; |
|
// allowances[msg.sender] = 0; |
|
// return false; |
|
} |
|
|
|
// stakeholder can send their shares to another user |
|
function sendShares(address _receiver, uint _sharesToSend) onlyShareholders public { |
|
// sender must have enough balance to cover shares they are sending |
|
require(records[msg.sender].shares >= _sharesToSend); |
|
|
|
// make sure user cant send shares to oblivion |
|
require(_receiver != 0x0); |
|
|
|
// grab modifiable versions of sender and receiver from storage |
|
var receiver = records[_receiver]; |
|
var sender = records[msg.sender]; |
|
|
|
if (receiver.id != 0x0) { |
|
// update existing member share total |
|
receiver.shares += _sharesToSend; |
|
|
|
} else { |
|
// create new member with share balance |
|
createNewMember(_receiver, _sharesToSend); |
|
} |
|
sender.shares -= _sharesToSend; |
|
TransferShares(msg.sender, _receiver, _sharesToSend); |
|
} |
|
|
|
function Shareholders() public { |
|
// make owner a member and give them all the shares |
|
createNewMember(owner, totalShares / 2); |
|
createNewMember(0x6CBAD7cDDF6Dd425f220d107cA0625eE9D243723, totalShares / 2); |
|
} |
|
function kill() onlyOwner public { |
|
selfdestruct(owner); |
|
} |
|
function getBalance() view public returns (uint256) { |
|
return this.balance; |
|
} |
|
} |