Berry Farms

Smart contracts security assessment
final report August 2021
Tariff: Standard
Introduction
The report has been prepared for Berry Farms.
Contracts checked
Procedure
We perform our audit according to the following procedure:
Automated analysis
  • Scanning the project's smart contracts with several publicly available automated Solidity analysis tools
  • Manual verification (reject or confirm) all the issues found by the tools

Manual audit
  • Manually analyze smart contracts for security vulnerabilities
  • Smart contracts' logic check
Privileged roles
PavlovaToken
— mint tokens. The ownership of the token was transferred to the MasterChef contract. Only the MasterChef can mint tokens.

MasterChef
— The update emission rate of the token
— Update start block
— Add pool
— Set pool parameters
— Set dev and fee address
Known vulnerabilities checked
Title
Check result (passed/not passed)
Unencrypted Private Data On-Chain
Code With No Effects
Message call with hardcoded gas amount
Typographical Error
DoS With Block Gas Limit
Presence of unused variables
Incorrect Inheritance Order
Requirement Violation
Weak Sources of Randomness from Chain Attributes
Shadowing State Variables
Incorrect Constructor Name
Block values as a proxy for time
Authorization through tx.origin
DoS with Failed Call
Delegatecall to Untrusted Callee
Use of Deprecated Solidity Functions
Assert Violation
State Variable Default Visibility
Reentrancy
Unprotected SELFDESTRUCT Instruction
Unprotected Ether Withdrawal
Unchecked Call Return Value
Floating Pragma
Outdated Compiler Version
Integer Overflow and Underflow
Function Default Visibility
Classification of issues
High severity
Bugs leading to assets theft, locking or any other loss of assets or leading to contract malfunctioning.

Medium severity
Bugs that can trigger a contract failure of malfunctioning.

Low severity
Bugs that do now affect contract functionality. For example, unoptimized gas usage, outdated or unused code, code style violations, etc.

Issues
High severity issues 
1. Broken governance mechanism (PavlovaToken)
The votes in the governance mechanism of the PavlovaToken can be double spended (see sushi votes attack).
Medium severity issues
  1. massUpdatePools() and updateEmissionRate() may run out of block gas limit
Functions massUpdatePools() and updateEmissionRate() may run out of block gas limit if a big number of pools is added as they iterate over an unlimited number of pools.
2. Emission rate not limited
The owner of the MasterChef can set an arbitrary big value for emission rate. The emission rate must be capped.
Recommendation:
cap the emission rate.
3. Hidden pool owner’s attack
The owner of MasterChef can create a pool with zero allocation and then by setting allocation to a big value may mint significant number of tokens (see Dracula protocol article).
Recommendation:
call massUpdatePools() function in the add() and set() before changing.
Low severity issues
  1. Outdated compiler version
Outdated compiler version is used (v0.6.12+commit.27d51765). We recommend using the latest stable version of the Solidity compiler.
2. Insufficient amount of events
In functions add(), set(), updatePool() and updateStartBlock() there are no corresponding events.
Conclusion
Berry Farms MasterChef and PavlovaToken contracts were audited. 1 high and 3 medium severity issues were found.
Disclaimer
This report is subject to the terms and conditions (including without limitation, description of services, confidentiality, disclaimer and limitation of liability) set forth in the Services Agreement, or the scope of services, and terms and conditions provided to the Company in connection with the Agreement. This report provided in connection with the Services set forth in the Agreement shall be used by the Company only to the extent permitted under the terms and conditions set forth in the Agreement. This report may not be transmitted, disclosed, referred to or relied upon by any person for any purposes without 0xGuard prior written consent.

This report is not, nor should be considered, an “endorsement” or “disapproval” of any particular project or team. This report is not, nor should be considered, an indication of the economics or value of any “product” or “asset” created by any team or project that contracts 0xGuard to perform a security assessment. This report does not provide any warranty or guarantee regarding the absolute bug-free nature of the technology analyzed, nor do they provide any indication of the technologies proprietors, business, business model or legal compliance.

