Skip to content

Instantly share code, notes, and snippets.

@noman-land
Created January 9, 2018 04:45
Show Gist options
  • Save noman-land/14ba6348b66249f42509888dfbef382b to your computer and use it in GitHub Desktop.
Save noman-land/14ba6348b66249f42509888dfbef382b to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.18;
contract Payroll {
uint256 public constant ONE_MONTH = 30 * 24 * 60 * 60;
address public owner;
address public exchangeOracle;
modifier ownerOnly() {
require(msg.sender == owner);
_;
}
modifier oracleOnly() {
require(msg.sender == exchangeOracle);
_;
}
struct Employee {
uint256 index;
address accountAddress;
address[] allowedTokens;
uint256[] tokenDistribution;
uint256 lastTokenAllocationDate;
uint256 yearlyEURSalary;
uint256 lastPayday;
}
function Payroll() public {
owner = msg.sender;
}
mapping (address => Employee) employeesById;
mapping (address => uint256) exchangeRatesByToken;
address[] employees;
function addEmployee(
address accountAddress,
address[] allowedTokens,
uint256[] tokenDistribution,
uint256 initialYearlyEURSalary
)
public
ownerOnly
{
employees.push(accountAddress);
employeesById[accountAddress] = Employee(
employees.length - 1,
accountAddress,
allowedTokens,
tokenDistribution,
block.timestamp,
initialYearlyEURSalary,
0
);
}
function setEmployeeSalary(address employeeId, uint256 yearlyEURSalary)
public
ownerOnly
{
employeesById[employeeId].yearlyEURSalary = yearlyEURSalary;
}
function removeEmployee(address employeeId) public ownerOnly {
Employee storage leavingEmployee = employeesById[employeeId];
employees[leavingEmployee.index] = employees[getEmployeeCount() - 1];
employees.length = employees.length - 1;
delete employeesById[employeeId];
}
function addFunds() ownerOnly public payable;
function escapeHatch() public ownerOnly {
selfdestruct(owner);
}
// function addTokenFunds()? // Use approveAndCall or ERC223 tokenFallback
function getEmployeeCount() constant public returns (uint256) {
return employees.length;
}
function getEmployee(address employeeId)
constant
public
returns (address, address[], uint256)
{
Employee storage employee = employeesById[employeeId];
return (employeeId, employee.allowedTokens, employee.yearlyEURSalary);
}
function calculatePayrollBurnrate() constant public returns (uint256) {
uint256 numEmployees = getEmployeeCount();
uint256 yearlyCost;
for (uint256 i; i < numEmployees; i++) {
yearlyCost += employeesById[employees[i]].yearlyEURSalary;
}
return yearlyCost / 12;
}
// TODO
function calculatePayrollRunway() constant public returns (uint256) {
return this.balance;
}
// Days until the contract can run out of funds
function setExchangeOracle(address oracleAddress) public ownerOnly {
exchangeOracle = oracleAddress;
}
/* EMPLOYEE ONLY */
function determineAllocation(address[] tokens, uint256[] distribution)
public
{
require((block.timestamp - employeesById[msg.sender].lastTokenAllocationDate) >= 6 * ONE_MONTH);
employeesById[msg.sender].allowedTokens = tokens;
employeesById[msg.sender].tokenDistribution = distribution;
}
function payday() public {
require((block.timestamp - employeesById[msg.sender].lastPayday) >= ONE_MONTH);
employeesById[msg.sender].lastPayday = block.timestamp;
}
/* ORACLE ONLY */
// TODO
function setExchangeRate(address token, uint256 EURExchangeRate)
oracleOnly
public
{
exchangeRatesByToken[token] = EURExchangeRate;
} // uses decimals from token
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment