DeXe Protocol security record

As of 2 Nov 2026, DeXe Protocol has 3 audit reports by 2 security firms on Trustblock; the latest is by Hacken, dated 19 Jun 2023. Those reports list 2 open critical findings. It also holds 1 deployed contract on 1 chain.

Critical findings
2 open critical findings
Reported in “DeXe / DEX” by Hacken, Jun 2023. Not marked fixed in that report. See the findings
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.

Audits3

Newest first

AuditSecurity firmDateScopeCritical findingsReport
DeXe / DEXSecurity firm: HackenDate: Scope: 1 address on Ethereum2 open critical findingsOpen · hacken.io
DeXe AuditSecurity firm: CertiKDate: Scope: Files named in the reportNo open critical findingsOpen · skynet.certik.com
DeXe / Token salesSecurity firm: HackenDate: Scope: 1 address on EthereumNo open critical findingsOpen · hacken.io

Findings62

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

SeverityOpenAcknowledgedFixed
Critical200
High718
Medium206
Low18018
CriticalFlashloan Attack; Front-Running AttackDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
CriticalUnverified InteractionDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
HighAccess Control Violation; Race ConditionsDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
HighAssets Integrity; Undocumented BehaviorDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
HighDenial of Service VulnerabilityDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
HighDenial of Service VulnerabilityDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
HighRequirements ViolationDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
HighRequirements ViolationDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
HighRequirements Violation; Misleading NamingDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
MediumContradiction - Invalid Return ActionDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
Show 10 more
MediumInconsistent Data - Unused Return ValueDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
LowFloating PragmaDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
LowFunction Which May Be Declared PrivateDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
LowMissing EventsDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
LowMissing Zero Address ValidationDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
LowRedundant ImportDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
LowShadowing State VariablesDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
LowUnindexed EventsDeXe / DEX · Hacken · 19 Jun 2023Open

The report gives no description here.

Open the report
LowIncompatibility with Deflationary TokensDeXe Audit · CertiK · 4 May 2023Open

When 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 ## PriceFeed.sol In contract `PriceFeed`, below are the involved code snippets: ```solidity=96 _grabTokens(inToken, amountIn); ``` - Transferring tokens by `amountIn`. - This function call executes the following operation. ```solidity=98 uint256[] memory outs = uniswapV2Router.swapExactTokensForTokens( amountIn, minAmountOut, foundPath.path, msg.sender, block.timestamp ); ``` - The `amountIn` appears to be used for bookkeeping purposes without compensating the potential transfer fees. ```solidity=141 _grabTokens(inToken, maxAmountIn); ``` - Transferring tokens by `maxAmountIn`. - This function call executes the following operation. ```solidity=151 IERC20(inToken).safeTransfer(msg.sender, maxAmountIn - ins[0]); ``` - The `maxAmountIn` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ## Insurance.sol In contract `Insurance`, below are the involved code snippets: ```solidity=65 _dexe.transferFrom(msg.sender, address(this), deposit); ``` - Transferring tokens by `deposit`. ```solidity=62 userInfos[msg.sender].stake += deposit; ``` - The `deposit` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ## DistributionProposal.sol In contract `DistributionProposal`, below are the involved code snippets: ```solidity=75 rewardToken.safeTransferFrom(govAddress, address(this), reward - balance); ``` - Transferring tokens by `reward-balance`. - The `reward-balance` appears to be used for bookkeeping purposes without compensating the potential transfer fees. --- ## TraderPoolProposal.sol In contract `TraderPoolProposal`, below are the involved code snippets: ```solidity=123 IERC20(_parentTraderPoolInfo.baseToken).safeTransferFrom( _parentTraderPoolInfo.parentPoolAddress, address(this), baseInvestment.from18(_parentTraderPoolInfo.baseTokenDecimals) ); ``` - Transferring tokens by `baseInvestment.from18(_parentTraderPoolInfo.baseTokenDecimals)`. - The `baseInvestment` appears to be used for bookkeeping purposes without compensating the potential transfer fees.

