As of 21 Oct 2026, Huma Finance has 5 audit reports by 3 security firms on Trustblock; the latest is by Halborn, dated 17 Dec 2025. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Huma Solana Programs | Security firm: Halborn | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · halborn.com |
| Solana Programs | Security firm: Halborn | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · halborn.com |
| contracts-v2 PR 486 | Security firm: Cantina | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · cantina.xyz |
| huma-contracts-v2 | Security firm: Cantina | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · cantina.xyz |
| Huma Finance - Audit | Security firm: CertiK | Date: | Scope: Repository at commit 1075003 | No open critical findings | Open · skynet.certik.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 1 | 0 | 0 |
| Medium | 0 | 0 | 1 |
| Low | 1 | 0 | 14 |
If `treasuryAddress` is the zero address, then protocol fee will be lost when `withdrawProtocolFee()` is called.
Open the reportThe report gives no description here.
Open the reportThe report gives no description here.
Open the reportThe report gives no description here.
Open the reportIn 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`.
Open the reportThe `initialize()` function in `BasePoolConfig.sol` can be called multiple times by the owner.
Open the reportThe `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.
Open the reportIn `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()`.
Open the reportThere 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.
Open the report`_safeApproveForPoolConfig(0)` is called after `_poolConfig` is changed to the `newPoolConfig`. Thus, it does not update the approval of the `oldConfig` to be 0.
Open the reportSuffixes 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.
Open the reportIf tokens are accidentally sent to the protocol directly, they will be stuck forever.
Open the reportThe 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.
Open the reportThe 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.
Open the reportWhen `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.
Open the reportThe reports name a repository or files. Open a report to see its scope.
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="huma-finance"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
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