As of 14 Oct 2026, NAOS has 2 audit reports by 1 security firm on Trustblock; the latest is by Quantstamp, dated 24 Nov 2021. Those reports list no open critical findings.
Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Statuses are the security firms’ own. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| NAOS-Formation Updates | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
| Naos-Formation | Security firm: Quantstamp | Date: | Scope: Files named in the report | No open critical findings | Open · certificate.quantstamp.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 1 | 1 | 2 |
| Low | 0 | 2 | 14 |
The call `uniV2Router.swapExactTokensForTokens(alpacaToken.balanceOf(address(this)), 0, path, address(this), block.timestamp + 800);` sets the `amountOutMin` value to 0. If the pool is out-of-balance or manipulated in an unfavorable way (possibly through a [sandwich-attack](https://medium.com/coinmonks/defi-sandwich-attack-explain-776f6f43b2fd)), the swap may result in very few `bUSD` tokens being withdrawn.
Open the report`Formation.sol`, `L661`: the price fetching function Chainlink API (`latestAnswer()`) has been declared deprecated by Chainlink and may be outdated. Furthermore, `latestAnswer()` was used but its return value `updatedAt` and `answeredInRound` are not checked, and therefore the data could be arbitrarily old.
Open the reportThe related [TransmuterB.sol](https://github.com/alchemix-finance/alchemix-protocol/blob/master/contracts/TransmuterB.sol) contract utilizes an `ensureUserActionDelay` modifier, as implemented [here](https://github.com/alchemix-finance/alchemix-protocol/blob/14344a0386351b374da061122e1f5caf8e421afc/contracts/TransmuterB.sol#L330). This guards functions `stake`, `transmute`, and `forceTransmute`, and may mitigate unforeseen attacks such as flash loan attacks.
Open the reportThe following functions have return values that are not checked: 1. AlpacaVaultAdapter.withdraw(address,uint256) (contracts/adapters/AlpacaVaultAdapter.sol#124-133) ignores return value by busdToken.transfer(_recipient,busdToken.balanceOf(address(this))) (contracts/adapters/AlpacaVaultAdapter.sol#132) 1. AlpacaVaultAdapter.indirectWithdraw(address,uint256) (contracts/adapters/AlpacaVaultAdapter.sol#141-161) ignores return value by busdToken.transfer(_recipient,busdToken.balanceOf(address(this))) (contracts/adapters/AlpacaVaultAdapter.sol#160) 1. Formation._distributeToTransmuter(uint256) (contracts/Formation.sol#593-598) ignores return value by token.approve(transmuter,amount) (contracts/Formation.sol#594) 1. FormationV2._distributeToTransmuter(uint256) (contracts/FormationV2.sol#600-605) ignores return value by token.approve(transmuter,amount) (contracts/FormationV2.sol#601) 1. TransmuterV2._plantOrRecallExcessFunds() (contracts/TransmuterV2.sol#687-702) ignores return value by _activeVault.deposit(plantAmt) (contracts/TransmuterV2.sol#695) 1. TransmuterV2.migrateFunds(address) (contracts/TransmuterV2.sol#797-807) ignores return value by IERC20Burnable(Token).approve(migrateTo,migratableFunds) (contracts/TransmuterV2.sol#804) 1. AlpacaVaultAdapter.indirectWithdraw(address,uint256) (contracts/adapters/AlpacaVaultAdapter.sol#141-161) ignores return value by uniV2Router.swapExactTokensForTokens(alpacaToken.balanceOf(address(this)),0,path,address(this),block.timestamp + 800) (contracts/adapters/AlpacaVaultAdapter.sol#151-157) 1. YearnVaultAdapter.deposit(uint256) (contracts/adapters/YearnVaultAdapter.sol#63-65) ignores return value by vault.deposit(_amount) (contracts/adapters/YearnVaultAdapter.sol#64) 1. YearnVaultAdapter.withdraw(address,uint256) (contracts/adapters/YearnVaultAdapter.sol#73-75) ignores return value by vault.withdraw(_tokensToShares(_amount),_recipient) (contracts/adapters/YearnVaultAdapter.sol#74)
Open the reportEvery Solidity file specifies in the header a version number of the format `pragma solidity (^)0.4.*`. The caret (`^`) before the version number implies an unlocked pragma, meaning that the compiler will use the specified version _and above_, hence the term "unlocked".
Open the reportA fresh address could invoke `forceTransmute()`, in which case the bookkeeping handled by `checkIfNewUser()` will be incorrect.
Open the reportThe documentation states that "A CDP is healthy if its collateralization ratio is greater than the global collateralization limit.". However, in `L59` of `CDP.sol`, it returns true if the ratio is equal as well.
Open the reportIf a user accidentally deposits to this contract instead of the expected `Formation` contract, they will not be credited for their funds.
Open the reportThe `constructor` sets `flushActivator = 100000 ether` with the added comment "change for non 18 digit tokens". It is not clear which tokens will be used, but if their decimal values are significantly different than 18, this amount will be too small or large.
Open the report1. The function `MultiSigWallet.getTransactionIds` iterates over the entire transaction history on L384, even though only transaction with indices in the range `[from, to)` are under consideration. If the wallet has a long transaction history, this may cause an unnecessary amount of storage load (`SLOAD`) operations, and the function may fail due to gas limits. Although the function is declared `view`, `web3` clients may not execute functions beyond the gas-limit, and external contracts may try to invoke the function. 2. `StakingPools._updatePools` could fail if too many pools are added.
Open the report`Formation.sol`, `L440` states that "This function reverts if an emergency exit is active.". The intended revert is not present. Considering this is present for emergency, the lack of this revert may allow the attacker to forcefully push funds into the external protocol. If the external protocol was vulnerable and under attack, this exposes the funds in Formation to the attack as well.
Open the reportThe TimeToken contract does not seem to be used in the system. It is also not present in the tests.
Open the reportSome arguments in functions are not checked against zero. This leaves space for human-error and allows the arguments to be zero, which typically would simply revert, but in some cases it would result in transferring tokens to the `0x0` address and burning them. 1. `StakingPools.constructor` does not check that `_reward` is non-zero. 2. `StakingPools._token` does not check that `_token` is non-zero. 3. `Transmuter.constructor` does not check that `_NToken` and `_Token` are non-zero. 4. `Transmuter.setTransmutationPeriod` does not check that `newTransmutationPeriod` is non-zero. 5. `YearnVaultAdapter.constructor` should check that `_vault` and `_admin` are non-zero. 6. `Formation.constructor` should check that `_token` and `_xtoken` are non-zero.
Open the reportEvery Solidity file specifies in the header a version number of the format `pragma solidity (^)0.4.*`. The caret (`^`) before the version number implies an unlocked pragma, meaning that the compiler will use the specified version _and above_, hence the term "unlocked".
Open the reportThe purpose of `flush()` is to push the funds from `Formation` to the external protocol. Thus, it is unclear why `flush()` is activated in `withdraw()` when the specified `amount` is higher then the predefined threshold. When users withdraw more, the action tends to empty the Formation contract and there is no need to activate `flush()` at all.
Open the reportThe contracts declare the experimental feature ABIEnconderV2. As it is an experimental feature, it is more likely to include unknown bugs in the implementation.
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="naos"></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