This report should not be used in any way to make decisions around investment or involvement with any particular project. This report in no way provides investment advice, nor should be leveraged as investment advice of any sort. This report represents an extensive assessing process intending to help our customers increase the quality of their code while reducing the high level of risk presented by cryptographic tokens and blockchain technology.

Blockchain technology and cryptographic assets present a high level of ongoing risk. 0xGuard’s position is that each company and individual are responsible for their own due diligence and continuous security. 0xGuard’s goal is to help reduce the attack vectors and the high level of variance associated with utilizing new and consistently changing technologies, and in no way claims any guarantee of security or functionality of the technology we agree to analyze.

Static code analysis result
Number of lines: 512 (+ 1015 in dependencies, + 0 in tests)
Number of assembly lines: 0
Number of contracts: 2 (+ 8 in dependencies, + 0 tests)

Number of optimization issues: 15
Number of informational issues: 43
Number of low issues: 9
Number of medium issues: 10
Number of high issues: 0


Use: Openzeppelin-Ownable, Openzeppelin-SafeMath, Openzeppelin-ERC20
ERCs: ERC20
INFO:Detectors:
MasterChef.pendingPavlova(uint256,address) (contracts/MasterChef.sol#139-152) performs a multiplication on the result of a division:
    -pavlovaReward = multiplier.mul(pavlovaPerBlock).mul(pool.allocPoint).div(totalAllocPoint) (contracts/MasterChef.sol#146-148)
    -accPavlovaPerShare = accPavlovaPerShare.add(pavlovaReward.mul(1e18).div(lpSupply)) (contracts/MasterChef.sol#149)
MasterChef.updatePool(uint256) (contracts/MasterChef.sol#163-183) performs a multiplication on the result of a division:
    -pavlovaReward = multiplier.mul(pavlovaPerBlock).mul(pool.allocPoint).div(totalAllocPoint) (contracts/MasterChef.sol#174-176)
    -pool.accPavlovaPerShare = pool.accPavlovaPerShare.add(pavlovaReward.mul(1e18).div(lpSupply)) (contracts/MasterChef.sol#179-181)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply
INFO:Detectors:
MasterChef.updatePool(uint256) (contracts/MasterChef.sol#163-183) uses a dangerous strict equality:
    - lpSupply == 0 || pool.allocPoint == 0 (contracts/MasterChef.sol#169)
PavlovaToken._writeCheckpoint(address,uint32,uint256,uint256) (contracts/PavlovaToken.sol#198-217) uses a dangerous strict equality:
    - nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber (contracts/PavlovaToken.sol#209)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dangerous-strict-equalities
INFO:Detectors:
Reentrancy in MasterChef.deposit(uint256,uint256) (contracts/MasterChef.sol#186-211):
    External calls:
    - updatePool(_pid) (contracts/MasterChef.sol#189)
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    - safePavlovaTransfer(msg.sender,pending) (contracts/MasterChef.sol#195)
    - transferSuccess = pavlova.transfer(_to,pavlovaBal) (contracts/MasterChef.sol#247)
    - transferSuccess = pavlova.transfer(_to,_amount) (contracts/MasterChef.sol#249)
    - pool.lpToken.safeTransferFrom(address(msg.sender),address(this),_amount) (contracts/MasterChef.sol#199)
    - pool.lpToken.safeTransfer(feeAddress,depositFee) (contracts/MasterChef.sol#202)
    State variables written after the call(s):
    - user.amount = user.amount.add(_amount).sub(depositFee) (contracts/MasterChef.sol#204)
Reentrancy in MasterChef.deposit(uint256,uint256) (contracts/MasterChef.sol#186-211):
    External calls:
    - updatePool(_pid) (contracts/MasterChef.sol#189)
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    - safePavlovaTransfer(msg.sender,pending) (contracts/MasterChef.sol#195)
    - transferSuccess = pavlova.transfer(_to,pavlovaBal) (contracts/MasterChef.sol#247)
    - transferSuccess = pavlova.transfer(_to,_amount) (contracts/MasterChef.sol#249)
    - pool.lpToken.safeTransferFrom(address(msg.sender),address(this),_amount) (contracts/MasterChef.sol#199)
    State variables written after the call(s):
    - user.amount = user.amount.add(_amount) (contracts/MasterChef.sol#206)
Reentrancy in MasterChef.updateEmissionRate(uint256) (contracts/MasterChef.sol#270-274):
    External calls:
    - massUpdatePools() (contracts/MasterChef.sol#271)
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    State variables written after the call(s):
    - pavlovaPerBlock = _pavlovaPerBlock (contracts/MasterChef.sol#272)
Reentrancy in MasterChef.updatePool(uint256) (contracts/MasterChef.sol#163-183):
    External calls:
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    State variables written after the call(s):
    - pool.accPavlovaPerShare = pool.accPavlovaPerShare.add(pavlovaReward.mul(1e18).div(lpSupply)) (contracts/MasterChef.sol#179-181)
    - pool.lastRewardBlock = block.number (contracts/MasterChef.sol#182)
Reentrancy in MasterChef.withdraw(uint256,uint256) (contracts/MasterChef.sol#214-229):
    External calls:
    - updatePool(_pid) (contracts/MasterChef.sol#218)
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    - safePavlovaTransfer(msg.sender,pending) (contracts/MasterChef.sol#221)
    - transferSuccess = pavlova.transfer(_to,pavlovaBal) (contracts/MasterChef.sol#247)
    - transferSuccess = pavlova.transfer(_to,_amount) (contracts/MasterChef.sol#249)
    State variables written after the call(s):
    - user.amount = user.amount.sub(_amount) (contracts/MasterChef.sol#224)
Reentrancy in MasterChef.withdraw(uint256,uint256) (contracts/MasterChef.sol#214-229):
    External calls:
    - updatePool(_pid) (contracts/MasterChef.sol#218)
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    - safePavlovaTransfer(msg.sender,pending) (contracts/MasterChef.sol#221)
    - transferSuccess = pavlova.transfer(_to,pavlovaBal) (contracts/MasterChef.sol#247)
    - transferSuccess = pavlova.transfer(_to,_amount) (contracts/MasterChef.sol#249)
    - pool.lpToken.safeTransfer(address(msg.sender),_amount) (contracts/MasterChef.sol#225)
    State variables written after the call(s):
    - user.rewardDebt = user.amount.mul(pool.accPavlovaPerShare).div(1e18) (contracts/MasterChef.sol#227)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-1
INFO:Detectors:
MasterChef.constructor(PavlovaToken,uint256,address,address)._devAddress (contracts/MasterChef.sol#79) lacks a zero-check on :
    - devAddress = _devAddress (contracts/MasterChef.sol#85)
MasterChef.constructor(PavlovaToken,uint256,address,address)._feeAddress (contracts/MasterChef.sol#80) lacks a zero-check on :
    - feeAddress = _feeAddress (contracts/MasterChef.sol#86)
MasterChef.setDevAddress(address)._devAddress (contracts/MasterChef.sol#255) lacks a zero-check on :
    - devAddress = _devAddress (contracts/MasterChef.sol#256)
MasterChef.setFeeAddress(address)._feeAddress (contracts/MasterChef.sol#260) lacks a zero-check on :
    - feeAddress = _feeAddress (contracts/MasterChef.sol#261)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#missing-zero-address-validation
INFO:Detectors:
Reentrancy in MasterChef.deposit(uint256,uint256) (contracts/MasterChef.sol#186-211):
    External calls:
    - updatePool(_pid) (contracts/MasterChef.sol#189)
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    - safePavlovaTransfer(msg.sender,pending) (contracts/MasterChef.sol#195)
    - transferSuccess = pavlova.transfer(_to,pavlovaBal) (contracts/MasterChef.sol#247)
    - transferSuccess = pavlova.transfer(_to,_amount) (contracts/MasterChef.sol#249)
    - pool.lpToken.safeTransferFrom(address(msg.sender),address(this),_amount) (contracts/MasterChef.sol#199)
    - pool.lpToken.safeTransfer(feeAddress,depositFee) (contracts/MasterChef.sol#202)
    Event emitted after the call(s):
    - Deposit(msg.sender,_pid,_amount) (contracts/MasterChef.sol#210)
Reentrancy in MasterChef.emergencyWithdraw(uint256) (contracts/MasterChef.sol#232-240):
    External calls:
    - pool.lpToken.safeTransfer(address(msg.sender),amount) (contracts/MasterChef.sol#238)
    Event emitted after the call(s):
    - EmergencyWithdraw(msg.sender,_pid,amount) (contracts/MasterChef.sol#239)
Reentrancy in MasterChef.updateEmissionRate(uint256) (contracts/MasterChef.sol#270-274):
    External calls:
    - massUpdatePools() (contracts/MasterChef.sol#271)
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    Event emitted after the call(s):
    - UpdateEmissionRate(msg.sender,_pavlovaPerBlock) (contracts/MasterChef.sol#273)
Reentrancy in MasterChef.withdraw(uint256,uint256) (contracts/MasterChef.sol#214-229):
    External calls:
    - updatePool(_pid) (contracts/MasterChef.sol#218)
    - pavlova.mint(devAddress,pavlovaReward.div(10)) (contracts/MasterChef.sol#177)
    - pavlova.mint(address(this),pavlovaReward) (contracts/MasterChef.sol#178)
    - safePavlovaTransfer(msg.sender,pending) (contracts/MasterChef.sol#221)
    - transferSuccess = pavlova.transfer(_to,pavlovaBal) (contracts/MasterChef.sol#247)
    - transferSuccess = pavlova.transfer(_to,_amount) (contracts/MasterChef.sol#249)
    - pool.lpToken.safeTransfer(address(msg.sender),_amount) (contracts/MasterChef.sol#225)
    Event emitted after the call(s):
    - Withdraw(msg.sender,_pid,_amount) (contracts/MasterChef.sol#228)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3
INFO:Detectors:
PavlovaToken.delegateBySig(address,uint256,uint256,uint8,bytes32,bytes32) (contracts/PavlovaToken.sol#90-111) uses timestamp for comparisons
    Dangerous comparisons:
    - require(bool,string)(now <= expiry,PAVLOVA::delegateBySig: signature expired) (contracts/PavlovaToken.sol#109)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp
INFO:Detectors:
Address.isContract(address) (node_modules/@openzeppelin/contracts/utils/Address.sol#26-35) uses assembly
    - INLINE ASM (node_modules/@openzeppelin/contracts/utils/Address.sol#33)
Address._verifyCallResult(bool,bytes,string) (node_modules/@openzeppelin/contracts/utils/Address.sol#171-188) uses assembly
    - INLINE ASM (node_modules/@openzeppelin/contracts/utils/Address.sol#180-183)
PavlovaToken.getChainId() (contracts/PavlovaToken.sol#224-230) uses assembly
    - INLINE ASM (contracts/PavlovaToken.sol#226-228)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#assembly-usage
INFO:Detectors:
MasterChef.nonDuplicated(IERC20) (contracts/MasterChef.sol#95-98) compares to a boolean constant:
    -require(bool,string)(poolExistence[_lpToken] == false,nonDuplicated: duplicated) (contracts/MasterChef.sol#96)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#boolean-equality
INFO:Detectors:
Different versions of Solidity is used:
    - Version used: ['0.6.12', '>=0.6.0<0.8.0', '>=0.6.2<0.8.0']
    - >=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/access/Ownable.sol#3)
    - >=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/math/SafeMath.sol#3)
    - >=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#3)
    - >=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol#3)
    - >=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/token/ERC20/SafeERC20.sol#3)
    - >=0.6.2<0.8.0 (node_modules/@openzeppelin/contracts/utils/Address.sol#3)
    - >=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/utils/Context.sol#3)
    - >=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol#3)
    - 0.6.12 (contracts/MasterChef.sol#3)
    - 0.6.12 (contracts/PavlovaToken.sol#3)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#different-pragma-directives-are-used
INFO:Detectors:
Pragma version>=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/access/Ownable.sol#3) is too complex
Pragma version>=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/math/SafeMath.sol#3) is too complex
Pragma version>=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#3) is too complex
Pragma version>=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol#3) is too complex
Pragma version>=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/token/ERC20/SafeERC20.sol#3) is too complex
Pragma version>=0.6.2<0.8.0 (node_modules/@openzeppelin/contracts/utils/Address.sol#3) is too complex
Pragma version>=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/utils/Context.sol#3) is too complex
Pragma version>=0.6.0<0.8.0 (node_modules/@openzeppelin/contracts/utils/ReentrancyGuard.sol#3) is too complex
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity
INFO:Detectors:
Low level call in Address.sendValue(address,uint256) (node_modules/@openzeppelin/contracts/utils/Address.sol#53-59):
    - (success) = recipient.call{value: amount}() (node_modules/@openzeppelin/contracts/utils/Address.sol#57)
Low level call in Address.functionCallWithValue(address,bytes,uint256,string) (node_modules/@openzeppelin/contracts/utils/Address.sol#114-121):
    - (success,returndata) = target.call{value: value}(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#119)
Low level call in Address.functionStaticCall(address,bytes,string) (node_modules/@openzeppelin/contracts/utils/Address.sol#139-145):
    - (success,returndata) = target.staticcall(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#143)
Low level call in Address.functionDelegateCall(address,bytes,string) (node_modules/@openzeppelin/contracts/utils/Address.sol#163-169):
    - (success,returndata) = target.delegatecall(data) (node_modules/@openzeppelin/contracts/utils/Address.sol#167)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls
INFO:Detectors:
Parameter MasterChef.add(uint256,IERC20,uint16)._allocPoint (contracts/MasterChef.sol#102) is not in mixedCase
Parameter MasterChef.add(uint256,IERC20,uint16)._lpToken (contracts/MasterChef.sol#103) is not in mixedCase
Parameter MasterChef.add(uint256,IERC20,uint16)._depositFeeBP (contracts/MasterChef.sol#104) is not in mixedCase
Parameter MasterChef.set(uint256,uint256,uint16)._pid (contracts/MasterChef.sol#123) is not in mixedCase
Parameter MasterChef.set(uint256,uint256,uint16)._allocPoint (contracts/MasterChef.sol#124) is not in mixedCase
Parameter MasterChef.set(uint256,uint256,uint16)._depositFeeBP (contracts/MasterChef.sol#125) is not in mixedCase
Parameter MasterChef.getMultiplier(uint256,uint256)._from (contracts/MasterChef.sol#134) is not in mixedCase
Parameter MasterChef.getMultiplier(uint256,uint256)._to (contracts/MasterChef.sol#134) is not in mixedCase
Parameter MasterChef.pendingPavlova(uint256,address)._pid (contracts/MasterChef.sol#139) is not in mixedCase
Parameter MasterChef.pendingPavlova(uint256,address)._user (contracts/MasterChef.sol#139) is not in mixedCase
Parameter MasterChef.updatePool(uint256)._pid (contracts/MasterChef.sol#163) is not in mixedCase
Parameter MasterChef.deposit(uint256,uint256)._pid (contracts/MasterChef.sol#186) is not in mixedCase
Parameter MasterChef.deposit(uint256,uint256)._amount (contracts/MasterChef.sol#186) is not in mixedCase
Parameter MasterChef.withdraw(uint256,uint256)._pid (contracts/MasterChef.sol#214) is not in mixedCase
Parameter MasterChef.withdraw(uint256,uint256)._amount (contracts/MasterChef.sol#214) is not in mixedCase
Parameter MasterChef.emergencyWithdraw(uint256)._pid (contracts/MasterChef.sol#232) is not in mixedCase
Parameter MasterChef.safePavlovaTransfer(address,uint256)._to (contracts/MasterChef.sol#243) is not in mixedCase
Parameter MasterChef.safePavlovaTransfer(address,uint256)._amount (contracts/MasterChef.sol#243) is not in mixedCase
Parameter MasterChef.setDevAddress(address)._devAddress (contracts/MasterChef.sol#255) is not in mixedCase
Parameter MasterChef.setFeeAddress(address)._feeAddress (contracts/MasterChef.sol#260) is not in mixedCase
Parameter MasterChef.updateEmissionRate(uint256)._pavlovaPerBlock (contracts/MasterChef.sol#270) is not in mixedCase
Parameter MasterChef.updateStartBlock(uint256)._startBlock (contracts/MasterChef.sol#277) is not in mixedCase
Parameter PavlovaToken.mint(address,uint256)._to (contracts/PavlovaToken.sol#14) is not in mixedCase
Parameter PavlovaToken.mint(address,uint256)._amount (contracts/PavlovaToken.sol#14) is not in mixedCase
Variable PavlovaToken._delegates (contracts/PavlovaToken.sol#26) is not in mixedCase
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions
INFO:Detectors:
Redundant expression "this (node_modules/@openzeppelin/contracts/utils/Context.sol#21)" inContext (node_modules/@openzeppelin/contracts/utils/Context.sol#15-24)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#redundant-statements
INFO:Detectors:
renounceOwnership() should be declared external:
    - Ownable.renounceOwnership() (node_modules/@openzeppelin/contracts/access/Ownable.sol#54-57)
transferOwnership(address) should be declared external:
    - Ownable.transferOwnership(address) (node_modules/@openzeppelin/contracts/access/Ownable.sol#63-67)
symbol() should be declared external:
    - ERC20.symbol() (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#72-74)
decimals() should be declared external:
    - ERC20.decimals() (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#89-91)
totalSupply() should be declared external:
    - ERC20.totalSupply() (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#96-98)
transfer(address,uint256) should be declared external:
    - ERC20.transfer(address,uint256) (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#115-118)
allowance(address,address) should be declared external:
    - ERC20.allowance(address,address) (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#123-125)
approve(address,uint256) should be declared external:
    - ERC20.approve(address,uint256) (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#134-137)
transferFrom(address,address,uint256) should be declared external:
    - ERC20.transferFrom(address,address,uint256) (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#152-156)
increaseAllowance(address,uint256) should be declared external:
    - ERC20.increaseAllowance(address,uint256) (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#170-173)
decreaseAllowance(address,uint256) should be declared external:
    - ERC20.decreaseAllowance(address,uint256) (node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol#189-192)
deposit(uint256,uint256) should be declared external:
    - MasterChef.deposit(uint256,uint256) (contracts/MasterChef.sol#186-211)
withdraw(uint256,uint256) should be declared external:
    - MasterChef.withdraw(uint256,uint256) (contracts/MasterChef.sol#214-229)
emergencyWithdraw(uint256) should be declared external:
    - MasterChef.emergencyWithdraw(uint256) (contracts/MasterChef.sol#232-240)
mint(address,uint256) should be declared external:
    - PavlovaToken.mint(address,uint256) (contracts/PavlovaToken.sol#14-17)
Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#public-function-that-could-be-declared-external
INFO:Slither:. analyzed (10 contracts with 75 detectors), 77 result(s) found
All rights reserve
Copying and distribution of information on this site is permitted only by agreement of 0xGuard