Skip to content

Commit

Permalink
payroll: add payday remainders as accrued salary
Browse files Browse the repository at this point in the history
  • Loading branch information
facuspagnuolo committed Jul 5, 2019
1 parent d28394c commit da8fdd2
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 148 deletions.
64 changes: 35 additions & 29 deletions future-apps/payroll/contracts/Payroll.sol
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,41 @@ contract Payroll is EtherTokenConstant, IForwarder, IsContract, AragonApp {
// No need to use SafeMath here as we already know _paymentAmount > accruedSalary
currentSalaryPaid = _paymentAmount - accruedSalary;
}
employee.lastPayroll = _getLastPayrollDate(_employeeId, currentSalaryPaid);
_updateEmployeeLastPayrollDate(_employeeId, currentSalaryPaid);
}

/**
* @dev Update the last payroll date for an employee based on the requested payment amount. If the requested amount
* cannot be represented by a multiple of the employee's salary per second, it will be added as accrued salary.
* @param _employeeId Employee's identifier
* @param _paidAmount Requested amount to be paid to the employee
*/
function _updateEmployeeLastPayrollDate(uint256 _employeeId, uint256 _paidAmount) internal {
Employee storage employee = employees[_employeeId];

uint256 timeDiff = _paidAmount.div(employee.denominationTokenSalary);

// We check if the division was perfect, and if not, take its ceiling to avoid giving away tiny amounts of
// salary and add the remainder to the accrued salary.
if (timeDiff.mul(employee.denominationTokenSalary) != _paidAmount) {
timeDiff = timeDiff.add(1);
// No need to use SafeMath here, we already now that _paidAmount is lower than its ceil
uint256 remainder = timeDiff.mul(employee.denominationTokenSalary) - _paidAmount;

uint256 currentAccruedSalary = employee.accruedSalary;
uint256 newAccruedSalary = currentAccruedSalary + remainder;
if (newAccruedSalary < currentAccruedSalary) {
newAccruedSalary = MAX_UINT256;
}
employee.accruedSalary = newAccruedSalary;
}

uint256 lastPayrollDate = uint256(employee.lastPayroll).add(timeDiff);
// Even though this function should never receive a _paidAmount value that would result in
// the lastPayrollDate being higher than the current time, let's double check to be safe
require(lastPayrollDate <= uint256(getTimestamp64()), ERROR_LAST_PAYROLL_DATE_TOO_BIG);
// Already know lastPayrollDate must fit in uint64 from above
employee.lastPayroll = uint64(lastPayrollDate);
}

/**
Expand Down Expand Up @@ -726,34 +760,6 @@ contract Payroll is EtherTokenConstant, IForwarder, IsContract, AragonApp {
return uint256(xrt);
}

/**
* @dev Calculate the new last payroll date for an employee based on the requested payment amount
* @param _employeeId Employee's identifier
* @param _paidAmount Requested amount to be paid to the employee
* @return The new last payroll timestamp in seconds based on the requested payment amount
*/
function _getLastPayrollDate(uint256 _employeeId, uint256 _paidAmount) internal view returns (uint64) {
Employee storage employee = employees[_employeeId];

uint256 timeDiff = _paidAmount.div(employee.denominationTokenSalary);

// We check if the division was perfect, and if not, take its ceiling to avoid giving away
// tiny amounts of salary.
// Employees may lose up to a second's worth of payroll if they use the "request partial
// amount" feature or reach salary amounts that get capped by uint max.
if (timeDiff.mul(employee.denominationTokenSalary) != _paidAmount) {
timeDiff = timeDiff.add(1);
}

uint256 lastPayrollDate = uint256(employee.lastPayroll).add(timeDiff);

// Even though this function should never receive a _paidAmount value that would result in
// the lastPayrollDate being higher than the current time, let's double check to be safe
require(lastPayrollDate <= uint256(getTimestamp64()), ERROR_LAST_PAYROLL_DATE_TOO_BIG);
// Already know lastPayrollDate must fit in uint64 from above
return uint64(lastPayrollDate);
}

/**
* @dev Get owed salary since last payroll for an employee
* @param _employeeId Employee's identifier
Expand Down
Loading

0 comments on commit da8fdd2

Please sign in to comment.