Huma Finance - Audit

CertiKRepository at commit 1075003

CertiK reviewed Huma Finance (Huma Finance - Audit) on 30 Dec 2022: 14 findings, 0 critical; 12 marked fixed, 2 open.

No open critical findings
Open the reportOpen Huma Finance’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings14

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical000
High100
Medium001
Low1011
MediumPotential Lost Protocol FeesFixed

If `treasuryAddress` is the zero address, then protocol fee will be lost when `withdrawProtocolFee()` is called.

Low`approveCredit()` Comment Is UnclearFixed

In the comment for `approveCredit()` it says it approves the credit request with the terms on record. However, it uses the inputs not the terms on record for the `creditLimit`, `intervalInDays`, `remainingPeriods`, and `aprInBps`.

Low`initialize()` Can Be Called Multiple TimesFixed

The `initialize()` function in `BasePoolConfig.sol` can be called multiple times by the owner.

LowLack of Access ControlFixed

The `mintNFT()` function in `EvaluationAgentNFT.sol` has no access control, allowing anyone to mint themselves an NFT. While it is not possible to get access to privileged functions with simply minting an NFT, it is is still possible for a malicious user to mint themselves an NFT and attempt to pose as an EA in a phishing attempt.

LowMissing ChecksFixed

In `BasePoolConfig.sol`: - In `setEARewardsAndLiquidity()`, it is not checked that the input `rewardsRate` and `liquidityRate` are less than or equal to `10000`. - In `setHumaConfig()`, it is not checked that the input `_humaConfig` is not the zero address. - In `setPoolLiquidityCap()`, it is not checked that the input `liquidityCap` is greater than zero. - In `setPoolOwnerRewardsAndLiquidity()`, it is not checked that the input `rewardsRate` and `liquidityRate` are less than or equal to `10000`. - In `setPoolPayPeriod()`, it is not checked that the input `periodInDays` is non-zero. - In `setPoolToken()`, it is not checked that the input `_poolToken` is not the zero address. - In `withdrawEAFee()`, it is not checked that the input `amount` is non-zero. - In `withdrawPoolOwnerFee()`, it is not checked that the input `amount` is non-zero. In `BaseCreditPool.sol`: - In `approveCredit()`, it is not checked that the credit limit is less than or equal to the max credit line. It is possible this could accidentally be set higher than the maximum amount as the inputs of approve credit are never checked against the requested credit. In `BasePool.sol`: - In `reverseIncome()`, if the calculated `poolIncome` is larger than the `_totalPoolValue`, this will cause a revert and not allow a user to payoff their debt early. We recommend handling this case as is done in `distributeLosses()`.

LowPossible OverflowFixed

There is casting from `uint256` to lower integers such as `uint96`, which can overflow and will not return an error. Similarly there is also casting between `uint` and `int`, which can cause unexpected errors. For example in `BaseCreditPool`: feesAndInterestDue is a `uint96`. If it is greater than the max positive `int96`, then it will end up being a large negative value when it is cast as an `int`. For tokens with 18 decimals, this means it would have to be over 39 billion. For example in `BaseFeeManager`: If `fees+interest` is greater than or equal to `2**96`, then it will overflow. For tokens with 18 decimals, this means that it would have to be over 79 billion. For example in `ReceivableFactoringPool.sol`: If `receivableAmount` is greater than or equal to `2**88` it will overflow. For tokens with 18 decimals, this means it would have to be over 309 million.

LowSets Approval Of `newPoolConfig` to `0` instead oFixed

`_safeApproveForPoolConfig(0)` is called after `_poolConfig` is changed to the `newPoolConfig`. Thus, it does not update the approval of the `oldConfig` to be 0.

LowTime Units Can Be Used DirectlyFixed

Suffixes like seconds, minutes, hours, days and weeks after literal numbers can be used to specify units of time where seconds are the base unit and units are considered naively in the following way: - 1 == 1 seconds - 1 minutes == 60 seconds - 1 hours == 60 minutes - 1 days == 24 hours - 1 weeks == 7 days The gas is almost the same usage on either method, but this increases code readability.

LowTokens Can Be Stuck In The ProtocolFixed

If tokens are accidentally sent to the protocol directly, they will be stuck forever.

LowTyposFixed