Open the report
LowLogic Issue of Sending Rewards in `GovPoolStakingDeXe Audit · CertiK · 4 May 2023Open

According to the design of the `GovPoolStaking` contract, the `unstake()` function will calculate users' rewards from delegatees' micro pools. When sending rewards, the contract sends the minimum between the contract's token balance and the user's entitled rewards. In both cases, the delegator's reward is completely cleared. ```solidity=126 delegatorInfo.pendingRewards = 0; rewardToken.sendFunds(msg.sender, rewards.min(rewardToken.normThisBalance())); ``` A more reasonable approach would be to reduce `delegatorInfo.pendingRewards` by `rewards.min(rewardToken.normThisBalance())`, enabling users to receive the remainder of their reward at a later time once the contract has accrued more rewards.

Open the report
Show 9 more
LowMissing Emit EventsDeXe Audit · CertiK · 4 May 2023Open

Functions that update state variables should emit relevant events as notifications.

Open the report
LowMissing Input ValidationDeXe Audit · CertiK · 4 May 2023Open

## CoreProperties.sol According to the whitepaper, the listed functions in `CoreProperties` and the corresponding variables should fall within specific ranges, and it is recommended to perform validation checks to ensure their correctness: - `setMaximumPoolInvestors()` - `setMaximumOpenPositions()` - `setTraderLeverageParams()` - `setCommissionInitTimestamp()` - `setCommissionDurations()` - `setDEXECommissionPercentages()` - `setTraderCommissionPercentages()` - `setDelayForRiskyPool()` - `setInsuranceParameters()` - `setGovVotesLimit()` --- ## ERC721Multiplier.sol In contract `ERC721Multiplier`, the function `mint()` is missing an input validation for `multiplier`. The field `multiplier` of `NftInfo` will be used to calculate the reward in L67: ```solidity=67 ? rewards.ratio(_tokens[latestLockedTokenId].multiplier, PRECISION) ``` The aforementioned code snippet implements the following calculation: $\text{rewards} \times \frac{\text{\_tokens[latestLockedTokenId].multiplier}}{\text{PRECISION}}$. It is unclear if `multiplier` should be less than `PRECISION`. If `multiplier` is greater than `PRECISION`, the function `getExtraRewards()` will return a greater value than `rewards`.

Open the report
LowNew Contract Instance Created in Upgradeable ContDeXe Audit · CertiK · 4 May 2023Open

When creating a new instance of a contract from upgradeable contract’s code, these creations are handled directly by Solidity and not by OpenZeppelin Upgrades, which means that these contracts will not be upgradeable.

Open the report
LowPotential Inconsistency between `deployerBABTid`DeXe Audit · CertiK · 4 May 2023Open

The state variable `deployerBABTid` is set by the contract initializer and cannot be modified after the contract is deployed. According to the contract `PoolFactory`, `babtId` is defined as follows: ```solidity=277 if (_babt.balanceOf(msg.sender) > 0) { babtId = _babt.tokenIdOf(msg.sender); } ``` However, the state variable `babt` is set in function `setDependencies()` and can be modified more than once. There may exist inconsistency between `deployerBABTid` and `babt` when invoking the function `setDependencies()` multiple times, that is, the `deployerBABTid` may be for a different address if `babt` changes.

Open the report
LowPotential Inconsistency between `totalPowerInTokeDeXe Audit · CertiK · 4 May 2023Open

According to the design of the `GovUserKeeper` contract, the `_setERC721Address()` function is utilized to initialize the information of NFT contract and store it in `_nftInfo`. There is no relationship between the values of `_nftInfo.totalPowerInTokens` and `_nftInfo.totalSupply`. ```solidity=650 require(totalPowerInTokens > 0, "GovUK: the equivalent is zero"); _nftInfo.totalPowerInTokens = totalPowerInTokens; if (!IERC165(_nftAddress).supportsInterface(type(IERC721Power).interfaceId)) { if (!IERC165(_nftAddress).supportsInterface(type(IERC721Enumerable).interfaceId)) { require(nftsTotalSupply > 0, "GovUK: total supply is zero"); _nftInfo.totalSupply = uint128(nftsTotalSupply); } } else ``` In the `nftVotingPower()` function of the `GovUserKeeperView` contract, if the NFT contract does not support power (`nftInfo.isSupport = true`), the nftPower is calculated by $\frac{\text{\_nftInfo.totalPowerInTokens}}{\text{\_nftContract.totalSupply()}}$ or $\frac{\text{\_nftInfo.totalPowerInTokens}}{\text{\_nftInfo.totalSupply}}$. However, if `_nftInfo.totalPowerInTokens` is less than `nftContract.totalSupply()` or `_nftInfo.totalSupply`, the `nftPower` will be zero for each `nftId`, which is inconsistent with the fact that `totalPowerInTokens` is positive. ```solidity=72 if (!nftInfo.isSupportPower) { uint256 totalSupply = nftInfo.totalSupply == 0 ? nftContract.totalSupply() : nftInfo.totalSupply; if (totalSupply > 0) { uint256 totalPower = nftInfo.totalPowerInTokens; if (calculatePowerArray) { for (uint256 i; i < nftIds.length; i++) { perNftPower[i] = totalPower / totalSupply; } } nftPower = nftIds.length.ratio(totalPower, totalSupply); } ```

Open the report
LowPotential Price Manipulation RiskDeXe Audit · CertiK · 4 May 2023Open

