Black Lemon Fixed Staking - Audit Report

Summary

Black Lemon Audit Report Black Lemon is building a new staking platform with an associated database.

For this audit, we analyzed Black Lemon's FixStaking and Database contracts at commit cf9b2b5b9ec01988c46fc4ddf63d95704a6ce839 on the project team's GitHub repository.

We previously audited Black Lemon's Token and NFT Staking contracts here.

Notes on the Contracts:
  • These contracts allow users to stake specified tokens into the Database contract through the FixStaking contract in order to earn rewards which are intended to be in the form of the deposit asset.
  • The FixStaking contract is used as a frontend for users and Admins to interact with, while the Database is handles the majority of the staking logic and holds deposited funds and rewards.
  • At the time of deployment, the deployer is given the Admin role.
  • An Admin can create a new pool at any time, specifying a start and end time for deposits to be permitted, reward rate, a maximum total amount staked limit, fee rates, and whether the pool offers an NFT reward.
  • An Admin can update any pool's attributes to any values at any time.
  • An Admin can remove a pool at any time, which transfers any staked funds in the pool to the Admin.
  • Despite the pool's NFT attribute, there is no logic related to NFT rewards present in these contracts.
  • When depositing, the total resulting amount that the user has staked in the specified pool must be greater than a defined minimum amount and less than a defined maximum amount. The minimum and maximum amounts can be updated by an Admin to any amount at any time.
  • The total amount that can be staked in a pool accross all users is not permitted to exceed the pool's defined limit. A pool's limit can be updated by an Admin to any amount at any time.
  • There is no fee for depositing tokens.
  • Users can only deposit to a pool within the pool's defined start and end times. A pool's start and end times can be updated by an Admin to any values at any time.
  • If a user's funds have not been staked for the pools specified staking duration, they must pay both a fee on rewards earned and a fee on the amount staked when withdrawing. The staking duration for a pool is equal to its end time - start time. A user's staking duration for a pool is updated whenever they deposit funds.
  • Fees are based on the pool's main penalty rate, which is subtracted from user's staked funds, and the pool's sub penalty rate, which is subtracted from the users earned rewards. The fees are percentage based and can be changed by an Admin to any amount at any time.
  • Users will lose previously unclaimed rewards for a pool when depositing additional funds to it.
  • If a user withdraws early, they must wait a penalty period before claiming rewards from the pool again. This penalty period can be changed by an Admin at any time.
  • If a user withdraws after the pool's staking duration has passed, there is no fee on the staked principal or the earned rewards.
  • An admin can update the reward rate of a pool to any amount at any time.
  • A user's tokens will stop earning rewards once they have reached the pool's staking duration.
  • An emergencyWithdraw function exists so users can withdraw without collecting rewards. There are no fees or penalties for emergency withdrawals.
  • An Admin can pause and unpause the contract at any time. Users can deposit, withdraw, or claim pending rewards only when the contract is unpaused. Users can use the emergency withdraw function only when the contract is paused.
  • The team must be careful not to use a fee on transfer token as the platform's token.
  • An Admin can withdraw any ERC20 from the Database contract at any time.
  • The token used for deposits, withdrawals, and rewards can be changed by an Admin at any time.
  • The project team must fund the Database contract in order to pay out earned rewards.
  • An Admin can update the FixStaking contract's associated Database contract address at any time.
  • Any address with the Staking role can access any Admin functions by interacting directly with the Database contract; this role is intended to be given to the FixStaking contract.
  • As the contracts are implemented with Solidity 0.8.x, they are protected from overflows.
  • The console library can be removed for gas saving purposes as it is never used.


Audit Findings Summary:
  • No security issues from outside attackers were identified.
  • Ensure trust in the owner as they have substantial control in the ecosystem. An Admin can withdraw any tokens staked by users from the platform at any time. The platform's token can also be changed at any time; if a user has staked a certain token and the contract's token is subsequently updated, their withdrawals and rewards will be in the form of the updated token.
  • Date: November 20th, 2021

Combined External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Deprecated OpcodesN/APASS
Ether ThiefN/APASS
ExceptionsN/APASS
External CallsN/APASS
Integer Over/UnderflowN/APASS
Multiple SendsN/APASS
SuicideN/APASS
State Change External CallsN/APASS
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS


Details: FixStaking Contract


Smart Contract Graph

