Security News
New Python Packaging Proposal Aims to Solve Phantom Dependency Problem with SBOMs
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
@conflux-/aragon-apps-payroll
Advanced tools
Payroll is an Aragon app implementing an automated employee payroll mechanism, featuring real-time salaries in multiple currencies.
This app's frontend is currently unfinished, and is not available for use.
The Payroll
contract was last professionally audited in 2019-07.
This version was published to aragonPM as payroll.aragonpm.eth
.
The Payroll app defines the following roles:
ADD_EMPLOYEE_ROLE
: allows invocation of addEmployee()
TERMINATE_EMPLOYEE_ROLE
: allows invocation of terminateEmployee()
SET_EMPLOYEE_SALARY_ROLE
: allows invocation of setEmployeeSalary()
ADD_BONUS_ROLE
: allows invocation of addBonus()
ADD_REIMBURSEMENT_ROLE
: allows invocation of addReimbursement()
ALLOWED_TOKENS_MANAGER_ROLE
: allows invocation of addAllowedToken()
CHANGE_PRICE_FEED_ROLE
: allows invocation of setPriceFeed()
MODIFY_RATE_EXPIRY_ROLE
: allows invocation of setRateExpiryTime()
These roles can all be considered "management" roles, in that they are sensitive and meant to be held by more privileged members or apps in the organization. In particular, the set of ADD_EMPLOYEE_ROLE
, TERMINATE_EMPLOYEE_ROLE
, SET_EMPLOYEE_SALARY_ROLE
, ADD_BONUS_ROLE
, and ADD_REIMBURSEMENT_ROLE
roles control functionality related to managing employees and their salaries, and the set of ALLOWED_TOKENS_MANAGER_ROLE
, CHANGE_PRICE_FEED_ROLE
, MODIFY_RATE_EXPIRY_ROLE
roles control specific parameters and configuration points in how the Payroll app operates as a whole.
Employees themselves are authenticated based on their "employee account" (an address), and have access to functionality related to their account that only they are allowed to access:
changeAddressByEmployee()
determineAllocation()
payday()
The Payroll app can be configured through four parameters on initialization:
IFeed
implementation that provides exchange rates between different tokens
The price feed and expiration time can be later modified by setPriceFeed()
and setRateExpiryTime()
, respectively.
In addition to the instantiation options, Payroll managers must also use addAllowedToken()
to whitelist a set of tokens that will be provided as options for employees to withdraw their salaries in.
Note: we initially recommend only using ETH (
0x00...00
) or DAI (0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359
) as the denomination token.Using the wrong denomination token can have dangerous consequences. Understand the requirements for allowed tokens in the potentially dangerous gotchas section if you're considering using another token.
Note: for similar reasons, we also recommend only whitelisting ETH or DAI as the allowed tokens. You cannot yet revoke any allowed tokens.
Install an instance of the Payroll app onto the organization, and set up permissions in accordance to the governance structure desired.
For simplicity, we assume that all of the functionality discussed below can be achieved in one way or another (either one person directly holds the permission, or can access the functionality behind a forwarder).
Initializing a Payroll app requires the following parameters:
See Payroll management for more information on these specific parameters.
We assume the Payroll app has been instantiated using a Finance app installed onto the same organization and an already deployed price feed, using DAI as the denomination token and 10 minutes as the price feed rate expiry limit:
payroll.initialize(0xabc...def, 0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359, 0xabc...def, 600);
Add ETH and DAI as allowed tokens for salary withdrawal:
payroll.addAllowedToken(0x0000000000000000000000000000000000000000); // ETH
payroll.addAllowedToken(0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359); // DAI
Add an employee starting on Jan. 1st, 2020, with 80,000 DAI salary (note the salary is in seconds, and already adjusted for 18 decimals):
payroll.addEmployee(0xabc...def, 2535047025122317, 1577836800, "employee");
Assume for future examples this employee has an employee ID of 1
.
After some time, give the employee a raise by changing their salary to 90,000 DAI:
payroll.setEmployeeSalary(1, 2851927903262606);
Finally, remove the employee from payroll on Jan. 1, 2022:
payroll.terminateEmployee(1, 1640995200);
payroll.determineAllocation(address[] tokens, uint8[] distribution)
Employees can set the proportion of every allowed token that want to be used for their salary payment. Distribution values are expressed as a ratio to 100.
payroll.payday()
Employees can request payroll whenever they want and the proportional amount of their annual salary since the last request (or since the start date if it's the first one) will be transferred.
payroll.changeAddressByEmployee(address newAddress)
Employees can change their own address.
payroll.payday(PaymentType _type, uint256 _requestedAmount)
Due to the limits of mathematical precision, any token used as either the denomination token or an allowed token must have a "reasonable" exchange rate against the denomination token, and this exchange rate must be fetchable from the price feed.
A "reasonable" exchange rate is one that falls between 1e-18 and 1e18 against a base token.
payday()
fails if one of the token payments exceeds the budget left in the Finance app or the Vault's balance for that token. Even if the Vault could technically pay out the salary by converting its assets appropriately, no automatic conversions are attempted.
Denial-of-service: as salaries are not held in escrow, an organization could strategically transfer funds or move them into different accounts to deny employees' salaries.
Front-running: in the event where the Finance app is not able to pay everyone's salary, only the first ones able to execute payday()
will be paid.
Due to the nature of exchange rates and running imprecise arithmetic operations, a user's actual, paid salary will differ slightly from their "real" salary. In all cases though, these rounding errors should be so ridiculously small as to not present a problem in reality.
addBonus()
, addReimbursement()
, and setEmployeeSalary()
are all management-related
functionality which set storage variables on an employee's account that are later used in
calculating payments.
In particular, inputting a large number in any of these functions can create a denial of service situation for an employee when they later attempt to access payday()
, due to some calculations throwing on overflow errors.
As a mitigation, payday()
includes the ability to do partial paydays with the _requestedAmount
input field, allowing a user to specify that they only want to be paid up to a certain amount. If the employee is ever in a situation where their owed salary, bonus, or reimbursements become so high as to cause overflows, they will always have the option to request a smaller amount that doesn't overflow.
Executing a partial payday()
may result in the employee losing up to one second of their "real"
payroll, due to the inability for the EVM to operate in timespans less than one second.
FAQs
expremental
The npm package @conflux-/aragon-apps-payroll receives a total of 1 weekly downloads. As such, @conflux-/aragon-apps-payroll popularity was classified as not popular.
We found that @conflux-/aragon-apps-payroll demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.
Security News
Socket CEO Feross Aboukhadijeh discusses open source security challenges, including zero-day attacks and supply chain risks, on the Cyber Security Council podcast.
Security News
Research
Socket researchers uncover how threat actors weaponize Out-of-Band Application Security Testing (OAST) techniques across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.