CertiK reviewed Kromatika Finance on 26 Feb 2024: 24 findings, 0 critical; 18 marked fixed, 6 open.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 2 | 0 | 1 |
| Medium | 0 | 0 | 2 |
| Low | 4 | 0 | 15 |
In the contract `MetaSwapRouter` the role `controller` has authority over the functions shown in the list below. * addAdapter() - Add a new adapter. * updateAdpater() - Replace any adapter. * createFlashWallet() - Create a new flash wallet. * changeController() - Change the controller. * toggleForwarder() - Toggle the trust status of a forwarder address. * pause() - Pause the contract. * unpause() - Unpause the contract. * rescueFunds() - Withdraw a certain amount of specified token from the contract. * destroy() - Destruct the contract to move all the funds to caller. Any compromise to the `controller` account may allow the hackers to take advantage of this authority and gain unauthorized control over critical functions, allowing them to set malicious adapters, create exploitative flash wallets, change the controller address to maintain control, toggle trust status for forwarders, pause and unpause the contract at will, withdraw funds from the contract, and even destruct the contract, resulting in potential financial losses. --- In the contract `GaslessForwarder` the role `controller` has authority over the functions shown in the list below. * toggleForwarder() - Toggle the trust status of a forwarder address. * changeController() - Change the controller. * toggleValidator() - Toggle the trust status of a validator address. Any compromise to the `controller` account may allow the hacker to take advantage of this authority and set malicious accounts as forwarder or validators and change the controller address. --- In the contract `FlashWallet` the role `owner` has authority over the functions shown in the list below. * executeDelegateCall() - The owner can execute a delegatecall over the target address. Any compromise to the `owner` account may allow the hacker to take advantage of this authority and call the `delegatecall` over malicious target contract to gain funds. The `owner` is intended to be set to the `MetaSwapRouter` contract according to the `createFlashWallet` function.
The `MetaSwapRouter` contract has a potential centralization issue that could result in the theft of users' tokens. The vulnerability lies in the approval process for token allowances. In the contract, users are required to approve token allowances to the `MetaSwapRouter` contract before performing a swap. However, if the owner account of the `MetaSwapRouter` contract is compromised, an attacker could exploit this situation. The attacker could first add a malicious forwarder address to the `trustedForwarders` mapping, pretending to be a legitimate forwarder. By doing so, the attacker can submit the transactions for the victim's sender address which has approved sufficient allowance to the `MetaSwapRouter` contract. Once the attacker has the victim's sender address, they can add a malicious adapter on behalf of themselves using the `addAdapter()` function. This malicious adapter would have the ability to withdraw all the tokens that were approved for swapping. As a result, the attacker can execute a swap on behalf of the victim, but instead of performing the intended swap, they would transfer all the tokens to their own address using the newly added malicious adapter. This centralization issue poses a significant risk to users' funds as it allows the owner of the `MetaSwapRouter` contract to potentially steal tokens from users who have approved allowances. To mitigate this issue, it is crucial to ensure the security of the owner account of the `MetaSwapRouter` contract. Additionally, users should exercise caution when approving token allowances and verify the legitimacy of the contracts they interact with.
External calls are made inside a `for` loop. This might lead to a denial-of-service attack. If any of the calls fail, it will cause the entire loop to revert. ```solidity=40 (bool success, bytes memory ret) = target.call{gas: gasLimit}(abi.encodePacked(callData,msg.sender)); ``` --- ```solidity=14 (bool success, bytes memory result) = address(this).delegatecall(data[i]); ```
When a loop allows an arbitrary number of iterations or accesses state variables in its body, the function may run out of gas and revert the transaction. ```solidity=36 for (uint256 i = 0; i < calls.length; i++) { ``` Function `GaslessInterfaceMulticall.multicall` contains a loop and its loop condition depends on parameters: `calls`. --- ```solidity=13 for (uint256 i = 0; i < data.length; i++) { ``` Function `MetaSwapRouter.multicall` contains a loop and its loop condition depends on parameters: `data`.
Solidity frequently releases new compiler versions with improved security features and bug fixes. Using an outdated version prevents access to these enhancements and may leave the smart contract vulnerable to known issues. ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=2 pragma solidity =0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ``` --- ```solidity=2 pragma solidity 0.7.6; ``` --- ```solidity=2 pragma solidity 0.7.6; ``` --- ```solidity=3 pragma solidity 0.7.6; ```
There are some questions related to Gasless swap: ## Calculation of `paymentFees` and `tokenGasPrice` In gasless mode, users are exempted from paying network gas fees and instead, they only need to cover the payment fees deducted from one of the swapping tokens. It is essential to ensure that the paymentFees amount is not less than the value of gas consumption. If this requirement is not met, the entire transaction will be reverted. ```solidity // check payment fees validity require(request.tokenGasPrice.mul(initialGas.sub(gasleft())) <= request.paymentFees, 'GF_OC'); ``` Typically, the calculation of `tokenGasPrice` and `paymentFees` relies on an external oracle or a price feed that provides the exchange rate between the swapping tokens and the gas token (e.g., ETH). The oracle serves the purpose of supplying the latest pricing information, enabling the determination of the appropriate payment fees denominated in the swapping tokens. The auditing team is interested in understanding the specific calculation process for `tokenGasPrice` and `paymentFees`. ## Gas protection mechanism Regarding the scenario where a transaction reverts, users do not suffer any loss, but the relayer incurs gas expenses. Malicious users could exploit this situation by repeatedly initiating transactions that revert, causing the relayer to experience increased gas losses. To address this concern, it is important to implement protection mechanisms that prevent such abuse. The auditing team would like to know if any protective measures are in place to mitigate this issue. ## Sending native token in `GaslessForwarder` The `executeCall()` function in `GaslessForwarder` contract should be called by Biconomy forwarder according to white paper. ```solidity (bool success, bytes memory result) = request.targetAddress.call{ value: msg.value }( abi.encodePacked(request.data, sender) ); ``` However, in the implementation of Biconomy contract, there is no ether sending during the low-level call. So the native token like `ETH` should be wrapped to contract token. ```solidity function executePersonalSign( ERC20ForwardRequest calldata req, bytes calldata sig ) external returns (bool success, bytes memory ret) { _verifySigPersonalSign(req, sig); _updateNonce(req); (success, ret) = req.to.call{gas: req.txGas}( abi.encodePacked(req.data, req.from) ); ``` The auditing team would like to know the purpose of sending native token in `GaslessForwarder`. Is it used to support more other forwarder protocols?
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (12)
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething 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