IceCreamSwap

CertiKFiles named in the report

CertiK reviewed IceCreamSwap on 6 Jul 2023: 6 findings, 0 critical; 3 marked fixed, 1 acknowledged, 2 open.

No open critical findings
Open the reportOpen IceCreamSwap’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings6

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

SeverityOpenAcknowledgedFixed
Critical000
High000
Medium013
Low200
MediumIncompatibility with Deflationary TokensFixed

When transferring deflationary ERC20 tokens, the input amount is not be equivalent 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. A failure to account for such fees will allow the same user to withdraw 100 tokens from the contract, which causes the contract to lose 10 tokens in such a transaction. ```solidity=314 lpToken[_pid].safeTransferFrom(msg.sender, address(this), _amount); ``` - Transferring tokens by `_amount`. ```solidity=316 user.amount = user.amount.add(_amount); ``` - This function call executes the following operation. - In `SafeMath.add`, - `uint256 c = a + b;` - The `_amount` appears to be used for bookkeeping purposes without compensating the potential transfer fees.

MediumPotential Reentrancy AttackFixed

A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. If the attacker can control the untrusted contract, they can make a recursive call back to the original function, repeating interactions that would have otherwise not run after the external call resolved the effects. ### External call(s) ```solidity=309 // FALSE POSITIVE settlePendingIce(msg.sender, _pid, multiplier); ``` * This function call executes the following external call(s). * In `SafeERC20._callOptionalReturn`, * `returndata = address(token).functionCall(data,"SafeERC20: low-level call failed")` * In `IceCreamFarm._safeTransfer`, * `ICE.safeTransferFrom(iceTreasury,_to,_amount)` * In `Address.functionCallWithValue`, * `(success,returndata) = target.call{value: value}(data)` ```solidity=314 // FALSE POSITIVE lpToken[_pid].safeTransferFrom(msg.sender, address(this), _amount); ``` ### State variables written after the call(s) ```solidity=325 poolInfo[_pid] = pool; ``` ```solidity=316 user.amount = user.amount.add(_amount); ``` ```solidity=322 user.rewardDebt = user.amount.mul(multiplier).div(BOOST_PRECISION).mul(pool.accIcePerShare).div( ACC_ICE_PRECISION ); ``` ### Cross-function reentrancy into these function(s) ```solidity=157 function poolLength() public view returns (uint256 pools) { ``` ```solidity=168 function add( ``` ```solidity=203 function set( ``` ```solidity=247 function massUpdatePools() public { ``` ```solidity=275 function updatePool(uint256 _pid) public returns (PoolInfo memory pool) { ``` ```solidity=491 function getBoostMultiplier(address _user, uint256 _pid) public view returns (uint256) { ``` ### External call(s) ```solidity=341 settlePendingIce(msg.sender, _pid, multiplier); ``` * This function call executes the following external call(s). * In `SafeERC20._callOptionalReturn`, * `returndata = address(token).functionCall(data,"SafeERC20: low-level call failed")` * In `IceCreamFarm._safeTransfer`, * `ICE.safeTransferFrom(iceTreasury,_to,_amount)` * In `Address.functionCallWithValue`, * `(success,returndata) = target.call{value: value}(data)` ### State variables written after the call(s) ```solidity=344 user.amount = user.amount.sub(_amount); ``` ### Cross-function reentrancy into these function(s) ```solidity=491 function getBoostMultiplier(address _user, uint256 _pid) public view returns (uint256) { ``` --- ### External call(s) ```solidity=341 settlePendingIce(msg.sender, _pid, multiplier); ``` * This function call executes the following external call(s). * In `SafeERC20._callOptionalReturn`, * `returndata = address(token).functionCall(data,"SafeERC20: low-level call failed")` * In `IceCreamFarm._safeTransfer`, * `ICE.safeTransferFrom(iceTreasury,_to,_amount)` * In `Address.functionCallWithValue`, * `(success,returndata) = target.call{value: value}(data)` ```solidity=345 lpToken[_pid].safeTransfer(msg.sender, _amount); ``` ### State variables written after the call(s) ```solidity=351 poolInfo[_pid].totalBoostedShare = poolInfo[_pid].totalBoostedShare.sub( _amount.mul(multiplier).div(BOOST_PRECISION) ); ``` ```solidity=348 user.rewardDebt = user.amount.mul(multiplier).div(BOOST_PRECISION).mul(pool.accIcePerShare).div( ACC_ICE_PRECISION ); ``` ### Cross-function reentrancy into these function(s) ```solidity=157 function poolLength() public view returns (uint256 pools) { ``` ```solidity=168 function add( ``` ```solidity=203 function set( ``` ```solidity=247 function massUpdatePools() public { ``` ```solidity=275 function updatePool(uint256 _pid) public returns (PoolInfo memory pool) { ``` ```solidity=491 function getBoostMultiplier(address _user, uint256 _pid) public view returns (uint256) { ``` ### External call(s) ```solidity=386 _safeTransfer(burnAdmin, pendingIceToBurn); ``` * This function call executes the following external call(s). * In `SafeERC20._callOptionalReturn`, * `returndata = address(token).functionCall(data,"SafeERC20: low-level call failed")` * In `IceCreamFarm._safeTransfer`, * `ICE.safeTransferFrom(iceTreasury,_to,_amount)` * In `Address.functionCallWithValue`, * `(success,returndata) = target.call{value: value}(data)` ### State variables written after the call(s) ```solidity=387 lastBurnedBlock = block.number; ``` --- ### External call(s) ```solidity=413 burnIce(false); ``` * This function call executes the following external call(s). * In `SafeERC20._callOptionalReturn`, * `returndata = address(token).functionCall(data,"SafeERC20: low-level call failed")` * In `IceCreamFarm._safeTransfer`, * `ICE.safeTransferFrom(iceTreasury,_to,_amount)` * In `Address.functionCallWithValue`,

MediumStaked Token and Reward Token Must Not be IdenticFixed

In the `deployPool()` function of the SmartChefFactory contract, there is a logic flaw where the `_stakedToken` and `_rewardToken` can be identical. This means that a user could stake the same token that is also used as a reward. This will lead to a loss of funds for the contract as the accumulated rewards are calculated with respect to the `_stakedToken` balance.

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (7)

  • projects/staking/contracts/SmartChefFactory.sol
  • projects/dex/contracts/PancakeRouter.sol
  • projects/dex/contracts/PancakePair.sol
  • projects/dex/contracts/PancakeFactory.sol
  • projects/liquidity-farms/contracts/MasterChefV2.sol
  • projects/staking/contracts/SmartChefInitializable.sol
  • projects/dex/contracts/PancakeERC20.sol

Part of IceCreamSwap’s security record

IceCreamSwap
Audits9 audits by 2 firmsLast audit Jul 2023, by CertiK.
Critical findingsNo open critical findingsAcross 9 reports.
Open IceCreamSwap’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