This repository contains the HRManager Solidity smart contract, designed to implement a Human Resources (HR) Payment System on the Optimism blockchain. It enables HR managers to efficiently manage employee registrations, terminations, and salary withdrawals, while ensuring secure and transparent payments.
- HR Manager:
- Register new employees and set their weekly salaries.
- Terminate employees and stop their salary accrual.
- Employees:
- Withdraw accrued salaries in their preferred currency.
- Toggle salary payment preference between USDC and ETH.
- Register Employee: Add an employee with their weekly USD salary. Re-registering starts salary accrual afresh.
- Terminate Employee: Stops salary accrual for an employee and emits a termination event.
- Continuous Salary Accrual: Employees' salaries accrue linearly based on time (e.g., 2 days = 2/7th of weekly salary).
- Flexible Withdrawals:
- Employees can withdraw salaries in USDC (default) or ETH.
- Integration with Uniswap V3 AMM for real-time USDC-to-ETH conversion.
- Chainlink Oracle ensures accurate ETH/USD price feeds for withdrawals.
- Automatic Withdrawal:
- Any pending salary is automatically withdrawn when switching payment currencies.
- Employees can toggle their payment currency between:
- USDC (Default): Fast and stable currency.
- ETH: Real-time exchange through Uniswap.
- Triggers the
CurrencySwitchedevent for tracking.
- Blockchain: Optimism Layer 2.
- Dependencies:
- Chainlink Oracle for fetching ETH/USD price feeds.
- Uniswap V3 Router for AMM-based USDC-to-ETH swaps.
- Precision:
- USDC: 6 decimals.
- ETH: 18 decimals.
-
Clone the Repository:
git clone https://github.com/TonyP4N/HRManager.git cd HRManager -
Install Dependencies: Run the following commands to install the required dependencies for the project:
bash install.sh
-
Build the Contracts:
forge build
-
Test the Contracts:
forge test
- Access Control: Only HR manager.
- Purpose: Registers a new employee with a weekly USD salary.
- Validation: Salary must be greater than zero; reverts if employee is already registered.
- Updates:
- Sets employee details in the
Employeestruct. - Increments
activeEmployeeCount.
- Sets employee details in the
- Event: Emits
EmployeeRegistered.
- Access Control: Only HR manager.
- Purpose: Terminates an employee.
- Validation: Reverts if employee is not registered.
- Updates:
- Calculates unclaimed salary and updates
totalUsdSalaries. - Sets
isActivetofalseand updatesterminatedAt. - Decrements
activeEmployeeCount.
- Calculates unclaimed salary and updates
- Event: Emits
EmployeeTerminated.
- Access Control: Only callable by employees.
- Purpose: Allows employees to withdraw accumulated salary.
- Functionality:
- Calculates unclaimed salary based on time worked.
- Resets
lastWithdrawalTimeandtotalUsdSalaries. - Distributes salary in USDC or swaps to ETH via Uniswap if
prefersEthistrue.
- Security: Uses
nonReentrantto prevent reentrancy attacks. - Event: Emits
SalaryWithdrawn.
- Access Control: Only callable by employees.
- Purpose: Toggles salary payment between USDC and ETH.
- Functionality:
- Calls
withdrawSalary()before switching. - Toggles
prefersEth.
- Calls
- Event: Emits
CurrencySwitched.
- Purpose: Returns the amount of salary available for withdrawal.
- Functionality:
- Calculates accumulated salary.
- Salary Calculation:
- Calculates the time since the last withdrawal.
- Determines
unclaimedSalarybased ontimeDiffandweeklyUsdSalary. - Calculates
totalAmountas the sum ofunclaimedSalaryand anytotalUsdSalaries.
- Salary Calculation:
- Converts amount to ETH if
prefersEthistrue.
- Calculates accumulated salary.
- Purpose: Returns the HR manager's address.
- Purpose: Returns the count of active employees.
- Purpose: Retrieves employee's salary, employment start, and termination time.
- Functionality:
- If the employee is not active, returns zeros for all values.
- Otherwise, returns:
weeklyUsdSalaryemployedSinceterminatedAt
- Function:
swapUSDCToETH(uint256 usdcAmount) - Purpose: Swaps USDC to ETH when employees prefer to receive their salary in ETH.
- Implementation:
- Approvals:
- Uses
safeIncreaseAllowanceto allow the Uniswap router to spend USDC.
- Uses
- Slippage Consideration:
- Calculates
expectedEthAmountbased on the current ETH price. - Sets
amountOutMinimumto 98% ofexpectedEthAmountto allow up to 2% slippage.
- Calculates
- Swap Execution:
- Constructs
ExactInputSingleParamsfor the Uniswap router. - Calls
exactInputSingleon the Uniswap router to execute the swap.
- Constructs
- ETH Handling:
- Unwraps WETH to ETH using
IWETH9.withdraw(wethReceived). - Returns the amount of ETH received.
- Unwraps WETH to ETH using
- Approvals:
- Function:
getLatestETHPrice() - Purpose: Retrieves the latest ETH price in USD.
- Implementation:
- Calls
latestRoundData()on the price feed. - Ensures the retrieved price is valid (greater than zero).
- Adjusts price to 18 decimals for consistency.
- Calls
NotAuthorized- Thrown when an unauthorized user attempts to call a restricted function.
EmployeeAlreadyRegistered- Thrown when trying to register an employee who is already registered.
EmployeeNotRegistered- Thrown when attempting to terminate or interact with an employee who is not registered.
- Invalid Price From Oracle
- Thrown when the price retrieved from the oracle is invalid.
- Slippage Protection
- Swap reverts if slippage exceeds 2% during USDC to ETH conversion.
The contract emits several events to enable tracking of important actions:
EmployeeRegistered(address indexed employee, uint256 weeklyUsdSalary)- Emitted when a new employee is registered.
EmployeeTerminated(address indexed employee)- Emitted when an employee is terminated.
SalaryWithdrawn(address indexed employee, bool isEth, uint256 amount)- Emitted when an employee withdraws their salary.
CurrencySwitched(address indexed employee, bool isEth)- Emitted when an employee switches their salary currency preference.
- Security:
- Access control enforced via modifiers.
- Reentrancy protection on critical functions.
- Uses
SafeERC20for secure token operations.
- Employee Struct Fields:
weeklyUsdSalary: The weekly salary in USD (scaled to 18 decimals).employedSince: Timestamp of when the employee was registered.terminatedAt: Timestamp of when the employee was terminated (0 if active).lastWithdrawalTime: Timestamp of the last salary withdrawal.totalUsdSalaries: Accumulated unclaimed salary in USD.prefersEth: Indicates if the employee prefers salary in ETH (true) or USDC (false).isActive: Indicates if the employee is currently active.
- Salary Accumulation:
- Salary accrues continuously over time, regardless of non-working hours.
This project is licensed under the MIT License. See the LICENSE file for details.