LandX Finance security record

Arbitrum, Ethereumlandx.fiXGitHub

As of 3 Nov 2026, LandX Finance has 1 audit report on Trustblock, by Quantstamp, dated 10 Nov 2022. 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 and findings, contracts and incidents up to Nov 2026. Trustblock does not review code.

Audits1

Newest first

AuditSecurity firmDateScopeCritical findingsReport
LandX FinanceSecurity firm: QuantstampDate: Scope: Files named in the reportNo open critical findingsOpen · certificate.quantstamp.com

Findings25

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

SeverityOpenAcknowledgedFixed
Critical000
High005
Medium013
Low2014
High`rewardSharesPerToken` Is Not Always UpdatedLandX Finance · Quantstamp · 10 Nov 2022Fixed

When `rewardsToDistribute()` is called, it mints the vested tokens and increments the `rewardSharesPerToken`. However, the `rewardSharesPerToken` is not incremented if the vesting has fully completed at the time of the function call, as seen in the following code segment on L245: ```=solidity if (elapsedDays >= rewardVestingDuration) { amountVested = MAX_REWARD_AMOUNT.sub(rewardVested.amountVested); _mint(address(this), amountVested); rewardVested.amountVested += amountVested; rewardVested.lastVestedAt = block.timestamp; } ```

Open the report
High`xBasket` Not Minted to ReceiverLandX Finance · Quantstamp · 10 Nov 2022Fixed

The specified receiver of the `_deposit()` function in `xBasket` never receives the minted xBasket tokens as intended. Additionally, the `deposit()` and `mint()` functions check whether the receiver is able to mint/deposit the requested amount whereas the funds are taken from the `msg.sender`.

Open the report
HighIncorrect Rewards Accounting for Vested TokensLandX Finance · Quantstamp · 10 Nov 2022Fixed

The `LNDX` contract uses the global variables `rewardSharesPerToken` and `feeSharesPerToken` to track the amount of rewards and fees to distribute on a per token basis. To track how many rewards each user should receive, the contract stores the amount the user is not entitled to in the mappings `rewardsPerGrant` and `feePerGrant`. The simplified computation for the rewards of a user is then `amountOfTokens * rewardSharesPerToken - rewardsPerGrant`. Whenever a user claims rewards, `rewardsPerGrant` will therefore need to be updated to exclude the rewards that have just been claimed by adding them to `rewardsPerGrant`. The code however subtracts the claimed rewards from `rewardsPerGrant` (L198), which means the user will be able to claim even more tokens with each claim. Similarly, the code subtracts the fee that has been distributed from `feePerGrant` instead of adding it (L192). Additionally, the amount used is likely wrong since all tokens - including unvested ones - are used when computing the rewards.

Open the report
HighMissing Support for Multiple CropsLandX Finance · Quantstamp · 10 Nov 2022Fixed

The `crop` state variable in `xToken` is set to the constant value, "CORN". The `xToken` constructor is designed to receive a value for the string of the crop being created, however, this is just used for the name of the ERC20 token, and not for the assignment of the `crop` state variable. This protocol is intended to work around multiple crops (e.g. xSOY, xWHEAT) however this constant state variable does not allow this as any reading of this state will read "CORN". Further, `xBasket` only considers four predetermined crops. While it is understood that these are the four crops that the `xBasket` will be beginning with, the team should have the functionality to add or remove crops used in the `xBasket` as needed.

Open the report
HighSandwich AttacksLandX Finance · Quantstamp · 10 Nov 2022Fixed

