As of 3 Nov 2026, Parex has 1 audit report on Trustblock, by CertiK, dated 15 Oct 2024. 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 | 0 | 1 | 4 |
| Medium | 0 | 0 | 2 |
| Low | 0 | 3 | 3 |
The ` sendBridgeOwnerReward()` function is used to allow the contract owner to retrieve the `PAREX` token from the contract, but this function will fail. This is because the 197 line of code function is to withdraw the contract's BNB, not `PAREX`. And since the `unlockTokens()` function only mints tokens for the user, without minting `bridgefee` into the contract, the contract doesn't own any `PAREX` tokens, and therefore you couldn't use the transfer function to transfer the contract token, you may use the `_mint` function. ```solidity=192 function sendBridgeOwnerReward() public onlyOwner { require(approvalCount >= requiredApprovals, "Not enough approvals"); require(address(this).balance >= bridgeTotalFee, "Insufficient balance"); if (bridgeTotalFee > 0) { address payable bridgeOwner = payable(owner()); (bool success, ) = bridgeOwner.call{value: bridgeTotalFee}(""); require(success, "Transfer failed"); bridgeTotalFee = 0; } resetApprovals(); } ```
Open the reportThe `lockTokens()` function allows any user to lock their own tokens, internally calling `_burnFrom` to burn the user's tokens. At line 30, the contract checks the allowance of the account, but since line 134 passes `msg.sender`, it results in checking the allowance of the user for themselves. If the user has not authorized themselves, they cannot lock their tokens. ```solidity=128 function lockTokens(uint256 amount, uint256 nonce, uint256 targetChainID) external whenNotPaused { require(!processedNonces[nonce], "Transfer already processed"); require(balanceOf(msg.sender) >= amount, "Insufficient balance to lock tokens"); require(maxAmount >= amount, "Lock amount exceeds maximum allowed"); // Burn tokens from the user's balance using burnFrom _burnFrom(msg.sender,amount); processedNonces[nonce] = true; emit Burned(msg.sender, amount, block.timestamp, nonce, targetChainID); } ``` ```solidity=29 function _burnFrom(address account, uint256 amount) internal virtual { uint256 currentAllowance = allowance(account, msg.sender); require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance"); _burn(account, amount); } ```
Open the reportThe `sendBridgeOwnerReward()` function, which is intended for the contract owner to withdraw native tokens from the contract, will fail. This is because the contract lacks a `payable` function or a `receive` function, preventing it from accepting native tokens. ```solidity=158 function sendBridgeOwnerReward() public onlyOwner { require(address(this).balance >= bridgeTotalFee, "Insufficient balance"); if (bridgeTotalFee > 0) { address payable bridgeOwner = payable(owner()); (bool success, ) = bridgeOwner.call{value: bridgeTotalFee}(""); require(success, "Transfer failed"); bridgeTotalFee = 0; } ```
Open the report`9000000 * 10 ** 18` `PRX` tokens are sent to the contract deployer. This is a centralization risk because the deployer can distribute tokens without obtaining the consensus of the community. Any compromise to these addresses may allow a hacker to steal and sell tokens on the market, resulting in severe damage to the project.
Open the reportThe `unlockTokens()` function allows the owner to unlock tokens for users. However, if the unlock amount is zero, at line 144, the `BridgeFee` token is minted to the current contract without accumulating it in `bridgeTotalFee`. This results in the token being locked in the contract with no way to withdraw it. ```solidity=131 function unlockTokens(address to, uint256 amount, uint256 nonce) external onlyOwner nonReentrant { require(!processedNonces[nonce], "Transfer already processed"); processedNonces[nonce] = true; uint256 amountToMint = amount; if (amount > 0) { require(amount > bridgeFee, "Amount must be greater than bridge fee"); amountToMint -= bridgeFee; // Deduct the bridge fee bridgeTotalFee += bridgeFee; // Accumulate the total fees collected } _mint(to, amountToMint); // Mint tokens to the recipient _mint(address(this), bridgeFee); // Mint tokens for the BridgeFee emit Minted(to, amountToMint+bridgeFee, block.timestamp, nonce); } ```
Open the reportIn the PRX contract, which manages cross-chain tokens, the `lockTokens` function is responsible for burning tokens on the origin chain, and the `unlockTokens` function mints tokens on the target chain while charging a fee. This fee is tracked using the `bridgeTotalFee` variable, but not minted to anyone. The owner is supposed to retrieve the fee by calling `sendBridgeOwnerReward`, but this function fails under certain conditions, preventing the owner from claiming the fees. ```solidity=165 function sendBridgeOwnerReward() public onlyOwner { if (bridgeTotalFee > 0) { address payable bridgeOwner = payable(owner()); require(transfer(bridgeOwner, bridgeTotalFee), "Transfer failed"); bridgeTotalFee = 0; // Reset the total fee counter after transferring } } ```
Open the reportThe `bridgeFee` variables in the contract have no set limits, allowing fees to potentially reach 100%. If this occurs, users would receive no tokens from the contract, resulting in a complete loss of their investment. ```solidity=155 function setBridgeFee(uint256 _fee) public onlyOwner { require(_fee > 0, "Bridge fee must be greater than 0"); bridgeFee = _fee; } ```
Open the reportThe smart contract fails to validate the uniqueness of signer addresses during the set process. This lack of validation could allow for duplicate addresses within the signer array, potentially undermining the integrity of the multi-sig approval mechanism.
Open the reportThe `PRX-BSCToken` contract, designed as a cross-chain token, does not include a public mint function after the initialization mint function was removed during the commit `1128a9b91128741280d9d4ffd07be7d91df6273f`. As a result, tokens can only be minted when transferred from another chain.
Open the reportAddresses are not validated before assignment or external calls, potentially allowing the use of zero addresses and leading to unexpected behavior or vulnerabilities. For example, transferring tokens to a zero address can result in a permanent loss of those tokens. ```solidity=89 _owner = initialOwner; ``` - `initialOwner` is not zero-checked before being used.
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="parex"></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