The following typos are found throughout the repo: In `BasePool`, the following typos were found: - depisit should be spelled deposit. - reqirements should be spelled requirements. ---- In `HumaConfig`, the following typos were found: - "* @param valid The new validity status a Liquidity Asset in Pools." should be something similar to "* @param valid The new validity status of a Liquidity Asset in Pools." - sentivity should be spelled sensitivity. ---- In `HDT`, the following typos were found: - brun should be spelled burn - `_owner` is the owner of the token contract, however the amount is the amount that the input `account` can withdraw. We think this should be `account` instead of `_owner`. ---- In `BasePoolStorage`, the following typos were found: - whether should be capitalized. ---- In `BasePoolConfig`, the following typos were found: - bais should be spelled basis. - depositers should be spelled depositors. - M0difier should be spelled Modifier. - Line 23 and 36 are outdated comments. We recommend updating the comments. ---- In `BaseStructs`, the following typos were found: - "credit originated" should just be credit or explain where it originated from. ---- In `BaseFeeManager`, the following typos were found: - stotal should be spelled total. - assersion should be spelled assertion ---- In `BaseCreditPool`, the following typos were found: - distribut should be spelled distribute. - "Positive correction is generated becasue of a drawdown within this period," should have a "." instead of a ",". - distributed should be changed distribute. - "be add" should be changed to "will be added". - themselvers should be spelled themselves. - becasue should be spelled because. - calcuate should be spelled calculate. - actuall should be spelled actual. - indciating should be spelled indicating. - initate should be spelled initiate. - creditRecrodStatic should be corrected to creditRecordStatic. - deaulted should be corrected to defaulted. - shwos should be changed to shows. ---- In `ReceivableFactoringPool`, the following typos were found: - assset should be spelled as asset. - dispersement should be spelled disbursement. - addrescredit should be spelled addresscredit.

Show 2 more
LowTypos and Errors In Change To Centralized RolesFixed

The following typos and errors were found in the code: - In `BaseCreditPool.sol`, in the comment for the function `_makePayment()`, “manul” is used instead of “manual”, “Outier” is used instead of “Outlier”, “actuall” is used instead of “actual”. Also there is a missing comment for the third return variable `isReviewRequired`. - In `BaseCreditPool.sol`, in the comment for the event `PaymentMade`, it still reads “it is possible for someone to make payment on behalf of the borrower.” However, the logic of `makePayment()` has changed so payments can only be made by the borrower or come from a receivable. In addition, the `PaymentMade` event emitted in `_makePayment()` has `msg.sender` for the `by` address, as the tokens are always payed by the borrower in this case either this should be changed to `borrower` or the comment for `by` address changed. - In `BasePoolConfig.sol`, "_opeartor" is used instead of "_operator" in multiple places. - In `BasePool.sol`, the comment for the function `addApprovedLender()` mentions only the pool owner can call this function, when now only a `poolOperator` can call the function. In addition, only a `poolOperator` can disable a pool, we recommend having the comments in `BasePoolConfig.sol` reflect that operators can also disable pools.

LowVariables Not Initialized on DeploymentFixed

When `BasePoolConfig` is deployed, there is minimal initialization for variables in the configuration. Because of this, the deployment script needs to be thoroughly checked to ensure that all variables are initialized to proper values to ensure issues do not occur.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (22)

  • https://github.com/00labs/huma-contracts/contracts/BasePool.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/interfaces/ICredit.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/HDT/interfaces/IHDT.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/libraries/BaseStructs.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/BaseCreditPool.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/HDT/HDTStorage.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/BasePoolConfig.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/Errors.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/ReceivableFactoringPool.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/BaseFeeManager.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/interfaces/ILiquidityProvider.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/interfaces/IReceivable.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/interfaces/IFeeManager.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/BasePoolStorage.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/HumaConfig.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/interfaces/IPool.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/openzeppelin/TransparentUpgradeableProxy.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/openzeppelin/TimelockController.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/EvaluationAgentNFT.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/HDT/HDT.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/ReceivableFactoringPoolStorage.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a
  • https://github.com/00labs/huma-contracts/contracts/BaseCreditPoolStorage.sol at commit 1075003788f343a1a30606834fd9ac073b23c23a

Part of Huma Finance’s security record

Huma Finance
Audits5 audits by 3 firmsLast audit Dec 2025, by Halborn.
Critical findingsNo open critical findingsAcross 5 reports.
Open Huma Finance’s security record

Security firm

CertiK

1,044 projects reviewed · 1,393 reports · latest May 2025

See CertiK’s audits

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us