Smart Contract Inheritance



 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public

  + [Int] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [Int] IAccessControl 
    - [Ext] hasRole
    - [Ext] getRoleAdmin
    - [Ext] grantRole #
    - [Ext] revokeRole #
    - [Ext] renounceRole #

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 + [Lib] Strings 
    - [Int] toString
    - [Int] toHexString
    - [Int] toHexString

 + [Int] IERC165 
    - [Ext] supportsInterface

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  AccessControl (Context, IAccessControl, ERC165)
    - [Pub] supportsInterface
    - [Pub] hasRole
    - [Int] _checkRole
    - [Pub] getRoleAdmin
    - [Pub] grantRole #
       - modifiers: onlyRole
    - [Pub] revokeRole #
       - modifiers: onlyRole
    - [Pub] renounceRole #
    - [Int] _setupRole #
    - [Int] _setRoleAdmin #
    - [Prv] _grantRole #
    - [Prv] _revokeRole #

 + [Lib] console 
    - [Prv] _sendLogPayload
    - [Int] log
    - [Int] logInt
    - [Int] logUint
    - [Int] logString
    - [Int] logBool
    - [Int] logAddress
    - [Int] logBytes
    - [Int] logBytes1
    - [Int] logBytes2
    - [Int] logBytes3
    - [Int] logBytes4
    - [Int] logBytes5
    - [Int] logBytes6
    - [Int] logBytes7
    - [Int] logBytes8
    - [Int] logBytes9
    - [Int] logBytes10
    - [Int] logBytes11
    - [Int] logBytes12
    - [Int] logBytes13
    - [Int] logBytes14
    - [Int] logBytes15
    - [Int] logBytes16
    - [Int] logBytes17
    - [Int] logBytes18
    - [Int] logBytes19
    - [Int] logBytes20
    - [Int] logBytes21
    - [Int] logBytes22
    - [Int] logBytes23
    - [Int] logBytes24
    - [Int] logBytes25
    - [Int] logBytes26
    - [Int] logBytes27
    - [Int] logBytes28
    - [Int] logBytes29
    - [Int] logBytes30
    - [Int] logBytes31
    - [Int] logBytes32
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log

 + [Lib] UintSet 
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at
    - [Int] getArray

 +  Database (AccessControl)
    - [Pub]  #
    - [Ext] setMinMaxStake #
       - modifiers: onlyRole
    - [Ext] setPenaltyDay #
       - modifiers: onlyRole
    - [Ext] fundPool #
       - modifiers: onlyRole
    - [Ext] withdrawERC20 #
       - modifiers: onlyRole
    - [Ext] setExternalAddress #
       - modifiers: onlyRole
    - [Ext] createPool #
       - modifiers: onlyRole
    - [Ext] editPool #
       - modifiers: onlyRole
    - [Ext] removePool #
       - modifiers: onlyRole
    - [Ext] withdrawReserve #
       - modifiers: onlyRole
    - [Ext] setStakerStartTime #
       - modifiers: onlyRole
    - [Ext] setStakerEndTime #
       - modifiers: onlyRole
    - [Ext] setStakerAmount #
       - modifiers: onlyRole
    - [Ext] setStakerPoolIndex #
       - modifiers: onlyRole
    - [Ext] setStakerAmountMap #
       - modifiers: onlyRole
    - [Ext] setTotStakedAmount #
       - modifiers: onlyRole
    - [Ext] setStakerIndex #
       - modifiers: onlyRole
    - [Pub] setStakerPending #
       - modifiers: onlyRole
    - [Ext] setCurrentStakerIndex #
       - modifiers: onlyRole
    - [Ext] setPoolStakedAmount #
       - modifiers: onlyRole
    - [Ext] setPoolReserve #
       - modifiers: onlyRole
    - [Ext] deposit #
       - modifiers: onlyRole
    - [Ext] withdraw #
       - modifiers: onlyRole
    - [Pub] transferAndRemove #
       - modifiers: onlyRole
    - [Ext] getStaker
    - [Ext] getMinMaxStake
    - [Ext] getCurrentStakerIndex
    - [Ext] getStakerIndex
    - [Ext] getStakerAmount
    - [Ext] getPoolInfo
    - [Ext] getPools
    - [Ext] getPoolsLength
    - [Ext] getPenaltyDays

	
	


Details: Database Contract


Smart Contract Graph

