As of 21 Oct 2026, Cadabra has 2 audit reports by 2 security firms on Trustblock; the latest is by PeckShield, dated 22 Nov 2023. 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 |
|---|---|---|---|---|---|
| Cadabra audit | Security firm: PeckShield | Date: | Scope: Not recorded (see the report) | No open critical findings | Open · GitHub |
| Cadabra Finance | Security firm: CertiK | Date: | Scope: Files named in the report | 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 | 3 | 0 | 2 |
| Medium | 1 | 0 | 3 |
| Low | 4 | 0 | 12 |
The report gives no description here.
Open the reportThe report gives no description here.
Open the reportThe report gives no description here.
Open the reportIf the `sqrtPriceX96` is greater than the maximum `uint128`, that is `2^128 - 1`, then when the following logic is reached it will revert due to overflow: ```solidity uint256 priceX192 = uint256(sqrtPriceX96) * uint256(sqrtPriceX96); ``` Thus in this scenario when the function `value()` is called on the `ThenaGammaToken0TWAPAdapter` it will revert, which will make it impossible for users to invest or redeem.
Open the reportThe `SUPPLY_OFFSET` and `ASSEST_OFFSET` are set to be `1e18`, which creates `1e18` virtual shares and `1e18` virtual assets. As the amount of virtual assets is greater than 1, it allows for the possibility that a user will redeem for more assets than they should be entitled to, or it may revert as it may overestimate the actual amount of assets held by the contract. This is because when shares are redeemed for assets the following equation is used: $$ \frac{shares * (nav + 1e18)}{totalSupply() + 1e18} $$ rearranging this gives $$ \frac{shares}{totalSupply() + 1e18} * (nav + 1e18) $$ If the total supply is redeemed at once this equation becomes $$\frac{totalSupply}{totalSupply() + 1e18} * (nav + 1e18) < nav + 1e18$$ However as the fraction $\frac{totalSupply}{totalSupply() + 1e18}$ converges to 1 as the total supply increases, this value may exceed the value of `nav`. Thus allowing for some of the locked profit or fees to be given when redeeming or if the entire total supply is redeemed and there are no locked fees it will cause it to revert due to a lack of funds.
Open the reportIn the contract `TwapUtils`, the function `getSqrtTwapX96()` has the following logic: ```solidity sqrtPriceX96 = TickMath.getSqrtRatioAtTick( int24((tickCumulatives[1] - tickCumulatives[0]) / SafeCast.toInt56(SafeCast.toInt256(uint256(twapInterval)))) ); ``` However, if the difference `tickCumulatives[1] - tickCumulatives[0]` is negative, then when dividing by the `twapInterval` it will not round towards negative infinity. (For example -10/3 = -3 as opposed to -4) This means that the tick with the slightly higher price will be chosen in this scenario.
Open the reportIn the contact `ChainLinkLib`, there a `TODO` comment as follows: ```solidity // TODO: L2 https://twitter.com/bytes032/status/1653943092427325448 // https://docs.chain.link/data-feeds/l2-sequencer-feeds ``` The first link addresses the potential problem of a sequencer going offline, while the second provides guidance on properly handling this issue for Arbitrum, Optimism, and Metis L2 chains.
Open the reportThe locked profits and fees are fixed and will not change in value as the invested tokens may. Thus if the invested tokens decrease dramatically in value, then the locked profits may exceed the total value of the adapters and cause calls to `_totalNAV()` to revert when the operation `value - lockedProfit` is performed.
Open the reportThere should always be events emitted in the sensitive functions that update important states.
Open the reportIf a chainlink feed uses more than 18 decimals, when `scaleFactor` is computed it will revert due to underflow. While most chainlink feeds use 8 or 18 decimals, it is possible for a feed with more than 18 decimals to be created and used in the future.
Open the reportIn the contract `LiquidityUtils` if the `reserve0` or `reserve1` is 0, then the function `ratio2` may unexpectedly revert due to a division by 0.
Open the reportThere is no method to recover tokens other than the `depositTokens()` that are accidentally sent to an adapter, causing them to be lost forever. As the swaps are input manually, it is possible that an incorrect token will be swapped for and sent to the adapter or users may accidentally send the wrong token directly to the adapter. In addition, in the contract `BalancerUpgradeable` in the function `rebalance()`, when `redeem()` is called the redeemed tokens are sent to `address(this)` and when `invest()` is called the dust is sent to `address(this)`. This allows for tokens to potentially be left in the `BalancerUpgradeable` contract.
Open the reportThe following comment is not correct in all possible cases ```solidity // shouldn't be susceptible to inflation attacks, since `valuePrior` can only increase through adding shares (???) ``` The `valuePrior` is determined by the `value()` returned by the adapter, which may depend on the value returned from an oracle, its balances stored in other contracts, or the balance of a certain token. These values may be able to be manipulated by an attacker. In general, the `value()` heavily depends on the adapter implementation.
Open the reportMany of the for loops execute functions that take a significant amount of gas, if enough adapters, swaps, or transfers are used the transaction may exceed the block gas limit.
Open the reportIn the contract `BalancerUpgradeable`: - The comment for the constant `REBALANCE_COOLDOWN` says "1 hour", when it is set to 6 hours. In the contract `ThenaGammaAdapter`: - The comment "// doesn't really mater what is `to` argument, shares are always issued to msg.sender" is not consistent with the functionality. The `to` argument indicates who the shares will be minted to and is not necessarily minted to the message sender.
Open the reportThis contract does not contain any method to remove native tokens from the contract. This will cause any native token sent to the contract through the `receive()` function to be permanently lost.
Open the reportIn the contract `TwapUtils`, the function `getSqrtTwapX96` performs the following logic: ```solidity if (twapInterval == 0) { uint32[] memory secondsAgos = new uint32[](1); secondsAgos[0] = 0; (sqrtPriceX96,,,,,,) = IPool(uniswapV3Pool).globalState(); } ``` However, the array `secondsAgos` is defined and initialized, but never used. If the `twapInterval` is 0, then it should fetch the current price, which can be done by reading it from the global state without the need for the `secondsAgos` array.
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="cadabra-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