Payrool.sol 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. pragma solidity ^0.4.14;
  2. import './SafeMath.sol';
  3. import './Ownable.sol';
  4. contract Payroll is Ownable{
  5. using SafeMath for uint;
  6. struct Employee {
  7. address id;
  8. uint salary;
  9. uint lastPayday;
  10. }
  11. uint constant payDuration = 10 seconds;
  12. address self;
  13. uint totalSalary;
  14. uint totalEmployee;
  15. address[] employeeList;
  16. mapping(address => Employee) public employees;
  17. function Payroll() public {
  18. self = this;
  19. }
  20. function changePaymentAddress (address fromEmployeeId, address toEmployeeId) employeeExit(fromEmployeeId) employeeNoExit(toEmployeeId) public {
  21. var employeePre = employees[fromEmployeeId];
  22. employees[toEmployeeId] = Employee(toEmployeeId, employeePre.salary, employeePre.lastPayday);
  23. delete employees[fromEmployeeId];
  24. }
  25. //settlement one employee's salary
  26. function _partialPaid(Employee employee) private {
  27. uint payment = employee.salary.mul(now.sub(employee.lastPayday)).div(payDuration);
  28. assert(self.balance > payment && payment > 0);
  29. employee.id.transfer(payment);
  30. }
  31. function addEmployee(address employeeId, uint salary) onlyOwner employeeNoExit(employeeId) public{
  32. uint salaryWei = salary.mul(1 ether);
  33. totalSalary = totalSalary.add(salaryWei);
  34. employees[employeeId] = Employee(employeeId, salaryWei, now);
  35. totalEmployee = totalEmployee.add(1);
  36. employeeList.push(employeeId);
  37. AddEmployee(employeeId);
  38. }
  39. function removeEmployee(address employeeId) onlyOwner employeeExit(employeeId) public {
  40. _partialPaid(employees[employeeId]);
  41. totalSalary = totalSalary.sub(employees[employeeId].salary);
  42. delete employees[employeeId];
  43. totalEmployee = totalEmployee.sub(1);
  44. uint index = getEmployeeIndex(employeeId);
  45. if(index >= 0 ){
  46. delete employeeList[index];
  47. uint tailIndex = employeeList.length.sub(1);
  48. employeeList[index] = employeeList[tailIndex];
  49. employeeList.length = employeeList.length.sub(1);
  50. }
  51. RemoveEmployee(employeeId);
  52. }
  53. function updateEmployee(address employeeId, uint salary) onlyOwner employeeExit(employeeId) public {
  54. _partialPaid(employees[employeeId]);
  55. totalSalary = totalSalary.sub(employees[employeeId].salary);
  56. uint salaryWei = salary.mul(1 ether);
  57. totalSalary = totalSalary.add(salaryWei);
  58. employees[employeeId].salary = salaryWei;
  59. employees[employeeId].lastPayday = now;
  60. UpdateEmployee(employeeId);
  61. }
  62. function checkEmployee(uint index) public view returns (address employeeId, uint salary, uint lastPayday) {
  63. require(index < employeeList.length);
  64. employeeId = employeeList[index];
  65. var employee = employees[employeeId];
  66. salary = employee.salary;
  67. lastPayday = employee.lastPayday;
  68. }
  69. /* function checkEmployee(address employeeId) employeeExit(employeeId) public view returns (uint salary, uint lastPayday) {
  70. salary = employees[employeeId].salary;
  71. lastPayday = employees[employeeId].lastPayday;
  72. } */
  73. function addFund() public payable returns (uint) {
  74. AddFund(self.balance);
  75. return self.balance;
  76. }
  77. function calculateRunway() public view returns (uint) {
  78. //assert(totalSalary > 0);
  79. if(totalSalary == 0)return 0;
  80. return self.balance.div(totalSalary);
  81. }
  82. function hasEnoughFund() public view returns (bool) {
  83. return calculateRunway() > 0;
  84. }
  85. function getPaid() employeeExit(msg.sender) public {
  86. uint nextPayday = employees[msg.sender].lastPayday.add(payDuration);
  87. assert(nextPayday < now);
  88. employees[msg.sender].lastPayday = nextPayday;
  89. employees[msg.sender].id.transfer(employees[msg.sender].salary);
  90. GetPaid(msg.sender);
  91. }
  92. function getEmployeeIndex(address employeeId) private view returns (uint) {
  93. for(uint i = 0; i < employeeList.length; i++) {
  94. if(employeeList[i] == employeeId) {
  95. return i;
  96. }
  97. }
  98. }
  99. function getInfo() public view returns (uint balance, uint runway, uint employeeCount) {
  100. balance = this.balance;
  101. runway = calculateRunway();
  102. employeeCount = totalEmployee;
  103. }
  104. function getEmployeeList() public view returns (address[]) {
  105. return employeeList;
  106. }
  107. modifier employeeExit(address employeeId) {
  108. assert(employees[employeeId].id != 0x0);
  109. _;
  110. }
  111. modifier employeeNoExit(address employeeId) {
  112. assert(employees[employeeId].id == 0x0);
  113. _;
  114. }
  115. modifier employeeDelete(address employeeId) {
  116. _;
  117. delete employees[employeeId];
  118. }
  119. event AddEmployee (
  120. address employee
  121. );
  122. event RemoveEmployee (
  123. address employee
  124. );
  125. event UpdateEmployee (
  126. address employee
  127. );
  128. event GetPaid (
  129. address employee
  130. );
  131. event AddFund (
  132. uint balance
  133. );
  134. }