As of 3 Nov 2026, LendeXe Finance has 1 audit report on Trustblock, by CertiK, dated 28 Apr 2023. 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
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 1 |
| High | 3 | 0 | 5 |
| Medium | 0 | 0 | 4 |
| Low | 0 | 0 | 15 |
The visibility of the function `transfer()` is public, which allows anyone to transfer tokens from the `from` address to the `to` address. The visibility of the function `approve()` is public, which allows anyone to set allowance of `spender` over the `owner's` token. The visibility of the function `spendAllowance()` is public, which allows anyone to update the `owner's` allowance for `spender` based on the spent `amount`.
Open the reportIn the history of the compound protocol, the calculation of the Comp rewards becomes incorrect after proposal 062(`Split COMP rewards distribution and bug fixes`) is executed. In response to this problem, the function `fixBadAccruals()` has been temporarily added in proposal 065(`Correct Over-Accrued COMP`) and removed later. The function `fixBadAccruals()` is a centralized function. It will update the users' unclaimed Comp rewards to decrease the incorrect rewards, and record the COMP debt in the variable `compReceivable` for the users whose unclaimed Comp rewards are not enough to decrease. The function `fixBadAccruals()` is only used to handle the error caused by this upgrade migration in the Compound protocol, which is useless in the newly deployed Compound forks. Refer to: - https://compound.finance/governance/proposals/62 - https://compound.finance/governance/proposals/65
Open the reportThe function `_setSwapHelperAddress()` is `external` and can be called by anyone as long as the contract is deployed.
Open the reportThe function `_setSwapRouter()` is `external` and can be called by anyone as long as the contract is deployed.
Open the reportThe input variable `nftAmount` is not validated in the function `supply()`, so the user can input the arbitrary `nft` amount to mint the maximum allowed XSD tokens.
Open the reportThe user can provide assets by calling the function provide() in the contract `UltimateLoan` and then directly call the function `burn()`/`burnShares()` in the contract `XSDStabilizer` to perform an arbitrage attack. The steps can be as follows, 1. call function `supply()` to lock xLEXE tokens as collateral, then receive XSD tokens, which is 150% of locked XLEXE tokens in value. 2. call the function `burn()`/`burnShares()` in the contract `XSDStabilizer` instead of the function `repay()` to burn XSD tokens will eventually receive 50% of the locked XLEXE tokens value in profit. ```solidity=240 (uint256 mintAmount, ) = stabilizer.mintShares(xsdAmount, supplyTokens); //UL will gain double the xsd amount that was set as input because it locks an equal amount of LEXE uint256 portionOfOwnerMint = mul_(mintAmount, Exp({mantissa: 0.75e18})); ``` In an extreme case, the user can give up repaying the loan, and receive 50% of the locked `xLEXE` tokens value in profit.
Open the reportThe contract deployer can input himself as the admin to pass the validation. ```solidity=349 constructor( XSDStabilizer XSDStabilizer_, address lexeVault_, address payable admin_, Lexe lexe_, XToken xLEXE_, XToken[] memory supplyTokens_, uint256[] memory supplyTokenShares_, XSDInterface xsd_, PriceOracle oracle_ ) public { // Creator of the contract is admin during initialization admin = msg.sender; require(msg.sender == admin, "only admin may initialize the UL"); // Set initial exchange rate ULPercentage = uint256(50); stabilizer = XSDStabilizer(XSDStabilizer_); ... ```
Open the reportThere is no validation to ensure the `lockEndBlocks[i]` is larger than the `_lockingPeriodEndBlock`.
Open the reportThere's no sanity check to validate if a `lockTime` is existing. If the `lockTime` does not exist, the user who locked assets will not get the rewards.
Open the reportThe user has locked their `xLEXE` tokens in the contract `UltimateLoanLock` for at least 3 months, with the expectation of minting `XDS` tokens through the function `supply()` in the contract `UltimateLoan` at the end of the lock period. However, if XDS's market share exceeds a certain threshold after three months, they may be unable to mint additional `XDS` tokens. - Contract `XSDStabilizer.sol` ```solidity=242 require( getHypotheticalLendexeShare(amount) < 0.6e18, "Market share of XSD is too high!" );
Open the reportThe `liquidate()` function calls the `xLEXE.transferFrom()` function with the `to` address specified as `lexeVault` for acquiring the `xLEXE` tokens. As a result, over time the `lexeVault` address will accumulate a significant portion of `xLEXE` tokens. If the `lexeVault` is an EOA (Externally Owned Account), the mishandling of its private key can have devastating consequences for the project as a whole.
Open the reportIn the function `liquidateStabilizerPool`, the `poolShares` is possibly deleted if the length of the array `_poolShares` is 1, and there is no function provided in the contract to reset the `poolShares`. Therefore, the function `liquidateStabilizerPool` will execute fail in the next call. We would like to confirm with the customer whether it is as intended.
Open the report`vt.lockEndBlock` is assigned the same value twice. ```solidity=111 for (uint256 i = 0; i < _lockTimes.length; i++) { uint8 distributionTime = uint8(totalSupply[i] / tokensPerDay); VestingModel storage vt = vestingModels[_lockTimes[i]]; vt.lockEndBlock = lockEndBlocks[i]; vt.totalSupply = totalSupply[i]; vt.lockEndBlock = lockEndBlocks[i]; vt.distributionTime = distributionTime; } ```
Open the reportThe array `supplyTokens` is not reset before new supply tokens are pushed, so it is impossible to update the supply tokens and shares if the function is called again. ```solidity=87 supplyTokens.push( supplyToken({ token: supplyTokens_[i], share: Exp({mantissa: supplyTokenShares_[i]}) }) ); ```
Open the reportThe function `calculateTokenPortions()` in the contract `LockDrop` should be called successfully daily. Otherwise, users who locked assets will potentially lose their rewards. We want to check with the team for more detail about the mechanism that can ensure the function `calculateTokenPortions()` run successfully daily.
Open the reportThe **require** can be used to check for conditions and throw an exception if the condition is not met. It is better to provide a string message containing details about the error that will be passed back to the caller.
Open the report`EIP20NonStandardInterface` and `EIP20Interface` are used in the contract `XSDStabilizer`, but the import is missing.
Open the reportThere is no validation between `_lockTimes.length` , `lockEndBlocks.length` ,`totalSupply.length` and `_xTokenAddresses.length` in constructor. And there is no validation between `amounts.length` and `_xTokenAddresses.length` in function `lockAssets()`.
Open the reportA sandwich attack may happen when an attacker observes a transaction swapping tokens or adding liquidity without setting restrictions on slippage or minimum output amount. The attacker can manipulate the exchange rate by frontrunning (executing before the target) a transaction to purchase one of the assets and make profits by backrunning (executing after the target) a transaction to sell the asset. The following functions are called without setting restrictions on slippage or minimum output amount, so transactions triggering these functions are vulnerable to sandwich attacks, especially when the input amount is large: - `swapRouter.exactInputSingle(ISwapRouter.ExactInputSingleParams()`
Open the reportA sandwich attack might happen when an attacker observes a transaction swapping tokens or adding liquidity without setting restrictions on slippage or minimum output amount. The attacker can manipulate the exchange rate by frontrunning (before the transaction is attacked) a transaction to purchase one of the assets and make profits by backrunning (after the transaction is attacked) a transaction to sell the asset. The following functions are called without setting restrictions on slippage or minimum output amount, so transactions triggering these functions are vulnerable to sandwich attacks, especially when the input amount is large: - `swapRouter.exactInputSingle()` - `swapRouter.exactInput()`
Open the reportIf the supply token status is marked as `BLACKLISTED` or `BANNED`, users are possibly unable to burn the XDS tokens to get the supply tokens.
Open the reportThese expressions in the contracts do not check arithmetic overflow. Such unsafe math operations may cause unexpected behavior if unusual parameters are given.
Open the reportThe transfer amount of `xwbtc`/`supplyToken` from the `XSDStabilizer` contract is not properly calculated, this will transfer all `xwbtc`/`supplyToken` left in the current contract to the recipient. The token balance should be checked before and after the transfer. ```solidity=665 xwbtc.mint(underlyingSupplyTokenBalance); xwbtc.transfer( address(xsdInterface), xwbtc.balanceOf(address(this)) ); ``` ```solidity=682 supplyToken.mint(underlyingSupplyTokenBalance); supplyToken.transfer( address(xsdInterface), supplyToken.balanceOf(address(this)) ); ```
Open the reportThe linked functions invocations do not check the return value of the function call which returns a value in case of a proper call.
Open the reportAs per the fee calculation logic, if the amount is less than 1, all the locked assets amount will be charged as fees. ```solidity=157 uint256 actualAmount = (amount * 99) / 100; uint256 fee = amount - actualAmount; ```
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="lendexe"></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