CertiK reviewed Rangers Protocol (Rangersprotocol-CrossContract) on 18 Dec 2024: 16 findings, 0 critical; 7 marked fixed, 5 acknowledged, 4 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 | 0 | 3 | 1 |
| Medium | 0 | 2 | 2 |
| Low | 4 | 0 | 4 |
The logic ensures the cross-chain transaction atomicity is not implemented in the contract. The cross-chain functions emit messages to 3rd party application. The scope of the audit treats the 3rd party application entities as black boxes and assumes their functional correctness. However, in the real world, 3rd parties can be compromised, which may lead to lost or stolen assets. Suppose the cross-chain transaction atomicity is not guaranteed properly. In that case, the user deposits tokens into the source chain, but not be able to redeem the correct token amount from the target chain.
The `IsInPoolfts` function checks whether a token contract address (addr) exists in the `g_pool_fts` array, which acts as a pool or whitelist of token addresses. However, the contract exhibits problematic behavior when `_fromcontract` is not in `g_pool_fts`. Specifically: ### Minting of Non-Whitelisted Tokens: When `_fromcontract` is not in `g_pool_fts`, the contract can still call `IERC20(_fromcontract).mint(address(this), am)`. This is counterintuitive to the purpose of a whitelist, which is typically used to control and limit the minting or interaction to approved token contracts. Allowing minting of tokens outside the whitelist undermines the trustworthiness and control of the contract over its operations. ### No Explicit Minting Whitelist: The `IsInPoolfts` function seems to check for inclusion in the pool (g_pool_fts), but its logic does not explicitly enforce a prohibition against minting non-whitelisted tokens. This ambiguity makes it difficult for users and auditors to determine which tokens the contract is allowed to mint, leading to potential exploitation. ```solidity function IsInPoolfts(address addr) private view returns(bool) { for(uint256 i = 0; i < g_pool_fts.length; i++) { if(g_pool_fts[i] == addr){ return true; } } return false; } function AddPoolFts(address[] memory addr) external{ require(msg.sender == g_Setter ,'p1'); for(uint256 i=0;i<addr.length; i++){ if(IsInPoolfts(addr[i]) == false){ g_pool_fts.push(addr[i]); } } } ... if(IsInPoolfts(_fromcontract) == false){ IERC20(_fromcontract).mint(address(this),am); } ```
The specified input parameters lack validation. Specifically, a check should be implemented to confirm whether `groupid` already exists in `g_CheckAddrs`.
The function `DoCrossErc20_CM()` charges user's ERC20 tokens and send message to bridge. When the conditions are not met, the native fee tokens will not be sent back to the user, as the transaction will still succeed due to the `return` statement. ```solidity g_FeeAddr.transfer(msg.value); ... if(IERC20(_fromcontract).balanceOf(_fromaddr) >= amount && IERC20(_fromcontract).allowance(_fromaddr,address(this)) >= amount) { ... } emit event_CrossErc20_Failed_CM(msg.value,_fromcontract,_tocontract,_toChainId,_fromaddr,_toaddr,am); return; ``` The function `DoCrossErc20_CM2()` shares the same issue.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (1)
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