As of 3 Nov 2026, KonnektVPN has 2 audit reports by 2 security firms on Trustblock; the latest is by Cyberscope, dated 1 May 2024. Those reports list 2 open critical findings. It also holds 1 deployed contract on 1 chain.
Record last updated . It holds audits and findings, contracts and incidents up to Nov 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| KonnektVPN | Security firm: Cyberscope | Date: | Scope: 1 address on Polygon (POS) | 2 open critical findings | Open · cyberscope.io |
| KonnektVPN - Audit | Security firm: CertiK | Date: | Scope: Files named in the report | No open critical findings | Original removed |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 2 | 0 | 0 |
| High | 1 | 0 | 1 |
| Medium | 0 | 0 | 3 |
| Low | 5 | 0 | 11 |
200000000000000000000000000 of the `KPN` tokens are sent to the contract deployer when deploying the contract. This could be a centralization risk as the anonymous deployer can distribute tokens without obtaining the consensus of the community. Any compromise to the deployer account that holds undistributed tokens may allow the attacker to steal and sell tokens on the market, resulting in severe damage to the project.
Open the reportAccording to L32-L60, the decimals of the rewards are 18. The rewards are paid using USDT. But the decimal of the USDT is 6. The inconsistency may lead to the project's loss. ```solidity=32 uint256 public tier1mon6 = 750 * (10**18); uint256 public tier1mon12 = 1800 * (10**18); uint256 public tier1mon24 = 4500 * (10**18); // TIER 2 uint256 public tier2mon6 = 1500 * (10**18); uint256 public tier2mon12 = 3500 * (10**18); uint256 public tier2mon24 = 8000 * (10**18); // TIER 3 uint256 public tier3mon6 = 4200 * (10**18); uint256 public tier3mon12 = 9000 * (10**18); uint256 public tier3mon24 = 21000 * (10**18); // TIER 4 uint256 public tier4mon6 = 8000 * (10**18); uint256 public tier4mon12 = 17000 * (10**18); uint256 public tier4mon24 = 37000 * (10**18); // TIER 5 uint256 public tier5mon6 = 13500 * (10**18); uint256 public tier5mon12 = 28500 * (10**18); uint256 public tier5mon24 = 58500 * (10**18); // TIER 6 uint256 public tier6mon6 = 25000 * (10**18); uint256 public tier6mon12 = 50000 * (10**18); uint256 public tier6mon24 = 112500 * (10**18); ``` ```solidity=209 function _payUSDT(address _target, uint rewardAmount) internal { IERC20(USDT).transfer(_target, rewardAmount); emit RewardsPaid(_target, rewardAmount); } ```
Open the reportThe issue lies within the `claimTokens` function where the `KPNToken` is an `ERC777` token. ```solidity=49 function claimTokens() public{ require(owner == msg.sender, "Claiming ERC20: Only contract owner can call function"); require(whiteList.length > 0, "Claiming ERC20: No addresses on whitelist"); uint256 totalSendAmount = _calculateTotalClaim(); require(KPNToken.balanceOf(address(this)) >= totalSendAmount, "Claiming ERC20: Contract Balance Too Low"); for(uint i = 0; i < whiteList.length; i++){ uint256 sendAmount = whiteList[i].amount; address target = whiteList[i].target; whiteList[i].amount = 0; KPNToken.transfer(target, sendAmount); } emit BulkTokenClaim(totalSendAmount, block.timestamp); } ``` If the user is a malicious contract that either lacks a `tokensReceived()` function or explicitly rejects the saleTokens, this will lead to the entire transaction being reverted. This means that users will be unable to receive the claimed tokens - a situation known as a denial of service (DoS) attack.
Open the reportIf there isn't sufficient USDT available in the `LockTokens`, users are unable to directly reclaim their locked `KPN`. There are two ways of withdrawing `KPN` from the contract: `cancelStake` and `withdrawLocked`. The `cancelStake` is using to withdraw locked token before the `lock` expired. ```solidity=172 function cancelStake() public { require(block.timestamp < lockedBalances[msg.sender].lockTime + lockedBalances[msg.sender].timestamp, "ERC20: Cannot Cancel Completed Stake"); ``` The `withdrawLocked` function is utilized to retrieve locked tokens once the `lock` period has ended. However, should there be insufficient USDT available to cover the rewards, the transaction will fail, preventing users from withdrawing their tokens. Additionally, once the `lock` period is over, users are unable to withdraw their tokens by using the `cancelStake` function. Therefore, the sole option for users wanting to withdraw their tokens, in the event that the contract lacks sufficient USDT, is to place a new stake and then cancel this recent stake. ```solidity=189 function withdrawLocked() public { require(block.timestamp > lockedBalances[msg.sender].lockTime + lockedBalances[msg.sender].timestamp, "ERC20: Time Lock not complete"); require(lockedBalances[msg.sender].amount > 0, "ERC20: No Funds Locked"); uint256 tokenAmount = lockedBalances[msg.sender].amount; // gets local copy of variable to save on gas cost require(KPN.balanceOf(address(this)) >= tokenAmount, "ERC20: Contract Balance Too Low"); LockAmount memory lockStruct = lockedBalances[msg.sender]; totalLockedTokens -= tokenAmount; // deletes the staking struct delete lockedBalances[msg.sender]; // approves and transfers kpn balance from this contract KPN.approve(address(this), tokenAmount); KPN.transferFrom(address(this), msg.sender, tokenAmount); _payUSDT(msg.sender, lockStruct.rewardAmount); emit TokensWithdrawn(msg.sender, block.timestamp); } ```
Open the reportWhen 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
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=83 USDT = rewardsToken; ``` - `rewardsToken` is not zero-checked before being used. --- ```solidity=271 USDT = _usdt; ``` - `_usdt` is not zero-checked before being used. --- ```solidity=17 KPNToken = IERC20(kpnToken); ``` - `KPNToken` is not zero-checked before being used.
Open the reportComparisons that are always true or always false may be incorrect or unnecessary. ```solidity=90 require(amount >= 0, "ERC20: Cannot send 0 tokens"); ```
Open the reportIn contract `LockTokens`, the reward token is the `USDT` token, but it is only initialized with an uncertain address and the actual implementation is unknown. In the function `withdrawLocked()` which the users use to retrieve the reward tokens, the `USDT` token is transferred to the retriever from the current contract. However, we do not find the code that mints or transfers the `USDT` token to the current contract.
Open the reportState variables that never change should be declared as `constant` to save gas. ```solidity=15 uint256 public maxSupply = 8000000000000000000000000000; ``` - `maxSupply` should be declared `constant`. --- ```solidity=16 uint256 public tier1Cutoff = 750000 * (10**18); ``` - `tier1Cutoff` should be declared `constant`. --- ```solidity=17 uint256 public tier2Cutoff = 1250000 * (10**18); ``` - `tier2Cutoff` should be declared `constant`. --- ```solidity=18 uint256 public tier3Cutoff = 3000000 * (10**18); ``` - `tier3Cutoff` should be declared `constant`. --- ```solidity=19 uint256 public tier4Cutoff = 5000000 * (10**18); ``` - `tier4Cutoff` should be declared `constant`. --- ```solidity=20 uint256 public tier5Cutoff = 7500000 * (10**18); ``` - `tier5Cutoff` should be declared `constant`. --- ```solidity=21 uint256 public tier6Cutoff = 12500000 * (10**18); ``` - `tier6Cutoff` should be declared `constant`. --- ```solidity=24 uint256 public locktime1 = 180 days; ``` - `locktime1` should be declared `constant`. --- ```solidity=25 uint256 public locktime2 = 365 days; ``` - `locktime2` should be declared `constant`. --- ```solidity=26 uint256 public locktime3 = 730 days; ``` - `locktime3` should be declared `constant`.
Open the reportIn the `addToWhitelist()` function, if the `claimableTokens[newTarget]` is equal to 0, then `newTarget` will be added to the `whitelistedAddresses`. ```solidity=54 if (claimableTokens[newTarget] == 0) { whitelistedAddresses.push(newTarget); } ``` After a user claims their tokens via the `claimTokens()` function, the `claimableTokens[msg.sender]` will be reset to 0. ```solidity=63 claimableTokens[msg.sender] = 0; // Prevent Reentrancy ``` If the `addToWhitelist` function is invoked and the `newTarget` is the address of a user who has previously called `claimTokens`, then the address will be added to `whitelistedAddresses` once more. This could lead to duplicate entries in `whitelistedAddresses`.
Open the reportLiterals with many digits are difficult to read and review.
Open the reportThe return values of the `transfer()` and `transferFrom()` calls in the smart contract are not checked. Some ERC-20 tokens' transfer functions return no values, while others return a bool value, they should be handled with care. If a function returns `false` instead of reverting upon failure, an unchecked failed transfer could be mistakenly considered successful in the contract. ```solidity=42 KPNToken.transfer(target, sendAmount); ``` --- ```solidity=53 KPNToken.transfer(target, amount); ``` --- ```solidity=79 KPNToken.transfer(addressList[i].target, addressList[i].amount); ``` --- ```solidity=98 KPN.transfer(msg.sender, refund); ``` --- ```solidity=110 KPN.transferFrom(msg.sender, address(this), lockAmount); ``` --- ```solidity=122 KPN.transferFrom(msg.sender, address(this), lockAmount); ``` --- ```solidity=132 KPN.transferFrom(msg.sender, address(this), lockAmount); ``` --- ```solidity=143 KPN.transferFrom(msg.sender, address(this), lockAmount); ``` --- ```solidity=154 KPN.transferFrom(msg.sender, address(this), lockAmount); ``` --- ```solidity=165 KPN.transferFrom(msg.sender, address(this), amount); ``` --- ```solidity=202 KPN.transferFrom(address(this), msg.sender, tokenAmount); ``` --- ```solidity=211 IERC20(USDT).transfer(_target, rewardAmount); ```
Open the reportThe smart contract does not check or store the return value of an external call in a local or state variable, which may introduce vulnerabilities due to the unhandled outcome. ```solidity=201 KPN.approve(address(this), tokenAmount); ```
Open the reportThere is no need to use `approve` and `transferFrom` to transfer tokens from the contract to the `msg.sender`. ```solidity=201 KPN.approve(address(this), tokenAmount); KPN.transferFrom(address(this), msg.sender, tokenAmount); ```
Open the reportThe 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| Address | Chain | Source code |
|---|---|---|
| 0x8328…83e50x8328e6fcec9477c28298c9f02d740dd87a1683e5 | Chain: Polygon (POS) | Source code: Verified source |
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="konnektvpn"></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