ALTR security record

Polygon (POS)altr.tradeXGitHub

As of 3 Nov 2026, ALTR has 1 audit report on Trustblock, by CertiK, dated 2 Mar 2023. That report lists no open critical findings.

Critical findings
No open critical findings
In 1 report.
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.

Audits1

Newest first

AuditSecurity firmDateScopeCritical findingsReport
ALTRSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com

Findings18

Statuses are the security firm’s own, from each report.

SeverityOpenAcknowledgedFixed
Critical000
High022
Medium012
Low038
HighFunction Calls User-Provided Addresses With No AcALTR · CertiK · 2 Mar 2023Fixed

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.

Open the report
HighLack Of Access ControlALTR · CertiK · 2 Mar 2023Fixed

The function `grantRole` can be called by anyone as it has no access restriction. This enables anyone to call this and grant existing roles to any addresses. For the AltrFractions contract, there are `DEFAULT_ADMIN_ROLE` and `BURN_MANAGER_ROLE`.

Open the report
MediumIncorrect `maxAmount` Returned in `getFractionsAmALTR · CertiK · 2 Mar 2023Fixed

The function `getFractionsAmountByPrice()` in the contract `AltrFractionsSale` loops through the `tiers` mapping, uses the input `price` to retrieve the amount of fractions that an NFT can be divided into. Since `getFractionsAmountByPrice` is a `view` function, the result to be returned is purely based on the on-chain data. That is to say, if the input arrays are not well checked in `constructor()` and `setTiers()`, `getFractionsAmountByPrice()` would return an incorrect result.

Open the report
MediumPrivileged Address Not Assigned in `AltrFeeManageALTR · CertiK · 2 Mar 2023Fixed

In contract AltrFeeManager, there is a function `setSaleInfo()` that can set the redemption fee token address and the first price. An external caller is required to be a privileged role, `TRADE_CHECKER_ROLE`, because of the `onlyRole()` modifier. However, the `TRADE_CHECKER_ROLE` is never assigned in the contract, which means no addresses can successfully call the function.

Open the report
LowDiscussion on the `FractionsAmount` variableALTR · CertiK · 2 Mar 2023Fixed

In the `setupSale()` function of the contract `AltrFractionsSale`, the local variable is a new-ed `TimedTokenSplitter`. The input parameter of the new `TimedTokenSplitter` has `fractionsAmount` as `0`. In the same contract `fractionsAmount` is also used as a required input fields for a new FractionsSale struct, and the `FractionsSale` is saved to the state variable `fractionsSales[currentSaleId]`. We feel like the `fractionsAmount` concept in the TimedTokenSplitter contract is different from the concept in the AltrFractionsSale contract. Our understanding is that `fractionsAmount` represents for the cap of a fraction sale of a NFT in AltrFractionsSale, while in TimedTokenSplitter, `fractionsAmount` is more like `fractionsSold`. We would like to confirm if our understanding is correct.

Open the report
LowDivide Before MultiplyALTR · CertiK · 2 Mar 2023Fixed

Performing integer division before multiplication truncates the low bits, losing the precision of calculation. ```solidity=65 uint256 tokenPrice = redemptionToken.balanceOf(address(this)) / fractionsAmount; ``` ```solidity=69 fractionsPrice = tokenPrice * amounts[i]; ```

Open the report
LowLocked EtherALTR · CertiK · 2 Mar 2023Fixed

In the contract `AltrFeeManager`, the function `receive() external payable` can receive ether but the internal function `_transferEth` that can withdraw the fund is never called. In the contract `AltrTradeChecker`, the function `buyERC721(...) external payable` can receive ether but does not have a function to withdraw the fund. In addition, the `msg.value` of `buyERC721()` is neither recorded nor emitted via an event.

Open the report
LowMissing minimum time constraint on `openingTime`ALTR · CertiK · 2 Mar 2023Fixed

In the contract `AltrFractionsSale`, there is a function `setupSale()`, that can set up a new fraction sale. The requirement and initialization of two variables, `openingTime` and `closingTime`, caught our attention. The current require statements check that `openingTime > block.timestamp` and `closingTime > openingTime`. Our understanding is that there should be one or two constant variables like `MIN_OPENING_GAP` and `MIN_CLOSING_GAP` to make sure that a sale is not only open for a very short period of time, like one active block.

Open the report
LowMissing Sale Status Check in `withdrawFractionsKeALTR · CertiK · 2 Mar 2023Fixed

In contract `AltrFractionsSale`, the comment of the function `withdrawFractionsKept()` says that "The initiator can withdraw the fractions kept after the sale is closed and successful". However, the function implementation has only two checks: 1. the function caller is required to be the initiator 2. the fractions sold amount is required to be greater or equal to `saleMinFractions`, which is equivalent to checking that the sale is successful Neither of the two checks covers the case that the sale is required to be closed.

Open the report
LowUnused `DEFAULT_ADMIN_ROLE`ALTR · CertiK · 2 Mar 2023Fixed

In the contract `AltrAllowList`, the `DEFAULT_ADMIN_ROLE` is granted to the contract deployer in the constructor function. However, the privileged role is never used.

Open the report
Show 2 more
LowUnused Return ValueALTR · CertiK · 2 Mar 2023Fixed

The return value of an external call is not stored in a local or state variable. ```solidity=458 tiers.set(priceLimits[i], fractionsAmounts[i]); ``` --- ```solidity=131 _collectionAddressSet.add(address(collection)); ``` --- ```solidity=81 sellOrder.erc20Token.transferFrom(msg.sender, address(this), sellOrder.erc20TokenAmount); sellOrder.erc20Token.approve(address(zeroExContract), sellOrder.erc20TokenAmount); ```

Open the report
LowWrong EIP20 ApplicationALTR · CertiK · 2 Mar 2023Fixed

According to [EIP-20](https://eips.ethereum.org/EIPS/eip-20), functions `transfer()`, `transferFrom()`, and `approve()` should always have a `bool` return value, for the ERC20 caller to handle, as the callers must not assume that `false` is never returned.

Open the report

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

The repositories and files the reports name

Show this on your site

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.

Content

Facts

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.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="altr-1"
></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