Actuator Finance

Smart Contract Audit Report

Actuator Finance Audit Report

Executive Summary

This report presents the outcomes of our collaborative engagement with the Actuator Finance team, focusing on the comprehensive evaluation of the complete Actuator Finance platform.

Our team conducted an initial security assessment from August 15th to August 22nd, 2024 of the contracts folder at commit 5022c9c on the team's GitHub repository. This report was updated on August 27th, 2024, focusing on the changes presented in commit a168cd9 resolving all findings and updated team minting in the MasterChef contract.

Actuator Finance is a platform built on top of the HEX and Hedron protocols offering additional functionality. Users can mint and earn various tokens as well as earn additional rewards. It is important to note that the team's contracts rely on several contracts that have not been audited by our team. As a result we are unable to give an assessment in regard to security of any contract outside the scope of this audit.


Audit Scope


Audit Findings

All findings have been resolved, and minimal centralized aspects are present.

Finding #1

Actuator & HEXTimeToken

MediumResolved

Finding #1 - Actuator & HEXTimeToken
MediumResolved

Description: Users with Actuator tokens can deposit them in the Actuator contract. This credits the user with shares equal to the amount of deposited tokens in the HEXTimeToken contract. Users earn HEXTimeToken rewards based on their share amount. However, the Actuator token is 18 decimals and the HEXTimeToken is 8 decimals.

Risk/Impact: The accHttPerShare in the HEXTimeToken contract will be truncated unless the taxAmount is sufficiently large as the totalDeposits will be terms of 18 decimals:

accHttPerShare = accHttPerShare + (taxAmount * 1e12 / totalDeposits);

Recommendation: The team should increase the precision factor to account for the difference in decimals between the two tokens.

Resolution: The team has increased the precision to 1e22 to accommodate the difference in decimals between both tokens.

Finding #2

MasterChef

MediumResolved

Finding #2 - MasterChef
MediumResolved

Description: This contract allows users to deposit HEXTimeTokens to earn Actuator rewards over time. Users earn a portion of the rewards based on the amount of shares they have deposited relative to the total amount of tokens in the pool.

Risk/Impact: The accActrPerShare will be truncated if the lpSupply is sufficiently larger than the actrReward:

pool.accActrPerShare = pool.accActrPerShare + (actrReward * 1e12 / lpSupply);

Recommendation: The team should increase the precision factor to account for a potentially large difference between lpSupply and actrReward values.

Resolution: The team has increased the precision factor to 1e24 to accommodate potential differences in the size of the lpSupply and accActrPerShare.

Finding #3

Actuator

InformationalResolved

Finding #3 - Actuator
InformationalResolved

Description: The contract contains the following variables that are never used:

uint256 public totalShares;
uint256 public lastUpdate;
uint256 public totalDividendPoints;
uint256 pointMultiplier = 10e18;

Recommendation: The team should remove these variables to decrease contract size and deployment cost.

Resolution: The team has removed the unused variables.

Finding #4

HEXTimeTokenManager

InformationalResolved

Finding #4 - HEXTimeTokenManager
InformationalResolved

Description: The contract contains the _creator variable that is never used.

Recommendation: The team should remove this variable to decrease contract size and deployment cost.

Resolution: The team has removed the unused variable.


System Overview

Actuator

The Actuator token is an ERC-20 compliant token that can be minted by the contract's MasterChef address.

Deposits

Users may deposit their Actuator tokens at any time. The tokens are transferred to and stored within this contract. Users are credited with the amount deposited in the HEXTimeToken contract. Once users perform an initial deposit, they must use the increaseDeposit() function for subsequent deposits.

Withdraws

Users may withdraw their deposited tokens at any time. However, a penalty is taken if the "min vault time" of 90 days has not passed from the last time the user deposited. The penalty is calculated proportionally to the amount of time remaining until the min vault time is reached. For example, withdrawing after 45 days would be subject to a 50% penalty. Tokens taken as a penalty are burned and the remainder transferred to the user.

HEXTimeToken

The HEXTimeToken is an ERC-20 compliant token that can be minted by the HEXTimeTokenManager contract. Each instance of HEXTimeTokens are associated with a "maturity" which is the day the token matures.

Minting & Burning Tokens

