CertiK reviewed Altura (Altura NFT (Audit)) on 20 Dec 2023: 16 findings, 0 critical; 4 acknowledged, 12 open.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 2 | 0 |
| Medium | 0 | 2 | 0 |
| Low | 12 | 0 | 0 |
The `Clones.clone()` function deploys and returns the address of a clone that mimics the behavior of `targetAddress`. Since this function uses the create opcode, which should never revert. However, the `targetAddress` is not set because the `setTarget()` function is only called by the owner, who is set after the execution of the `__Ownable_init()` function.
The function `createCollection()` can be called by anyone as it has no access restriction. This enables anyone to call this and create a collection. If the collection is public, everyone can add items and mints nfts to anyone
Calling a user provided address is dangerous, especially in a public function with no access control restriction. An attacker could deploy a malicious contract and use the vulnerable function to trigger a call to the malicious contract, potentially stealing user funds or causing other serious damages.
It is unnecessary to transfer 0 NFTs to another account, as it not only wastes gas, but also leads to an increase in `totalSwapped` by 1, which results in useless data statistics.
There should always be events emitted in the sensitive functions that are controlled by centralization roles.
Addresses should be checked before assignment or external call to make sure they are not zero addresses.
It's recommended the team verify the UUPS implementation contract is initialized correctly. Besides initializing the contract, another way to prevent the implementation contract from being used is to invoke the "_disableInitializers" function in the constructor to automatically lock it when it is deployed. For more information, please refer to: https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable#initializing_the_implementation_contract
Contract `AlturaNFTFactoryV3` extends UUPSUpgradeable, while `__UUPSUpgradeable_init()` and `__UUPSUpgradeable_init_unchained()` are not called in the initialize function. Generally, the initializer function of an upgradeable contract should always call all the initializer functions of the contracts that it extends.
The function `buy()` is able to receive ether if the `items[_id].currency` is not equal to `address(0x0)`. However, there is no withdraw function in the `AlturaNFTFactoryV3` contract to empty any leftover ether from the contract.
The `Multicall2` contract cannot be set as the owner of other contracts. The functions `aggregate` and `tryAggregate` have no access control. If the `Multicall2` contract is the owner of the `target` contracts, anyone can call the ownership functions in the `target` contracts.
The `SafeMath` library is used unnecessarily. With Solidity compiler versions 0.8.0 or newer, arithmetic operations will automatically revert in case of integer overflow or underflow.
One or more state variables are never used in the codebase. Variable `_supportedTokens` in `AlturaNFTFactory` is never used in `AlturaNFTFactory`. ```solidity=68 EnumerableSet.AddressSet private _supportedTokens; ```
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (5)
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething 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