A common attack in DeFi is the sandwich attack. Upon observing a trade of asset X for asset Y, an attacker front-runs the victim trade by also buying asset Y, lets the victim execute the trade, and then executes another trade after the victim by trading back the amount gained in the first trade. Intuitively, one uses the knowledge that someone is going to buy an asset, and that this trade will increase its price, to make a profit. The attacker’s plan is to buy this asset cheaply, let the victim buy at an increased price, and then sell the received amount again at a higher price afterward. The `getShards()` function of `xToken` converts both the shards mint fee and the `xTokensAnnualRent` from `xToken` to USDC through a Uniswap router. The `amountOutMinimum` and `sqrtPriceLimitX96` variables specified in the `ExactInputSingleParams` required for the Uniswap swap are set to 1, and 0 respectively, which will execute the swap even if there is one USDC returned to the user or a price of zero for the `xToken`. A savvy user could front-run these swaps to minimize the USDC returned to the `xToken` contract following the swap and profit off of the price change. This issue is also present in `xBasket.autoCompoundRewards()`, except they would be front-running USDC to `xToken` swaps.

Open the report
MediumIdentical Token Symbols for cTokensLandX Finance · Quantstamp · 10 Nov 2022Fixed

The `cToken` constructor instantiates the ERC20 symbol of all cTokens created as "cCorn". This creates cTokens with identical symbols.

Open the report
MediumMaximum Allowable Crop Share Not EnforcedLandX Finance · Quantstamp · 10 Nov 2022Fixed

The maximum allowable crop share value stored in `KeyProtocolVariables` is unused when minting a new LandXNFT. With nothing limiting the assignable value of the crop shares, LandXNFTs can be minted with crop share values that exceed the `maxAllowableCropShare` for the given crop as specified in `KeyProtocolVariables`.

Open the report
MediumUnclear Precision UsedLandX Finance · Quantstamp · 10 Nov 2022Fixed

The contracts use different precision values throughout the code base without properly documenting them. Constants such as `10 ** 3`, `1e6`, `10 ** 7` and `10**9` are just some of the constants that can be found in the code. Without documentation, it is impossible to verify that the correct precision is used everywhere.

Open the report
Low`totalAssets` Does Not Account for Potential YieldLandX Finance · Quantstamp · 10 Nov 2022Fixed

EIP-4626 specifies the following requirement for `totalAssets()`: > SHOULD include any compounding that occurs from yield. However, the current implementation of `totalAssets()` does not account for the potential yield.

Open the report
Low`unstakePreview()` Returns Inaccurate ValuesLandX Finance · Quantstamp · 10 Nov 2022Fixed

`unstakePreview()` returns a tuple of the staked amount, rewards, and fees for a given `stakeID` if it were to be unstaked. However, the rewards value is not guaranteed to be accurate because `computeStakeReward()` is dependent on `rewardSharesPerToken`, which can be modified by the `rewardsToDistribute()` call in `unstake()`. The `previewUnstake()` function does not take into account possible changes to `rewardSharesPerToken` when `rewardsToDistribute()` is called.

Open the report
Show 10 more
Low`xBasket` Auto Compound Potentially Vulnerable to Sandwich AttackLandX Finance · Quantstamp · 10 Nov 2022Fixed

Similar to the `xToken` sandwich attack issue, the `xBasket` also converts tokens using the UniswapV3 router without specifying a minimum amount out. Since sandwich attacks are only profitable for larger trades, it is unclear whether the yields from auto compounding are large enough to be at risk.

Open the report
LowHardcoded Price Used for xTokenLandX Finance · Quantstamp · 10 Nov 2022Fixed

While it may be acceptable to use hardcoded prices pre-launch, these prices should not be used following the LandX launch. If the Uniswap pool for the queried xToken does not exist, these hardcoded values are used.

Open the report
LowInconsistent Return Values for `calculateGrantClaim()`LandX Finance · Quantstamp · 10 Nov 2022Fixed

`calculateGrantClaim()` currently behaves inconsistently. If the entire vesting duration has elapsed, it returns a tuple of the full vesting duration and any unclaimed rewards. If only part of the vesting duration has elapsed, it returns a tuple of the number of vested but unclaimed days, and the number of unclaimed rewards. An excerpt of the function is included below: ```=solidity // Check cliff was reached uint256 elapsedDays = block.timestamp.sub(grant.startTime - 1 days).div( 1 days ); // If over vesting duration, all tokens vested if (elapsedDays >= grant.vestingDuration) { uint256 remainingGrant = grant.amount.sub(grant.totalClaimed); return (grant.vestingDuration, remainingGrant); // <- Returns full vesting duration (of which only a subset may be unclaimed) } else { uint16 daysVested = uint16(elapsedDays.sub(grant.daysClaimed)); uint256 amountVestedPerDay = grant.amount.div( uint256(grant.vestingDuration) ); uint256 amountVested = uint256(daysVested.mul(amountVestedPerDay)); return (daysVested, amountVested); // <- returns only the unclaimed vested days } ```