The HEXTimeTokenManager can mint tokens at any time. Users are minted the full token amount if no tokens have been deposited. A tax amount of 1% is taken and retained in the contract if tokens have been deposited.

The HEXTimeTokenManager can burn tokens from a specified address at any time.

Deposits & Withdraws

The Actuator address may trigger a deposit at any time. This does not transfer any tokens but users are credited with the specified amount of tokens. This also updates the user's last deposit time.

The Actuator address may trigger a withdraw at any time. This similarly to deposits does not transfer any tokens but does subtract the specified amount of tokens from the user.

Fees & Rewards

All fees collected within the contract are distributed to users with deposited tokens. Users earn rewards based on the amount of tokens deposited relative to the total amount deposited. For example, if a user has deposited half of the tokens in the contract they will receive half of all rewards.

Users are transferred any pending rewards on deposits and withdraws. Users may also manually claim any pending rewards at any time.

MasterChef

The MasterChef contract distributes staked users Actuator tokens based on the current emission rate. The Team address is minted a specified amount of Actuator tokens upon deployment.

Adding Pools

Pools are added once per year for 3 years from the contract's deployment. Each Pool is associated with a specified HEXTimeToken. Additionally, existing Pools have their allocation points updated. Any user may trigger this by calling the massUpdatePools() function. The team must ensure that all of the point amounts in the poolPointSchedule do not exceed the MaxAllocPoint value to ensure proper progression of the pool point allocation.

Deposits & Withdraws

Users may deposit a Pool's corresponding HEXTimeTokens at any time. Users may withdraw their deposited HEXTimeTokens at any time.

Rewards

The contract accumulates Actuator rewards based on the elapsed time and the current emission rate. The emission rate is constant per year. The first 3 years each have their own emission rate. Rewards will no longer accumulate after 3 years.

Each Pool earns a portion of the accumulated rewards based on their allocated points. For example, if a Pool has been allocated half of the total points they will earn half of the accumulated rewards.

Users within each Pool earn rewards based on the amount of tokens they have staked relative to the total amount staked in the Pool. Similar to the Pool's allocated points, a user who has staked half of the total staked tokens in the Pool will earn half of the Pool's accumulated rewards. Users are transferred any pending rewards on each deposit and withdraw.

HEXTimeTokenManager

This contract allows users to deposit HEX tokens and HSI NFTs as collateral in order to mint HEXTimeTokens.

Payout

The contract maintains a running list of the cumulative payout per staked HEX per day. This information is retrieved from the HEX token contract.

Staking

Users may stake HEX tokens at any time for a specified staking duration. The specified amount of HEX tokens are transferred to the contract and subsequently staked via the HEXStakeInstanceManager. This creates an HSI NFT which is stored within the contract and credited to the user as an HSI instance.

Users may also delegate an HSI NFT they already own to the contract. The hexStakeDetokenize() function is called in the HEXStakeInstanceManager. The user is then credited with an HSI instance.

Minting HEXTimeTokens

Users may mint HEXTimeTokens using a staked HSI instance as collateral. The contract will create a new HEXTimeToken contract if one does not already exist for the specified maturity. Users may only mint HEXTimeTokens for one maturity at any given time for each staked instance.

Users may only mint HEXTimeTokens up to their "extractable" amount of staked HEX tokens at any given time. The extractable amount is determined based on the user's staked amount for the instance. Users are also credited with an additional amount of HEX tokens based on the current payout from the HEX contract up to a "reserve day". Tokens accumulated after the reserve day are considered "reserved".

The reserve day is calculated based on whether the HEXTimeTokens being minted would mature before or after the stake period would end. Users are credited from half of the stake length up to the reserve day if the HEXTimeTokens would mature before the stake period would end. The reserve day for HEXTimeTokens that would mature after the stake period is calculated based on the stake duration and the number of days until tokens mature after the stake period. An additional "late penalty" is deducted from the staked amount also based on when the tokens would mature after the stake period. In both cases, users are only credited up to the current day if the reserve day is in the future.

Returning HEXTimeTokens

Users may return minted HEXTimeTokens before their maturity date. This will burn the HEXTimeTokens from the user and deduct them from their borrowed amount.

Unstaking