The DeXe network only considers the Uniswap V2 pool as the protocol's price feed. Attackers with enough funds or using flashloan operations could temporarily manipulate the price of the underlying assets.

Open the report
LowPotential Reentrancy AttackDeXe Audit · CertiK · 4 May 2023Open

A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. If the attacker can control the untrusted contract, they can make a recursive call back to the original function, repeating interactions that would have otherwise not run after the external call resolved the effects. ## TraderPoolInvestProposal.sol ### External call(s) ```solidity=87 _transferAndMintLP(proposalId, trader, lpInvestment, baseInvestment); ``` * This function call executes the following external call(s). * In `ERC1155._doSafeTransferAcceptanceCheck`, * `IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data)` ### State variables written after the call(s) ```solidity=89 _proposalInfos[proposalId].descriptionURL = descriptionURL; _proposalInfos[proposalId].lpLocked = lpInvestment; _proposalInfos[proposalId].investedBase = baseInvestment; _proposalInfos[proposalId].newInvestedBase = baseInvestment; ``` --- ### External call(s) ```solidity=117 _transferAndMintLP(proposalId, trader, lpInvestment, baseInvestment); ``` * This function call executes the following external call(s). * In `ERC1155._doSafeTransferAcceptanceCheck`, * `IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data)` ### State variables written after the call(s) ```solidity=119 _proposalInfos[proposalId].descriptionURL = descriptionURL; _proposalInfos[proposalId].lpLocked = lpInvestment; _proposalInfos[proposalId].investedBase = baseInvestment; _proposalInfos[proposalId].newInvestedBase = baseInvestment; ``` --- ## ERC721Power.sol ### External call(s) ```solidity=93 _safeMint(to, tokenId, ""); ``` * This function call executes the following external call(s). * In `ERC721._checkOnERC721Received`, * `(retval) = IERC721Receiver(to).onERC721Received(_msgSender(),from,tokenId,data)` ### State variables written after the call(s) ```solidity=95 totalPower += getMaxPowerForNft(tokenId); ``` --- ## TokenSaleProposal.sol ### External call(s) ```solidity=103 ERC20(tierView.saleTokenAddress).safeTransfer( msg.sender, saleTokenAmount.percentage(PERCENTAGE_100 - tierView.vestingSettings.vestingPercentage) ); ``` ### State variables written after the call(s) ```solidity=108 tierInfo.tierInfoView.totalSold += saleTokenAmount; ``` ```solidity=110 tierInfo.customers[msg.sender] = Purchase({ purchaseTime: uint64(block.timestamp), vestingTotalAmount: saleTokenAmount.percentage( tierView.vestingSettings.vestingPercentage ), vestingWithdrawnAmount: 0, latestVestingWithdraw: 0 }); ``` --- ## GovPoolUnlock.sol ### External call(s) ```solidity=45 maxUnlocked = IGovUserKeeper(userKeeper) .unlockTokens(proposalId, user, isMicropool) .max(maxUnlocked); ``` ```solidity=48 IGovUserKeeper(userKeeper).unlockNfts( voteInfos[proposalId][user][isMicropool].nftsVoted.values() ); ``` ### State variables written after the call(s) ```solidity=52 userProposals.remove(proposalId); ``` * This function call executes the following assignment(s). * In `EnumerableSet.remove`, * `_remove(set._inner,bytes32(value))` * In `EnumerableSet._remove`, * `set._values[toDeleteIndex] = lastValue` * In `EnumerableSet._remove`, * `set._indexes[lastValue] = valueIndex` * In `EnumerableSet._remove`, * `set._values.pop()` * In `EnumerableSet._remove`, * `delete set._indexes[value]`

Open the report
LowThe insurance `payout` can be less than `userInfoDeXe Audit · CertiK · 4 May 2023Open

The linked function `_payout()` calculates the total insurance payout for the `user`. If `insurancePayout / _coreProperties.getInsuranceFactor() > userInfo.stake`, we have `stakePayout = userInfo.stake` and `payout = stakePayout + insurancePayout > userInfo.stake`. But `payout` may be less than `userInfo.stake` if `insurancePayout / _coreProperties.getInsuranceFactor() < userInfo.stake`. If the insurance premium is to be paid only once, it is not rational for a user to buy insurance if the payout will be less than the premium.

Open the report
LowVariables That Could Be Declared as ImmutableDeXe Audit · CertiK · 4 May 2023Open

The linked variables assigned in the constructor can be declared as `immutable`. Immutable state variables can be assigned during contract creation but will remain constant throughout the lifetime of a deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper than reading from regular state variables since they will not be stored in storage.

Open the report

Contracts1

All 1 address and the 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="dexe-protocol"
></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