PayrollManager
Inherits: NoncesUpgradeable, ReentrancyGuardUpgradeable, Patchable, StateAware, AdminControlled, MezzEIP712, MezzERC721Upgradeable, IPayrollManager
Author: Daniel Yamagata
A soulbound ERC721 contract that manages the payroll of a company. The contract is controlled by the company's board of directors and a set of admins set by the board. Some actions require a 24-hour time delay before they are executable. This was done such that a compromised admin cannot drain a company's funds instantaneously. Rather, the action can be canceled by the board or another admin before its execution. These actions include:
Changing an employee's cash salary
Extending an employee's equity payments
Setting a new equity payment schedule for an employee
Paying cash directly to an employee
Paying equity directly to an employee
The tokens are never burned, even after an employee resigns or is terminated. This was done such to preserve the on-chain data that an employee once worked at a company. Whether or not an employee resigned or was terminated is tracked accordingly.
State Variables
HIRE_TYPEHASH
RESIGN_TYPEHASH
EQUITY_EXTENSION_TYPEHASH
PayrollManagerStorageLocation
Functions
_getPayrollManagerStorage
requireEmployed
Reverts if the token ID does not correspond to a current employee
constructor
init
Initializes the Payroll Manager. The 'initTreasury' is set as the controller of the contract. Can only be called once.
The payroll manager is initialized upon a company's deployment within the Mezz Deployer
Parameters
Name | Type | Description |
---|---|---|
|
| The treasury that will control the payroll manager |
__PayrollManager_init
hire
Hires an employee with an annual salary and equity. An employee's start date must be at least 24 hours after calling this function. Only callable by 'admins' or the board of directors, who are the signers of the treasury
An employee signature must be included such that they accept their offer. This prevents companies from defrauding others by claiming that they have hired a certain employee. It also confirms that the employee has accepted the terms of the agreement, so that they do not have to be altered at a later time
Parameters
Name | Type | Description |
---|---|---|
|
| The data needed to hire an employee, defined as DataTypes.HireData |
|
| The signature of the employee. The employee should sign the hash of 'getHireTransactionHash' with the terms of their agreement |
Returns
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
terminate
terminate
Terminates the employees associated with 'tokenId'. Collects all collectible cash for 'tokenId'. Only callable by an admin
increaseUnpaidTimeOff
increaseUnpaidTimeOff
Increases the unpaid time off for the employees associated with 'tokenId' by 'timeOff'. Only callable by an admin. Collects any collectible cash associated with 'tokenIds'
collectCash
Collects the cash owed to an employee. If the treasury does not have a sufficcient cash balance, the cash owed to an employee is updated, such that it will be collectible at a later time. The cash is transferred to the employee's specified recipient, which may be different from the employee, themself.
This function is not access controlled. Any account can collect cash on behalf of an employee.
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
Returns
Name | Type | Description |
---|---|---|
|
| The amount of cash paid, which may be different than the amount that was collectible. This is due to potential transfer fees that may be incurred by the cash asset. |
collectEquity
Collects the equity owed to an employee. The common shares are transferred to the employee's specified recipient. Equity compensation will always be in the form of the company's common shares. This function is callable by any account
This function is not access controlled. Any account can collect cash on behalf of an employee. This function is will revert if the employee's vesting schedule has been completed or if they did not have a vesting schedule to begin with.
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
Returns
Name | Type | Description |
---|---|---|
|
| The amount of equity released |
changeRecipient
Changes the recipient of the employee's salary to 'newRecipient'. Only callable by the owner of 'tokenId'
resign
Resigns the employee associated with 'tokenId'. Only callable by the token owner. The employee will continue to earn their salary until their 'salaryEndDate'
The 'salaryEndDate' cannot exceed 1 year into the future and cannot be in the past
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The date that the employee will stop earning their salary |
resignBySig
Resigns the employee associated with 'tokenId'. A signature from the employee is required. The employee will continue to earn their salary until their 'salaryEndDate'
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The date that the employee will stop earning their salary |
|
| The signature of the employee. The employee should sign the hash of 'getResignTransactionHash' |
_resign
proposeActions
Proposes a series of 'actions' to be executed in the future. Each action has a corresponding 'params' which are the abi-encoded arguments of the actions' corresponding function. Only callable by an admin.
Parameters
Name | Type | Description |
---|---|---|
|
| The actions to be executed |
|
| The abi-encoded arguments of the actions' corresponding function |
proposeAction
Proposed actions require a minimum delay of 24 hours before their execution. This is done such that a compromised admin cannot drain the company's funds instantaneously. Rather, the action can be canceled by another admin within the 24-hour window. Once the delay has passed, any account can execute the action. Actions that include a delay are:
Changing an employee's cash salary
Extending an employee's equity payments
Setting a new equity payment schedule for an employee
Paying cash directly to an employee
Paying equity directly to an employee This function will revert if the action has already been proposed.
Parameters
Name | Type | Description |
---|---|---|
|
| The action to be executed, represented as the selector of the function |
|
| The abi-encoded parameters of the action. |
Returns
Name | Type | Description |
---|---|---|
|
| The ID of the action, which is the hash of the action and its parameters |
cancelPendingAction
Cancels a pending action. Only callable by an admin
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the action to be canceled |
changeCashSalary
Changes the cash salary of the employee with 'tokenId' to 'newCashSalary'
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The new annual cash salary of the employee |
extendEquityPayments
Extends the equity payments of 'tokenId' by 'equityExtension' and increases the duration by 'durationExtension'
Must be proposed by an admin and executed after a 24 hour delay This function will revert if the vesting schedule associated with 'tokenId' is non-existent, which can occur if the employee never had a vesting schedule to begin with or their vesting schedule has been completed
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The number of shares to be added to the employee's equity payments |
|
| The number of seconds to be added to the employee's vesting schedule |
|
| The signature of the employee. The employee should sign the hash of 'getEquityExtensionTransactionHash' The employee signature is needed such that an employer cannot arbitrarily increase the of an employee's vesting schedule without the consent of the employee |
setNewEquityPayments
Sets a new equity payment schedule for 'tokenId'
Must be proposed by an admin and executed after a 24 hour delay This function will revert if 'tokenId' has an existing vesting schedule
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The new equity payment data as a DataTypes.NewEquityPaymentsData struct - data.equityAmount: The total number of shares to be paid to the employee - data.startDate: The start date of the employee, represented as a unix timestamp - data.vestingDuration: The number of seconds that it will take for the employee to be able to claim all of their shares - data.vestingCliff: The number of seconds that it will take for the employee to be able to claim their first shares - data.vestingInitialUnlock: The number of shares that the employee will be able to claim at the end of their cliff |
payCash
Pays 'cashPaymentAmount' to the recipient of 'tokenId' in the cash asset of the employee, which should be the company's denomination asset. The recipient may be different from the employee, themself
Must be proposed by an admin and executed after a 24 hour delay 'cashPaymentAmount' cannot exceed $10 million
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The amount of cash to be paid to the employee |
|
| Details regarding the cash payment as a bit-field. Must be either encoded to include either or both: DataTypes.PaymentDetails.Bonus or DataTypes.PaymentDetails.ContractorPayment. 'Encoding' is done by shifting left 1 by the value of the Payment Details enum |
Returns
Name | Type | Description |
---|---|---|
|
| The amount paid, which may be different than the 'cashPaymentAmount' due to ERC20 transfer fees |
payEquity
Pays 'equityPaymentAmount' to the recipient of 'tokenId' in the form of the company's common shares
Must be proposed by an admin and executed after a 24 hour delay 'equityPaymentAmount' cannot exceed the treasury common shares
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The amount of equity to be paid to the employee |
|
| Details regarding the equity payment as a bit-field. Must be either encoded to include either or both: DataTypes.PaymentDetails.Bonus or DataTypes.PaymentDetails.ContractorPayment. 'Encoding' is done by shifting left 1 by the value of the Payment Details enum |
updateEmployeeDocument
Updates the document related to the employee with 'tokenId' in the Document Registry. Only callable by the board or an admin
Returns
Name | Type | Description |
---|---|---|
|
| The new version of the document |
collectibleCash
Returns the amount of cash collectible by 'tokenId'
This function will revert if 'tokenId' has not been minted
collectibleEquity
Returns the amount of equity collectible by 'tokenId'
This function will revert if 'tokenId' has not been minted
isEmployee
Returns true if 'tokenId' is a current employee, false otherwise
This function will revert if 'tokenId' has not been minted. It will return false if the employee's end date has passed. An end date is set during an employee's termination or resignation
getSalary
Returns the salary of 'tokenId' in the form of a DataTypes.Salary struct
To query the vesting schedule of the employee, call 'getVestingSchedule()' of the company's token timelock with the salary's 'tokenTimelockTokenId'
hashAction
Returns the action id of an 'action' given its abi-encoded 'params'
isActionReady
Returns true if the pending action associated with 'actionId' is ready to execute, false otherwise
Will return false instead of reverting, even if the pending action does not exist
isPendingAction
Returns true if the pending action associated with 'actionId' exists, false otherwise
getPendingActions
Returns the action IDs of all outstanding pending actions as a bytes32 array
getPendingActionSnapshot
Returns the snapshot of the pending action associated with 'actionId' The snapshot is the unix timestamp at which the action can be executed
getHireTransactionHash
Returns the transaction hash of the encoded hire data
This hash is to be signed by the employee before being hired
Parameters
Name | Type | Description |
---|---|---|
|
| The employee to hire |
|
| The annual cash salary of the employee |
|
| The total number of shares to be paid to the employee over 'vestingDuration' |
|
| The start date of the employee, represented as a unix timestamp |
|
| The number of seconds that it will take for the employee to be able to claim all of their shares |
|
| The number of seconds that it will take for the employee to be able to claim their first shares |
|
| The number of shares that the employee will be able to claim at the end of their cliff |
|
| The nonce of the employee, which is used to prevent replay attacks |
_getHireStructHash
Encodes hire data as a struct hash following the EIP-712 encoding standards
Reference: https://eips.ethereum.org/EIPS/eip-712
getResignTransactionHash
Returns the transaction hash of the encoded resign data
This hash is to be signed by the employee when resigning via signature
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The date that the employee will stop earning their salary |
|
| The nonce of the employee, which is used to prevent replay attacks |
_getResignStructHash
Encodes resign data as a struct hash following the EIP-712 encoding standards
Reference: https://eips.ethereum.org/EIPS/eip-712
getEquityExtensionTransactionHash
Returns the transaction hash of the encoded equity extension data
This hash is to be signed by the employee when extending their equity payments
Parameters
Name | Type | Description |
---|---|---|
|
| The ID of the payroll token |
|
| The total number of shares to be paid to the employee over 'vestingDuration' |
|
| The number of seconds to be added to the employee's vesting schedule |
|
| The nonce of the employee, which is used to prevent replay attacks |
_getEquityExtensionStructHash
Encodes equity extension data as a struct hash following the EIP-712 encoding standards
Reference: https://eips.ethereum.org/EIPS/eip-712
name
Returns the name of the Payroll Manager
symbol
Returns the symbol of the Payroll Manager
version
Returns the version of the implementation as a uint256
coreId
Returns the coreId of the implementation as a bytes32
The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))
_validateSignature
_validateAreEmployees
_validateIsEmployee
_getAddressesForEmployees
Returns the addresses of employees for a given set of token IDs
_getCollectibleCashForEmployees
Returns the collectible cash for a given set of token IDs
_getTokenTimelock
_getCommonShares
approve
Overridden ERC721 approve() such that approvals are disabled
transferFrom
Overridden ERC721 transferFrom() such that transfers are disabled
_update
Overridden ERC721 update such that burning is disabled
_setApprovalForAll
supportsInterface
ERC165 support
onERC721Received
Reference: https://eips.ethereum.org/EIPS/eip-721
upgradeToNewerVersion
Upgrades 'this' to a newer version via the Mezz Migrator. Only callable by the Treasury, whose signers are the board of directors
Will revert if the protocol state is 'Paused' or 'Frozen'
Parameters
Name | Type | Description |
---|---|---|
|
| The new version to upgrade to |
|
| The data to be passed to the new implementation, which likely should be a reinitializer function if used |
_authorizePatch
Access control for 'resetToPatchedLatestVersion()'
Structs
PayrollManagerStorage
Last updated