CertiK $SAFEMOON
CertiK audit report on $Safemoon
Due to the CertiK audit of $Safemoon we have to change our $MNRY token contract.
Certik Audit: https://www.certik.org/projects/safemoon
$MNRT contract: https://github.com/moonery-io/moonery-contracts/blob/main/contracts/Moonery.sol
Findings
ID | Category | Severity | Location | Changes |
SSL-01 Incorrect error message | Logical Issue | Moonery.sol:109 | The message "Account is already excluded" is changed to "Account is not excluded" . | |
SSL-01 Incorrect error message | Logical Issue | Moonery.sol:118 | The message "Account is already excluded" is changed to "Account is not excluded" . | |
SSL-02 Redundant code | Logical Issue | Moonery.sol: 452 | Code has been removed | |
SSL-03 | Logical Issue | - | - | BNB in $MNRY contract automatically distribute to our holders by claimBNBReward function |
SSL-04 Centralized risk in addLiquidity | Centralization / Privilege | Moonery.sol:601 | owner() changed to address(this) | |
SSL-05 Variable could be declared as constant | Gas Optimization | Moonery.sol:35 | changed to: uint256 private constant _tTotal = 1000000000 10 ** 6 10 ** 9; | |
SSL-05 Variable could be declared as constant | Gas Optimization | Moonery.sol:39 | changed to: string private constant _name = "Moonery"; | |
SSL-05 Variable could be declared as constant | Gas Optimization | Moonery.sol:40 | change to: string private constant _symbol = "MNRY"; | |
SSL-05 Variable could be declared as constant | Gas Optimization | Moonery.sol:41 | change to: uint8 private immutable _decimals = 9; | |
SSL-06 Return value not handled | Volatile Code | MooneryUtils.sol:105 | Handle return value from Pancakeswap. public returns (uint amountToken, uint amountETH, uint liquidity) | |
SSL-07 rd party dependencies | Contr ol Flow | - | Changes on 3rd party library means changes on $MNRY contract, we are aware of this. | |
SSL-08 Missing event emitting | Coding Style | |||
SSL-09 Function and variable naming doesn't match the operating environment | Coding Style | MooneryUtils.sol:54 | Function changed to swapTokensForBnb | |
SSL-09 Function and variable naming doesn't match the operating environment | Coding Style | MooneryUtils.sol:75 | Function change to swapBNBForTokens | |
SSL-09 Function and variable naming doesn't match the operating environment | Coding Style | several locations | ethAmount changed to bnbAmount | |
SSL-09 Function and variable naming doesn't match the operating environment | Coding Style | several locations | etheReceived change to bnbReceived | |
SSL-10 Privileged ownership | Centralization / Privilege | see chapter SSL-10 | ||
SSL-11 Typos in the contract | Coding Style | Moonery.sol:57 | changed to tokensIntoLiquidity | |
SSL-11 Typos in the contract | Coding Style | |||
SSL-12 The purpose of function deliver | Control Flow | Moonery.sol:227 | require(!_isExcluded[sender], "Excluded addresses cannot call this function"); | |
SSL- | Possible to gain ownership after renouncing the contract ownership | Logical Issue, Centralization / Privilege | Ownable | see chapter SSL--- | |
SSL-10 Privileged ownership
Description
The owner of contract Safemoon and $MNRY has the permission to:
change the address that can receive LP tokens
lock the contract
exclude/include addresses from rewards/fees
set taxFee, liquidityFee and _maxTxAmount
enable swapAndLiquifyEnabled
without obtaining the consensus of the community
Recommendation
Renounce ownership when it is the right timing, or gradually migrate to a timelock plus multisig governing procedure and let the community monitor in respect of transparency considerations.
Alleviation
Use OpenZeppelin Ownable, removing _previousowner. We also transparant about above functions activities, see also Token & Liquidity Locks
SSL- | Possible to gain ownership after renouncing the contract ownership
Description
An owner is possible to gain ownership of the contract even if he calls function renounceOwnership torenounce the ownership. This can be achieved by performing the following operations:.
1. Call lock to lock the contract. The variable _previousOwner is set to the current owner.
2. Call unlock to unlock the contract.
3. Call renounceOwnership to leave the contract without an owner.
4. Call unlock to regain ownership.
Recommendation
We advise updating/removing lock and unlock functions in the contract; or removing the renounce Ownership if such a privilege retains at the protocol level. If timelock functionality could be introduced, we recommend using the implementation of Compound finance as reference. Reference:https://github.com/compound-finance/compound-protocol/blob/master/contracts/Timelock.sol
Removed implementation of Ownable.sol from $Safemoon and use import "@openzeppelin/contracts/access/Ownable.sol" instead. We can't introduce Timelock.sol due the max size of the contract.
Stuck ERC20 tokens inside $MNRY contracts
Description
see also: https://docs.google.com/document/d/1Feh5sP6oQL1-1NHi-X1dbgT3ch2WdhbXRevDN681Jv4/
If a user will make a mistake and choose a wrong function then the token will get stuck inside our contract (contract will not recognize a transaction). There will be no way to extract stuck tokens.
Solution
We have add fallbackRedeem new IERC20 token, with the ability to recover ERC20 tokens stuck in the contract. The function doesn't have the ability to recover $MNRY and Liquidity tokens $CAKE LP. We only send stick ERC20 token to our lottery contract and add this token as rewards for the community. newToken.safeTransfer(address(_lottery), tokenAmount);
Max contract Size
Description
Due the above changes the Moonery contract exceed the size limit for testnet and mainnet deployment.
Solutions
Shorten error message
Error | Meaning |
FB1 | fallbackRedeem: cannot recover to $MNRY |
FB2 | fallbackRedeem: cannot recover to $CAKE LP |
AC1 | Moonery: Account is not excluded |
AC2 | Excluded addresses cannot call this function |
BEP1 | BEP20: transfer amount exceeds allowance |
BEP2 | BEP20: decreased allowance below zero |
BEP3 | BEP20: approve from the zero address |
BEP4 | BEP20: approve to the zero address |
BEP5 | BEP20: transfer from the zero address |
BEP6 | BEP20: transfer to the zero address |
BEP7 | BEP20: transfer to the zero address |
RFT1 | Moonery: reflectionFromToken Amount must be less than supply |
TFR1 | Moonery: tokenFromReflection Amount must be less than total reflections |
Last updated