Users may unstake their HEX tokens if they are not currently borrowing HEXTimeTokens using the specified HSI instance as collateral. This will end the stake in the HEXStakeInstanceManager contract and transfer the user all received HEX tokens.

Users may undelegate an HSI NFT that has been previously delegated to the contract if they are not currently borrowing HEXTimeTokens using the corresponding HSI instance as collateral. This will call the hexStakeTokenize() function on the HEXStakeInstanceManager. The contract will then transfer the HSI NFT back to the user.

Ending Collateralized Stake

Any user may end a stake that has borrowed HEXTimeTokens once the borrowed tokens have matured. If the tokens have not matured only the owner may end the stake after the stake duration has elapsed. Ending a collateralized stake will end the stake in the HEX contract and collect all redeemed HEX tokens.

The ending user will receive a "subsidy" of the redeemed HEX tokens based on when the tokens are redeemed assuming the corresponding HEXTimeTokens have matured. The subsidy is determined based on the amount of tokens reserved in the stake minus the late penalty. The user receives 1% of the reserves per day after the maturity (and redemption grace period) up to 10%.

The corresponding borrowed amount of the stake is added to the HEX balance of tokens maturing on the same day in order to be redeemed. Any remaining HEX tokens are transferred to the stake owner.

Redeeming HEXTimeTokens

Users may redeem their HEXTimeTokens once they have matured. This will burn the specified amount of HEXTimeTokens from the user and transfer them a corresponding amount of HEX tokens. The total amount of HEXTimeTokens that can be redeemed per maturity is incremented when collateralized stakes are ended.

Minting Hedron Tokens

Users can use this contract to mint Hedron tokens using an HSI instance. This will trigger the mintInstanced() function in the Hedron contract. This contract will transfer the user all Hedron received from this call.


Vulnerability Analysis

Vulnerability Category Notes Result
Arbitrary Jump/Storage Write N/A PASS
Centralization of Control The MasterChef Team address is minted a specified amount of Actuator tokens upon deployment. PASS
Compiler Issues N/A PASS
Delegate Call to Untrusted Contract N/A PASS
Dependence on Predictable Variables N/A PASS
Ether/Token Theft N/A PASS
Flash Loans N/A PASS
Front Running N/A PASS
Improper Events N/A PASS
Improper Authorization Scheme N/A PASS
Integer Over/Underflow N/A PASS
Logical Issues N/A PASS
Oracle Issues N/A PASS
Outdated Compiler Version N/A PASS
Race Conditions N/A PASS
Reentrancy N/A PASS
Signature Issues N/A PASS
Sybil Attack N/A PASS
Unbounded Loops N/A PASS
Unused Code N/A PASS
Overall Contract Safety   PASS

About SourceHat

SourceHat has quickly grown to have one of the most experienced and well-equipped smart contract auditing teams in the industry. Our team has conducted 1800+ solidity smart contract audits covering all major project types and protocols, securing a total of over $50 billion U.S. dollars in on-chain value!
Our firm is well-reputed in the community and is trusted as a top smart contract auditing company for the review of solidity code, no matter how complex. Our team of experienced solidity smart contract auditors performs audits for tokens, NFTs, crowdsales, marketplaces, gambling games, financial protocols, and more!

Contact us today to get a free quote for a smart contract audit of your project!

What is a SourceHat Audit?

Typically, a smart contract audit is a comprehensive review process designed to discover logical errors, security vulnerabilities, and optimization opportunities within code. A SourceHat Audit takes this a step further by verifying economic logic to ensure the stability of smart contracts and highlighting privileged functionality to create a report that is easy to understand for developers and community members alike.

How Do I Interpret the Findings?

Each of our Findings will be labeled with a Severity level. We always recommend the team resolve High, Medium, and Low severity findings prior to deploying the code to the mainnet. Here is a breakdown on what each Severity level means for the project:

  • High severity indicates that the issue puts a large number of users' funds at risk and has a high probability of exploitation, or the smart contract contains serious logical issues which can prevent the code from operating as intended.
  • Medium severity issues are those which place at least some users' funds at risk and has a medium to high probability of exploitation.
  • Low severity issues have a relatively minor risk association; these issues have a low probability of occurring or may have a minimal impact.
  • Informational issues pose no immediate risk, but inform the project team of opportunities for gas optimizations and following smart contract security best practices.