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
initTreasury
address
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
data
DataTypes.HireData
The data needed to hire an employee, defined as DataTypes.HireData
employeeSignature
bytes
The signature of the employee. The employee should sign the hash of 'getHireTransactionHash' with the terms of their agreement
Returns
<none>
uint256
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
tokenId
uint256
The ID of the payroll token
Returns
<none>
uint256
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
tokenId
uint256
The ID of the payroll token
Returns
<none>
uint256
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
tokenId
uint256
The ID of the payroll token
salaryEndDate
uint256
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
tokenId
uint256
The ID of the payroll token
salaryEndDate
uint256
The date that the employee will stop earning their salary
employeeSignature
bytes
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
actions
bytes4[]
The actions to be executed
params
bytes[]
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
action
bytes4
The action to be executed, represented as the selector of the function
params
bytes
The abi-encoded parameters of the action.
Returns
<none>
bytes32
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
actionId
bytes32
The ID of the action to be canceled
changeCashSalary
Changes the cash salary of the employee with 'tokenId' to 'newCashSalary'
Parameters
tokenId
uint256
The ID of the payroll token
newCashSalary
uint256
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
tokenId
uint256
The ID of the payroll token
equityExtension
uint256
The number of shares to be added to the employee's equity payments
durationExtension
uint32
The number of seconds to be added to the employee's vesting schedule
employeeSignature
bytes
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
tokenId
uint256
The ID of the payroll token
data
DataTypes.NewEquityPaymentsData
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
tokenId
uint256
The ID of the payroll token
cashPaymentAmount
uint256
The amount of cash to be paid to the employee
encodedDetails
bytes32
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
<none>
uint256
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
tokenId
uint256
The ID of the payroll token
equityPaymentAmount
uint256
The amount of equity to be paid to the employee
encodedDetails
bytes32
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
<none>
uint256
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
employee
address
The employee to hire
annualCash
uint256
The annual cash salary of the employee
equityAmount
uint256
The total number of shares to be paid to the employee over 'vestingDuration'
startDate
uint48
The start date of the employee, represented as a unix timestamp
vestingDuration
uint32
The number of seconds that it will take for the employee to be able to claim all of their shares
vestingCliff
uint32
The number of seconds that it will take for the employee to be able to claim their first shares
vestingInitialUnlock
uint256
The number of shares that the employee will be able to claim at the end of their cliff
employeeNonce
uint256
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
tokenId
uint256
The ID of the payroll token
endDate
uint256
The date that the employee will stop earning their salary
employeeNonce
uint256
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
tokenId
uint256
The ID of the payroll token
equityExtension
uint256
The total number of shares to be paid to the employee over 'vestingDuration'
durationExtension
uint32
The number of seconds to be added to the employee's vesting schedule
employeeNonce
uint256
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
newVersion
uint256
The new version to upgrade to
data
bytes
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