Open the report
LowIncorrect Version of SolidityLandX Finance · Quantstamp · 10 Nov 2022Fixed

The contracts currently use solidity version `0.8.6`. Due to a [medium severity bug](https://blog.soliditylang.org/2022/08/08/calldata-tuple-reencoding-head-overflow-bug/) in the solidity compiler since version `0.5.8`, this version is not in the [list of recommended versions](https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity).

Open the report
LowInherited Contract UnusedLandX Finance · Quantstamp · 10 Nov 2022Fixed

The `OraclePrices` contract inherits from both `Ownable` and `AccessControlEnumerable`. `Ownable` is unused and provides only a subset of the `AccessControlEnumerable` functionality and can thus be removed.

Open the report
LowMissing Input ValidationLandX Finance · Quantstamp · 10 Nov 2022Fixed

It is important to validate inputs, even if they only come from trusted addresses, to avoid human error. The functions `updateXTokenMintFee()`, `updateCTokensSellFee()`, `updatePayRentFee()`, `updateMaxAllowableCropShare()`, `updateHedgeFundAllocation()`, `updateSecurityDepositMonths()` in `KeyProtocolVariables` do not impose bounds on the values being set. This allows for fees over 100% to be assigned which would result in the loss of user funds. A non-exhaustive list of functions missing validation includes: * `KeyProtocolVariables`: Confirm that the following functions update variables to reasonable values (Ex. confirm that percentages cannot be above 100%). * `updateXTokenMintFee()` * `updateCTokenSellFee()` * `updatePayRentFee()` * `updateHedgeFundAllocation()` * `nft.setBaseURI()`: Validate that `newuri` is not an empty string. * `OraclePrices.setGrainPrice()`: Confirm that the grain exists. * `OraclePrices.setXTokenPrice()`: Confirm that the xToken exists. * `xToken.preview()`: Perform the same require statements performed in `getShards()`.

Open the report
LowNo Error Handling for Failed Grain Price AssignmentLandX Finance · Quantstamp · 10 Nov 2022Fixed

There is no error handling in the case that `oraclePrices.setGrainPrice()` fails in the Chainlink fulfill functions found in `OracleMulti`. Setting the grain price will fail if an invalid price was returned from the Chainlink request and the contract should react accordingly.

Open the report
LowOwnership Can Be RenouncedLandX Finance · Quantstamp · 10 Nov 2022Fixed

If the owner renounces their ownership, all ownable contracts will be left without an owner. Consequently, any function guarded by the `onlyOwner` modifier will no longer be able to be executed.

Open the report
LowRequire Message Deviates From Checked ConditionLandX Finance · Quantstamp · 10 Nov 2022Fixed

The function `grantLNDX()` checks that the `cliffInMonths` argument is less than five years when the require message states that it should be less than one year.

Open the report
LowUnlocked PragmaLandX Finance · Quantstamp · 10 Nov 2022Fixed

Every Solidity file specifies in the header a version number of the format `pragma solidity (^)0.8.*`. 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 report
Show 2 more
LowUnnecessary Use of `SafeMath` in Solidity 0.8.xLandX Finance · Quantstamp · 10 Nov 2022Fixed

Solidity 0.8.x has a built-in mechanism for dealing with overflows and underflows. There is no need to use the `SafeMath` library (it only increases gas usage).

Open the report
LowUntraceable Contract EventsLandX Finance · Quantstamp · 10 Nov 2022Fixed

Staking and unstaking xTokens, as well as auto-compounding xBasket rewards, does not emit events and is therefore untraceable. This inhibits off-chain monitoring of these events.

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="landx-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