As of 3 Nov 2026, Unreal Finance has 1 audit report on Trustblock, by CertiK, dated 13 Oct 2022. That report lists no open critical findings.
Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Unreal 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 | 2 | 0 | 1 |
| Medium | 0 | 0 | 1 |
| Low | 2 | 0 | 14 |
`Core` is an upgradeable contract that does not protect its `initialize()` function. Anyone can delete the contract with: `UUPSUpgradeable.upgradeTo(address)` or `UUPSUpgradeable.upgradeToAndCall(address, bytes)`. ```solidity function initialize(address _treasuryAddress) public initializer{ ``` ```solidity function upgradeTo(address newImplementation) external virtual onlyProxy { ``` ```solidity function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { ```
Open the reportA state variable is shadowing another component defined in a parent contract. Variable `_owner` in `Core` shadows the variable `_owner` in `OwnableUpgradeable`. ```solidity=18 address private _owner; ``` ```solidity=22 address private _owner; ```
Open the reportVariable `_decimals` can be made private to avoid two getter functions `_decimals()` and `decimals()` that return the same value.
Open the reportThe input `_protocol` used to check whether the given protocol is supported does not necessarily have to match the protocol that corresponds to the futures contract implemented through the input `_bytecode`. It is possible bytecode for a futures contract corresponding to one protocol is stored under the `streamKey` of a different protocol.
Open the report`_amountUnderlying` is the amount of underlying asset the `msg.sender` wishes to deposit, while `totalSupply` refers to the total supply of associated yield tokens for that underlying asset. The yield tokens are in one-to-one ratio with the asset tokens that are deposited, and they have the same decimals as the underlying asset. It is possible for the entire product `yield * _amountUnderlying / totalSupply` to exceed the value of `_amountUnderlying`, causing a revert due to underflow in `amountOT`. This may keep a user from depositing the underlying asset.
Open the reportWhen transferring deflationary ERC20 tokens, the input amount may not be equal to the received amount due to the charged transaction fee. For example, if a user sends 100 deflationary tokens (with a 10% transaction fee), only 90 tokens actually arrived to the contract. However, a failure to discount such fees may allow the same user to withdraw 100 tokens from the contract, which causes the contract to lose 10 tokens in such a transaction. Reference: https://thoreum-finance.medium.com/what-exploit-happened-today-for-gocerberus-and-garuda-also-for-lokum-ybear-piggy-caramelswap-3943ee23a39f ```solidity=31 IERC20(underlying).safeTransferFrom(msg.sender, address(this), _amount); ``` - Transferring tokens by `_amount`. ```solidity=33 ILendingPool(getProtocolFrontend()).deposit(underlying, _amount, address(this), 0); ``` - The `_amount` appears to be used for bookkeeping purposes without compensating the potential transfer fees. - Note: `deposit` is an external function and its behavior wasn't evaluated. --- ```solidity=31 IERC20(underlying).safeTransferFrom(msg.sender, address(this), _amount); ``` - Transferring tokens by `_amount`. ```solidity=33 IPool(getProtocolFrontend()).supply(underlying, _amount, address(this), 0); ``` - The `_amount` appears to be used for bookkeeping purposes without compensating the potential transfer fees. - Note: `supply` is an external function and its behavior wasn't evaluated. --- ```solidity=30 IERC20(underlying).safeTransferFrom(msg.sender, address(this), _amount); ``` - Transferring tokens by `_amount`. ```solidity=32 cToken.mint(_amount); ``` - The `_amount` appears to be used for bookkeeping purposes without compensating the potential transfer fees. - Note: `mint` is an external function and its behavior wasn't evaluated. --- ```solidity=120 deposit(_amountInUnderlying); ``` - Transferring tokens by `_amountInUnderlying`. - This function call executes the following operation. - In `AFuture.deposit`, - `IERC20(underlying).safeTransferFrom(msg.sender, address(this), _amount);` ```solidity=120 deposit(_amountInUnderlying); ``` - This function call executes the following operation. - In `AFuture.deposit`, - `ILendingPool(getProtocolFrontend()).deposit(underlying, _amount, address(this), 0);` - Note: `deposit` is an external function and its behavior wasn't evaluated. - The `_amountInUnderlying` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=120 deposit(_amountInUnderlying); ``` - Transferring tokens by `_amountInUnderlying`. - This function call executes the following operation. - In `YFuture.deposit`, - `IERC20(underlying).safeTransferFrom(msg.sender, address(this), _amount);` ```solidity=120 deposit(_amountInUnderlying); ``` - This function call executes the following operation. - In `YFuture.deposit`, - `yVault.deposit(_amount, address(this));` - Note: `deposit` is an external function and its behavior wasn't evaluated. - The `_amountInUnderlying` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ```solidity=126 deposit(_amount); ``` - Transferring tokens by `_amount`. - This function call executes the following operation. - In `AFuture.deposit`, - `IERC20(underlying).safeTransferFrom(msg.sender, address(this), _amount);` ```solidity=126 deposit(_amount); ``` - This function call executes the following operation. - In `AFuture.deposit`, - `ILendingPool(getProtocolFrontend()).deposit(underlying, _amount, address(this), 0);` - Note: `deposit` is an external function and its behavior wasn't evaluated. - The `_amount` appears to be used for bookkeeping purposes without compensating the potential transfer fees.
Open the reportFunctions that affect the status of sensitive variables should emit events as notifications.
Open the report- Input `_underlying` is missing a check that it is a non-zero address - Input `_durationSeconds` is missing a check that it is a non-zero value. - Input `_amountUnderlying` is missing a check that it is a non-zero value. - Input `_supply` is missing a check that it is a non-zero value. - Input `_core` and `_treasuryAddr` are missing a check that they are non-zero addresses. - State variable `yT` is missing a check that it is a non-zero address. - State variable `oT` is missing a check that it is a non-zero address. - Local variables `lendingProvider`, `compToken`, and `yearnVault` are missing a check that they are non-zero addresses.
Open the reportFunction `redeemYield()` can be called more than once, where all subsequent times will be for an `amountBurned` value of 0. Like function `redeemPrinciple()`, there should be a check that `amountBurned` is positive before proceeding with `claimYield()`.
Open the reportIn function `startEpoch()`, a check is made that the calculated `streamKey` corresponding to the input for `_protocol`, `_underlying`, and `_durationSeconds` is not `bytes32(0)`. No such check is made in `registerNewStream()`.
Open the reportThe construction of a futures contract depends on the correct input for `_bytecode` by the `_owner` of contract `Core`. However, the only check that the intended contract deployment was successful is that the `owner()` of the new futures contract is `address(this)`.
Open the reportThe return value of the transfer()/transferFrom() call is not checked. ```solidity=43 IERC20(underlying).transfer(treasury, underlyingbalance); ``` --- ```solidity=83 yT.transfer(_receiver, _amount); ``` --- ```solidity=93 oT.transfer(_receiver, _amount); ``` --- ```solidity=40 IERC20(underlying).transfer(treasury, underlyingbalance); ```
Open the reportThe contracts cited have unlocked compiler versions. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to an ambiguity when debugging as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.
Open the reportThe return value of an external call is not stored in a local or state variable. ```solidity=66 prevEpochInstance.expire(); ``` --- ```solidity=42 ILendingPool(getProtocolFrontend()).withdraw(underlying, _amount, treasury); ``` --- ```solidity=42 IPool(getProtocolFrontend()).withdraw(underlying, _amount, treasury); ``` --- ```solidity=32 cToken.mint(_amount); ``` --- ```solidity=41 cToken.redeem(_amountCToken); ``` --- ```solidity=29 yVault.deposit(_amount, address(this)); ``` --- ```solidity=38 yVault.withdraw(_amount); ```
Open the reportOne or more state variables are never used in the codebase. Variable `_owner` in `Core` is never used in `Core`. ```solidity=18 address private _owner; ``` ```solidity=15 contract Core is Initializable, UUPSUpgradeable, OwnableUpgradeable { ``` --- Variable `initialized` in `Core` is never used in `Core`. ```solidity=20 bool initialized; ``` ```solidity=15 contract Core is Initializable, UUPSUpgradeable, OwnableUpgradeable { ```
Open the reportThe variables `provider`, `yVault`, `cToken`, and `_decimals` assigned in the constructor can declared with `Immutable`. Immutable state variables can be assigned during contract creation but will remain constant throughout the lifetime of a deployed contract. An advantage of immutable variables is that reading them is significantly cheaper than reading from regular state variables since will not be stored in storage.
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="unreal-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