Smart Contract Inheritance



 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
  + [Int] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [Int] IAccessControl 
    - [Ext] hasRole
    - [Ext] getRoleAdmin
    - [Ext] grantRole #
    - [Ext] revokeRole #
    - [Ext] renounceRole #

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 + [Lib] Strings 
    - [Int] toString
    - [Int] toHexString
    - [Int] toHexString

 + [Int] IERC165 
    - [Ext] supportsInterface

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  AccessControl (Context, IAccessControl, ERC165)
    - [Pub] supportsInterface
    - [Pub] hasRole
    - [Int] _checkRole
    - [Pub] getRoleAdmin
    - [Pub] grantRole #
       - modifiers: onlyRole
    - [Pub] revokeRole #
       - modifiers: onlyRole
    - [Pub] renounceRole #
    - [Int] _setupRole #
    - [Int] _setRoleAdmin #
    - [Prv] _grantRole #
    - [Prv] _revokeRole #

 + [Lib] console 
    - [Prv] _sendLogPayload
    - [Int] log
    - [Int] logInt
    - [Int] logUint
    - [Int] logString
    - [Int] logBool
    - [Int] logAddress
    - [Int] logBytes
    - [Int] logBytes1
    - [Int] logBytes2
    - [Int] logBytes3
    - [Int] logBytes4
    - [Int] logBytes5
    - [Int] logBytes6
    - [Int] logBytes7
    - [Int] logBytes8
    - [Int] logBytes9
    - [Int] logBytes10
    - [Int] logBytes11
    - [Int] logBytes12
    - [Int] logBytes13
    - [Int] logBytes14
    - [Int] logBytes15
    - [Int] logBytes16
    - [Int] logBytes17
    - [Int] logBytes18
    - [Int] logBytes19
    - [Int] logBytes20
    - [Int] logBytes21
    - [Int] logBytes22
    - [Int] logBytes23
    - [Int] logBytes24
    - [Int] logBytes25
    - [Int] logBytes26
    - [Int] logBytes27
    - [Int] logBytes28
    - [Int] logBytes29
    - [Int] logBytes30
    - [Int] logBytes31
    - [Int] logBytes32
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log
    - [Int] log

 + [Lib] UintSet 
    - [Int] add #
    - [Int] remove #
    - [Int] contains
    - [Int] length
    - [Int] at
    - [Int] getArray

 + [Int] IDatabase 
    - [Ext] setMinMaxStake #
    - [Ext] setPenaltyDay #
    - [Ext] fundPool #
    - [Ext] withdrawERC20 #
    - [Ext] setExternalAddress #
    - [Ext] createPool #
    - [Ext] editPool #
    - [Ext] removePool #
    - [Ext] withdrawReserve #
    - [Ext] deposit #
    - [Ext] withdraw #
    - [Ext] transferAndRemove #
    - [Ext] getPools
    - [Ext] getMinMaxStake
    - [Ext] getStakerIndex
    - [Ext] getCurrentStakerIndex
    - [Ext] getStaker
    - [Ext] getPoolInfo
    - [Ext] getStakerAmount
    - [Ext] getPenaltyDays
    - [Ext] getPoolsLength

 +  Pausable (Context)
    - [Pub]  #
    - [Pub] paused
    - [Int] _pause #
       - modifiers: whenNotPaused
    - [Int] _unpause #
       - modifiers: whenPaused

 +  FixStaking (AccessControl, Pausable)
    - [Pub]  #
    - [Ext] pause #
       - modifiers: onlyRole
    - [Ext] unPause #
       - modifiers: onlyRole
    - [Ext] setMinMaxStake #
       - modifiers: onlyRole
    - [Ext] setPenaltyDay #
       - modifiers: onlyRole
    - [Ext] fundPool #
       - modifiers: onlyRole,isPoolExist
    - [Ext] withdrawERC20 #
       - modifiers: onlyRole
    - [Ext] setExternalAddress #
       - modifiers: onlyRole
    - [Ext] createPool #
       - modifiers: onlyRole,isValid
    - [Ext] editPool #
       - modifiers: onlyRole,isPoolExist,isPoolEmpty,isValid
    - [Ext] removePool #
       - modifiers: onlyRole,isPoolExist,isPoolEmpty
    - [Ext] deposit #
       - modifiers: whenNotPaused,isPoolExist
    - [Ext] withdraw #
       - modifiers: whenNotPaused
    - [Ext] emergencyWithdraw #
       - modifiers: whenPaused
    - [Ext] claimPending #
       - modifiers: whenNotPaused
    - [Pub] getPenalty
    - [Pub] calculateRew
    - [Ext] stakerInfo