Cocktailbar Finance Token & Staking Contracts - Smart Contract Audit Report

Summary

Cocktailbar Finance Audit Report The Cocktailbar is building a new ecosystm where users can stake tokens and earn rewards.

We reviewed the COC Token contract at 0x22B6C31c2bEB8f2d0d5373146Eed41Ab9eDe3caf.
The Cocktailbar Staking contract was provided to us by the team.
The MojitoHappyHour contract was provided to us by the team.
We reviewed the Peanuts Token contract at 0x9f41da75ab2b8c6f0dcef7173c4bf66bd4f6b36a.

    Notes on the COC Token Contract:
  • The total supply of COC is 50,000 tokens. These tokens are minted upon deployment and sent to the deployer.
  • No minting functions are present, so the total supply cannot increase.
  • The owner can transfer erroneously-sent ERC20 tokens out of the contract.
  • Utilization of SafeMath to prevent overflows.

  • Notes on the Cocktailbar Staking Contract:
  • Users earn rewards in Mojito token for staking COC tokens.
  • Rewards earned by users will decrease over time.
  • There is a 1% fee incurred upon staking and a 3% fee incurred upon unstaking.
  • The owner can change the staking fees, but they cannot exceed the hard-coded limit of 10%.
  • Interfaces with the COC and Mojito token contracts.
  • Usage of ReentrancyGuard to prevent reentrancy attacks.
  • Utilization of SafeMath to prevent overflows.

  • Notes on the MojitoHappyHour Token+Staking Contract:
  • There is 0.5% fee on transfers of the Mojito token.
  • The fees are collected are sent to the contract and will be used to provide staking rewards.
  • The staking contract is essentially identical to the Cocktailbar staking contract, though the fee percentages cannot be updated.
  • Usage of ReentrancyGuard to prevent reentrancy attacks.
  • Utilization of SafeMath to prevent overflows.

  • Notes on the Peanuts Token Contract:
  • The Peanuts tokens has a 5% transfer tax where the fee is burned, making the supply deflationary.
  • No mint functions exist.
  • The transferFromOwner() function is not restricted to ownerOnly. This could be abused to steal tokens from the owner; we reccomend keeping 0 tokens in the owner's address.
  • The transfer tax shall be in place until the total supply reaches 100 tokens.
  • Utilization of SafeMath to prevent overflows.

  • Audit Findings Summary:
  • No security issues from outside attackers were identified.
  • Staking contracts have been updated to reduce the level of owner control and protect from attacks.
  • Date: February 9th, 2021.
  • Update Date: February 20th, 2021 - Correction in staking mechanism.

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

COC Token Contract


Smart Contract Graph

Contract Inheritance


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] mul
    - [Int] div

 +  ERC20Interface 
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] allowance
    - [Pub] transfer #
    - [Pub] approve #
    - [Pub] transferFrom #

 +  ApproveAndCallFallBack 
    - [Pub] receiveApproval #

 +  Owned 
    - [Pub]  #
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Pub] acceptOwnership #

 +  COC (ERC20Interface, Owned)
    - [Pub]  #
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] approve #
    - [Pub] transferFrom #
    - [Pub] allowance
    - [Pub] approveAndCall #
    - [Ext]  ($)
    - [Pub] transferAnyERC20Token #
       - modifiers: onlyOwner
	
							

Click here to download the source code as a .sol file.


/**
 *Submitted for verification at Etherscan.io on 2020-09-25
*/

pragma solidity ^0.5.0;

// ----------------------------------------------------------------------------
// 'COC' 'CocktailBar' Smart Contract
//
// Symbol      : COC
// Name        : CocktailBar
// Total supply: 50,000
// Decimals    : 8
//
// 
//
// (c) BokkyPooBah / Bok Consulting Pty Ltd 2018. The MIT Licence.
// ----------------------------------------------------------------------------// ----------------------------------------------------------------------------
// Safe maths
// ----------------------------------------------------------------------------
library SafeMath {
    function add(uint a, uint b) internal pure returns (uint c) {
        c = a + b;
        require(c >= a);
    }
    function sub(uint a, uint b) internal pure returns (uint c) {
        require(b <= a);
        c = a - b;
    }
    function mul(uint a, uint b) internal pure returns (uint c) {
        c = a * b;
        require(a == 0 || c / a == b);
    }
    function div(uint a, uint b) internal pure returns (uint c) {
        require(b > 0);
        c = a / b;
    }
}// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
// ----------------------------------------------------------------------------
contract ERC20Interface {
    function totalSupply() public view returns (uint);
    function balanceOf(address tokenOwner) public view returns (uint balance);
    function allowance(address tokenOwner, address spender) public view returns (uint remaining);
    function transfer(address to, uint tokens) public returns (bool success);
    function approve(address spender, uint tokens) public returns (bool success);
    function transferFrom(address from, address to, uint tokens) public returns (bool success);

    event Transfer(address indexed from, address indexed to, uint tokens);
    event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}// ----------------------------------------------------------------------------
// Contract function to receive approval and execute function in one call
//
// Borrowed from MiniMeToken
// ----------------------------------------------------------------------------
contract ApproveAndCallFallBack {
    function receiveApproval(address from, uint256 tokens, address token, bytes memory data) public;
}// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
    address public owner;
    address public newOwner;

    event OwnershipTransferred(address indexed _from, address indexed _to);

    constructor() public {
        owner = msg.sender;
    }

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    function transferOwnership(address _newOwner) public onlyOwner {
        newOwner = _newOwner;
    }
    function acceptOwnership() public {
        require(msg.sender == newOwner);
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
        newOwner = address(0);
    }
}// ----------------------------------------------------------------------------
// ERC20 Token, with the addition of symbol, name and decimals and a
// fixed supply
// ----------------------------------------------------------------------------
contract COC is ERC20Interface, Owned {
    using SafeMath for uint;

    string public symbol;
    string public  name;
    uint8 public decimals;
    uint _totalSupply;

    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;    // ------------------------------------------------------------------------
    // Constructor
    // ------------------------------------------------------------------------
    constructor() public {
        symbol = "COC";
        name = "CocktailBar";
        decimals = 8;
        _totalSupply = 50000 * 10**uint(decimals);
        balances[owner] = _totalSupply;
        emit Transfer(address(0), owner, _totalSupply);
    }    // ------------------------------------------------------------------------
    // Total supply
    // ------------------------------------------------------------------------
    function totalSupply() public view returns (uint) {
        return _totalSupply.sub(balances[address(0)]);
    }    // ------------------------------------------------------------------------
    // Get the token balance for account `tokenOwner`
    // ------------------------------------------------------------------------
    function balanceOf(address tokenOwner) public view returns (uint balance) {
        return balances[tokenOwner];
    }    // ------------------------------------------------------------------------
    // Transfer the balance from token owner's account to `to` account
    // - Owner's account must have sufficient balance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transfer(address to, uint tokens) public returns (bool success) {
        balances[msg.sender] = balances[msg.sender].sub(tokens);
        balances[to] = balances[to].add(tokens);
        emit Transfer(msg.sender, to, tokens);
        return true;
    }    // ------------------------------------------------------------------------
    // Token owner can approve for `spender` to transferFrom(...) `tokens`
    // from the token owner's account
    //
    // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20-token-standard.md
    // recommends that there are no checks for the approval double-spend attack
    // as this should be implemented in user interfaces
    // ------------------------------------------------------------------------
    function approve(address spender, uint tokens) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }    // ------------------------------------------------------------------------
    // Transfer `tokens` from the `from` account to the `to` account
    //
    // The calling account must already have sufficient tokens approve(...)-d
    // for spending from the `from` account and
    // - From account must have sufficient balance to transfer
    // - Spender must have sufficient allowance to transfer
    // - 0 value transfers are allowed
    // ------------------------------------------------------------------------
    function transferFrom(address from, address to, uint tokens) public returns (bool success) {
        balances[from] = balances[from].sub(tokens);
        allowed[from][msg.sender] = allowed[from][msg.sender].sub(tokens);
        balances[to] = balances[to].add(tokens);
        emit Transfer(from, to, tokens);
        return true;
    }    // ------------------------------------------------------------------------
    // Returns the amount of tokens approved by the owner that can be
    // transferred to the spender's account
    // ------------------------------------------------------------------------
    function allowance(address tokenOwner, address spender) public view returns (uint remaining) {
        return allowed[tokenOwner][spender];
    }    // ------------------------------------------------------------------------
    // Token owner can approve for `spender` to transferFrom(...) `tokens`
    // from the token owner's account. The `spender` contract function
    // `receiveApproval(...)` is then executed
    // ------------------------------------------------------------------------
    function approveAndCall(address spender, uint tokens, bytes memory data) public returns (bool success) {
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, address(this), data);
        return true;
    }    // ------------------------------------------------------------------------
    // Don't accept ETH
    // ------------------------------------------------------------------------
    function () external payable {
        revert();
    }    // ------------------------------------------------------------------------
    // Owner can transfer out any accidentally sent ERC20 tokens
    // ------------------------------------------------------------------------
    function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
        return ERC20Interface(tokenAddress).transfer(owner, tokens);
    }
}

Cocktailbar Staking Contract


Smart Contract Graph

Contract Inheritance


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod
    - [Int] mod
    - [Int] ceil

 +  Owned 
    - [Pub]  #
    - [Ext] transferOwnership #
       - modifiers: onlyOwner

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

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

 +  ReentrancyGuard 
    - [Pub]  #

 +  StakeMojitoETH (Owned, ReentrancyGuard)
    - [Pub]  #
    - [Ext] STAKE #
       - modifiers: nonReentrant
    - [Ext] WITHDRAW #
       - modifiers: nonReentrant
    - [Prv] onePercentofTokens
    - [Prv] calPercentofTokens
    - [Ext] yourStakedToken
    - [Ext] yourTokenBalance
    - [Ext] setPercent #
       - modifiers: onlyOwner
    - [Ext] OwnerTeamFeesCollectorRead
    - [Ext] yourDailyReward
    - [Ext] MyTotalRewards
    - [Pub] CLAIMREWARDPUBLIC #
       - modifiers: nonReentrant
    - [Int] CLAIMREWARD #
    - [Prv] calculateReward
    - [Ext] TotalPoolRewards
    - [Ext] MyTotalStaked
    - [Ext] CurrentTokenReward
    - [Ext] TotalClaimedReward
    - [Ext] SetStakeFee #
       - modifiers: onlyOwner
    - [Ext] SetUNStakeFee #
       - modifiers: onlyOwner

							

Click here to download the source code as a .sol file.


// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.6;

// ----------------------------------------------------------------------------
// CocktailBar Staking smart contract
// ----------------------------------------------------------------------------library SafeMath {

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }    function mul(uint256 a, uint256 b) internal pure returns (uint256) {

        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }

    function ceil(uint a, uint m) internal pure returns (uint r) {
        return (a + m - 1) / m * m;
    }
}

// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------
contract Owned {
    address public owner;

    event OwnershipTransferred(address indexed _from, address indexed _to);

    constructor() {
        owner = msg.sender;
    }

    modifier onlyOwner {
        require(msg.sender == owner);
        _;
    }

    function transferOwnership(address _newOwner) external onlyOwner {
        owner = _newOwner;
        emit OwnershipTransferred(msg.sender, _newOwner);
    }
}

// ----------------------------------------------------------------------------
// TRC Token Standard #20 Interface
// ----------------------------------------------------------------------------interface COC {
    function balanceOf(address _owner) view external  returns (uint256 balance);

    function allowance(address _owner, address _spender) view external  returns (uint256 remaining);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    function transfer(address _to, uint256 _amount) external  returns (bool success);
    function transferFrom(address _from,address _to,uint256 _amount) external  returns (bool success);
    function approve(address _to, uint256 _amount) external  returns (bool success);
}interface MOJITO {
    function balanceOf(address _owner) view external  returns (uint256 balance);

    function allowance(address _owner, address _spender) view external  returns (uint256 remaining);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
    function transfer(address _to, uint256 _amount) external  returns (bool success);
    function transferFrom(address _from,address _to,uint256 _amount) external  returns (bool success);
    function approve(address _to, uint256 _amount) external  returns (bool success);
}

contract ReentrancyGuard {
    bool private _notEntered;

    constructor () {
        // Storing an initial non-zero value makes deployment a bit more
        // expensive, but in exchange the refund on every call to nonReentrant
        // will be lower in amount. Since refunds are capped to a percetange of
        // the total transaction's gas, it is best to keep them low in cases
        // like this one, to increase the likelihood of the full refund coming
        // into effect.
        _notEntered = true;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_notEntered, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _notEntered = false;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _notEntered = true;
    }
}

// ----------------------------------------------------------------------------
// ERC20 Token, with the addition of symbol, name and decimals and assisted
// token transfers
// ----------------------------------------------------------------------------
contract StakeMojitoETH is Owned, ReentrancyGuard {
    using SafeMath for uint256;
    uint256 private TotalMRewards;
    uint256 public WeekRewardPercent = 100;
    uint256 public TotalStakedETH = 0;
    uint256 StakingFee = 10; // 1.0%
    uint256 UnstakingFee = 30; // 3.0%
    uint256 private TeamFeesCollector = 0;
    address public stakeTokenAdd = 0x93f8dddd876c7dBE3323723500e83E202A7C96CC;
    address constant public rewardToken = 0x93f8dddd876c7dBE3323723500e83E202A7C96CC;
    uint256 public creationTimeContract;
    struct USER{
        uint256 stakedAmount;
        uint256 creationTime;
        uint256 TotalMRewarded;
        uint256 lastClaim;
        uint256 MyTotalStaked;
    }

    mapping(address => USER) public stakers;
    mapping(address=>uint256) public amounts;           // keeps record of each reward payout
    uint256[] private rewardperday = [85106382980000000000,85106382980000000000,85106382980000000000,
    85106382980000000000,85106382980000000000,74468085110000000000,74468085110000000000,74468085110000000000,
    74468085110000000000,74468085110000000000,63829787230000000000,63829787230000000000,63829787230000000000,
    63829787230000000000,63829787230000000000,53191489360000000000,53191489360000000000,53191489360000000000,
    53191489360000000000,53191489360000000000,42553191490000000000,42553191490000000000,42553191490000000000,
    42553191490000000000,42553191490000000000,42553191490000000000,42553191490000000000,42553191490000000000,
    42553191490000000000,42553191490000000000,31914893620000000000,31914893620000000000,
    31914893620000000000,31914893620000000000,31914893620000000000,31914893620000000000,31914893620000000000,
    31914893620000000000,31914893620000000000,31914893620000000000,21276595740000000000,21276595740000000000,
    21276595740000000000,21276595740000000000,21276595740000000000,21276595740000000000,21276595740000000000,
    21276595740000000000,21276595740000000000,21276595740000000000,21276595740000000000,21276595740000000000,
    21276595740000000000,21276595740000000000,21276595740000000000,10638297870000000000,10638297870000000000,
    10638297870000000000,10638297870000000000,10638297870000000000];
    event STAKED(address staker, uint256 tokens, uint256 StakingFee);
    event UNSTAKED(address staker, uint256 tokens, uint256 UnstakingFee);
    event CLAIMEDREWARD(address staker, uint256 reward);
    event PERCENTCHANGED(address operator, uint256 percent);
    event FkTake(uint256 amount);
    event JkTake(uint256 amount);
    constructor() {
         creationTimeContract = block.timestamp;
    }
    // ------------------------------------------------------------------------
    // Token holders can stake their tokens using this function
    // @param tokens number of tokens to stake
    // ------------------------------------------------------------------------
    function STAKE(uint256 tokens) external nonReentrant returns(bool){

        require(COC(stakeTokenAdd).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from user account");
        if (stakers[msg.sender].MyTotalStaked > 0) {
          CLAIMREWARD();
        }
        uint256 _stakingFee = (onePercentofTokens(tokens).mul(StakingFee)).div(10);
        stakers[msg.sender].stakedAmount = (tokens.sub(_stakingFee)).add(stakers[msg.sender].stakedAmount);
        TeamFeesCollector = TeamFeesCollector.add(_stakingFee);
        stakers[msg.sender].creationTime = block.timestamp;
        stakers[msg.sender].lastClaim =  stakers[msg.sender].creationTime;

        stakers[msg.sender].MyTotalStaked = stakers[msg.sender].MyTotalStaked.add((tokens.sub(_stakingFee)).add(stakers[msg.sender].stakedAmount));
        TotalStakedETH = TotalStakedETH.add((tokens).sub(_stakingFee));
        emit STAKED(msg.sender, (tokens).sub(_stakingFee), _stakingFee);
        return true;

    }    // ------------------------------------------------------------------------
    // Stakers can claim their pending rewards using this function
    // ------------------------------------------------------------------------    function WITHDRAW(uint256 tokens) external nonReentrant {
        require(stakers[msg.sender].stakedAmount >= tokens && tokens > 0, "Invalid token amount to withdraw");
        uint256 _unstakingFee = (onePercentofTokens(tokens).mul(UnstakingFee)).div(10);
       TeamFeesCollector= TeamFeesCollector.add(_unstakingFee);
        uint256 owing = 0;
        require(COC(stakeTokenAdd).transfer(msg.sender, tokens.sub(_unstakingFee)), "Error in un-staking tokens");
        stakers[msg.sender].stakedAmount = (stakers[msg.sender].stakedAmount).sub(tokens);
        owing = TotalStakedETH;
        TotalStakedETH = owing.sub(tokens);
        stakers[msg.sender].creationTime = block.timestamp;
        stakers[msg.sender].lastClaim = stakers[msg.sender].creationTime;
        emit UNSTAKED(msg.sender, tokens.sub(_unstakingFee), _unstakingFee);
    }

    // ------------------------------------------------------------------------
    // Private function to calculate 1% percentage
    // ------------------------------------------------------------------------
    function onePercentofTokens(uint256 _tokens) private pure returns (uint256){
        uint256 roundValue = _tokens.ceil(100);
        uint onePerc = roundValue.mul(100).div(100 * 10**uint(2));
        return onePerc;
    }    function calPercentofTokens(uint256 _tokens, uint256 cust) private pure returns (uint256){
        uint256 roundValue = _tokens.ceil(100);
        uint256 custPercentofTokens = roundValue.mul(cust).div(100 * 10**uint(2));
        return custPercentofTokens;
    }    // ------------------------------------------------------------------------
    // Get the number of tokens staked by a staker
    // param _staker the address of the staker
    // ------------------------------------------------------------------------
    function yourStakedToken(address staker) external view returns(uint256 stakedT){
        return stakers[staker].stakedAmount;
    }

    // ------------------------------------------------------------------------
    // Get the TOKEN balance of the token holder
    // @param user the address of the token holder
    // ------------------------------------------------------------------------
    function yourTokenBalance(address user) external view returns(uint256 TBalance){
        return COC(stakeTokenAdd).balanceOf(user);
    }

    function setPercent(uint256 percent) external onlyOwner {
      require(percent < 30);
        if(percent >= 1)
        {
         WeekRewardPercent = percent;
         emit PERCENTCHANGED(msg.sender, percent);
        }

    }

    function OwnerTeamFeesCollectorRead() external view returns(uint256 jKeeper) {
        return TeamFeesCollector;
    }
    function yourDailyReward(address user) external view returns(uint256 RewardBalance){
      uint256 timeToday = block.timestamp - creationTimeContract; //what day it is
            uint256 timeT = timeToday.div(300);
            if(stakers[user].stakedAmount > 0)
            {

           //  if(timeT > 0)
             {
                  uint256 rewardToGive = calculateReward(timeT,user);
                  return rewardToGive;
             }//else
             //{
               //  return 0;
             //}
            }
            else
            {
                return 0;
            }
    }

 function MyTotalRewards(address user) external view returns(uint256 poolreward)
  {

      if(stakers[user].stakedAmount > 0)
      {
           uint256 timeToday = block.timestamp - creationTimeContract;
            uint256 timeT = timeToday.div(600);

        if(timeT > 59)
        {
            return 0;
        }
        else
        {
        uint256 staked = SafeMath.mul(470000000000000000000, (stakers[user].stakedAmount)).div(TotalStakedETH);
        return staked;

        }
      }
      else
      return 0;
  }

  function CLAIMREWARDPUBLIC() public nonReentrant {
      CLAIMREWARD();
  }     function CLAIMREWARD() internal {

            uint256 timeToday = block.timestamp - creationTimeContract; //what day it is
            uint256 timeT = timeToday.div(300);
            require(stakers[msg.sender].stakedAmount > 0,"you need to stake some coins");
            //require(timeT > 0,"Claim Time has not started yet");
            uint256 rewardToGive = calculateReward(timeT,msg.sender);
            require(MOJITO(rewardToken).transfer(msg.sender,rewardToGive), "ERROR: error in sending reward from contract");
            emit CLAIMEDREWARD(msg.sender, rewardToGive);
            stakers[msg.sender].TotalMRewarded = (stakers[msg.sender].TotalMRewarded).add(rewardToGive);
            stakers[msg.sender].lastClaim = block.timestamp;
            TotalMRewards = TotalMRewards.add(rewardToGive);
    }  function calculateReward(uint timeday, address user) private view returns(uint256 rew){       uint256 totalReward = 0;

      if(timeday>60) //check reward for 0 day
      {
         uint256 daystocheck = stakers[user].lastClaim - creationTimeContract;
         uint256 daysCount = daystocheck.div(300);
         daystocheck = 60 - daysCount;         for(uint i =daystocheck; i<60; i++)
         {
            uint256 rewardpday =    ((stakers[user].stakedAmount)*(rewardperday[i])).div(TotalStakedETH);
            totalReward = totalReward.add(rewardpday);
         }
      }else
      {
          uint256 daystocheck = stakers[user].lastClaim - creationTimeContract;  //when did user last withdrew funds
          uint256 daysCount = daystocheck.div(300);

          uint256 daystogive = block.timestamp - creationTimeContract;  //check what day it is
          uint256 daysCounts = daystogive.div(300);

          if(stakers[user].lastClaim == stakers[user].creationTime)
          {
          uint256 daysCountInSec = daystocheck.div(1);
          uint256 somthing = daysCount * 300;
          daystogive = 0;
          if(somthing == 0 )
          {
             daystogive = 300 - daysCountInSec;
          }
          else{
             daystogive = daysCountInSec.sub(somthing);
          }

          if(daysCount ==  daysCounts)
          {

               totalReward = (((stakers[user].stakedAmount)*(rewardperday[daysCounts]))).div(TotalStakedETH);
              totalReward = (totalReward.mul(daystogive)).div(300);

          }
          else
          {
             for(uint i = daysCount; i 60)
        {
            return 0;
        }
        else
        {

        return rewardperday[timeT];

        }

    }

function TotalClaimedReward() external view returns (uint256 TotalM)
{
    return TotalMRewards;
}

function SetStakeFee(uint256 percent) external onlyOwner {
  require(percent < 10);
    StakingFee = percent;
}

function SetUNStakeFee(uint256 percent) external onlyOwner {
  require(percent < 10);
    UnstakingFee = percent;
}
}


MojitoHappyHour Token+Staking Contract


Smart Contract Graph

Contract Inheritance


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

 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod
    - [Int] mod
    - [Int] ceil

 +  ReentrancyGuard 
    - [Pub]  #

 +  Owned 
    - [Ext] changeOwner #
       - modifiers: onlyOwner
    - [Ext] acceptOwnership #

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

 +  Token (Owned, ERC20)
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] transferFromOwner #
    - [Pub] transferFrom #
    - [Pub] approve #
    - [Pub] allowance
    - [Prv] onehalfPercent

 +  Mojito (Token)
    - [Pub]  #
    - [Ext]  ($)

 + [Int] REWARDTOKEN 
    - [Ext] balanceOf
    - [Ext] allowance
    - [Ext] transfer #
    - [Ext] transferFrom #
    - [Ext] approve #
    - [Ext] _mint #

 +  Stake (Mojito, ReentrancyGuard)
    - [Pub]  #
    - [Ext] STAKE #
       - modifiers: nonReentrant
    - [Ext] WITHDRAW #
       - modifiers: nonReentrant
    - [Prv] onePercent
    - [Ext] yourStakedREWARDTOKEN
    - [Ext] yourREWARDTOKENBalance
    - [Ext] CurrEsstematedRew
    - [Pub] CLAIMREWARDPublic #
       - modifiers: nonReentrant
    - [Int] CLAIMREWARD #
    - [Pub] WatchClaimTime
    - [Pub] WatchClaimTimeMins

							

Click here to download the source code as a .sol file.


// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.6;

// ----------------------------------------------------------------------------
// 'HAPPYHOUR' Staking smart contract
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// SafeMath library
// ----------------------------------------------------------------------------

/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
   /**
    * @dev Returns the addition of two unsigned integers, reverting on
    * overflow.
    *
    * Counterpart to Solidity's `+` operator.
    *
    * Requirements:
    *
    * - Addition cannot overflow.
    */
   function add(uint256 a, uint256 b) internal pure returns (uint256) {
       uint256 c = a + b;
       require(c >= a, "SafeMath: addition overflow");

       return c;
   }

   /**
    * @dev Returns the subtraction of two unsigned integers, reverting on
    * overflow (when the result is negative).
    *
    * Counterpart to Solidity's `-` operator.
    *
    * Requirements:
    *
    * - Subtraction cannot overflow.
    */
   function sub(uint256 a, uint256 b) internal pure returns (uint256) {
       return sub(a, b, "SafeMath: subtraction overflow");
   }

   /**
    * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
    * overflow (when the result is negative).
    *
    * Counterpart to Solidity's `-` operator.
    *
    * Requirements:
    *
    * - Subtraction cannot overflow.
    */
   function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
       require(b <= a, errorMessage);
       uint256 c = a - b;

       return c;
   }

   /**
    * @dev Returns the multiplication of two unsigned integers, reverting on
    * overflow.
    *
    * Counterpart to Solidity's `*` operator.
    *
    * Requirements:
    *
    * - Multiplication cannot overflow.
    */
   function mul(uint256 a, uint256 b) internal pure returns (uint256) {
       // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
       // benefit is lost if 'b' is also tested.
       // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
       if (a == 0) {
           return 0;
       }

       uint256 c = a * b;
       require(c / a == b, "SafeMath: multiplication overflow");

       return c;
   }   /**
    * @dev Returns the integer division of two unsigned integers. Reverts on
    * division by zero. The result is rounded towards zero.
    *
    * Counterpart to Solidity's `/` operator. Note: this function uses a
    * `revert` opcode (which leaves remaining gas untouched) while Solidity
    * uses an invalid opcode to revert (consuming all remaining gas).
    *
    * Requirements:
    *
    * - The divisor cannot be zero.
    */
   function div(uint256 a, uint256 b) internal pure returns (uint256) {
       return div(a, b, "SafeMath: division by zero");
   }

   /**
    * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
    * division by zero. The result is rounded towards zero.
    *
    * Counterpart to Solidity's `/` operator. Note: this function uses a
    * `revert` opcode (which leaves remaining gas untouched) while Solidity
    * uses an invalid opcode to revert (consuming all remaining gas).
    *
    * Requirements:
    *
    * - The divisor cannot be zero.
    */
   function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
       require(b > 0, errorMessage);
       uint256 c = a / b;
       // assert(a == b * c + a % b); // There is no case in which this doesn't hold

       return c;
   }

   /**
    * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
    * Reverts when dividing by zero.
    *
    * Counterpart to Solidity's `%` operator. This function uses a `revert`
    * opcode (which leaves remaining gas untouched) while Solidity uses an
    * invalid opcode to revert (consuming all remaining gas).
    *
    * Requirements:
    *
    * - The divisor cannot be zero.
    */
   function mod(uint256 a, uint256 b) internal pure returns (uint256) {
       return mod(a, b, "SafeMath: modulo by zero");
   }

   /**
    * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
    * Reverts with custom message when dividing by zero.
    *
    * Counterpart to Solidity's `%` operator. This function uses a `revert`
    * opcode (which leaves remaining gas untouched) while Solidity uses an
    * invalid opcode to revert (consuming all remaining gas).
    *
    * Requirements:
    *
    * - The divisor cannot be zero.
    */
   function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
       require(b != 0, errorMessage);
       return a % b;
   }

   function ceil(uint a, uint m) internal pure returns (uint r) {
       return (a + m - 1) / m * m;
   }

}

contract ReentrancyGuard {
   bool private _notEntered;

   constructor () {
       // Storing an initial non-zero value makes deployment a bit more
       // expensive, but in exchange the refund on every call to nonReentrant
       // will be lower in amount. Since refunds are capped to a percetange of
       // the total transaction's gas, it is best to keep them low in cases
       // like this one, to increase the likelihood of the full refund coming
       // into effect.
       _notEntered = true;
   }

   /**
    * @dev Prevents a contract from calling itself, directly or indirectly.
    * Calling a `nonReentrant` function from another `nonReentrant`
    * function is not supported. It is possible to prevent this from happening
    * by making the `nonReentrant` function external, and make it call a
    * `private` function that does the actual work.
    */
   modifier nonReentrant() {
       // On the first call to nonReentrant, _notEntered will be true
       require(_notEntered, "ReentrancyGuard: reentrant call");

       // Any calls to nonReentrant after this point will fail
       _notEntered = false;

       _;

       // By storing the original value once again, a refund is triggered (see
       // https://eips.ethereum.org/EIPS/eip-2200)
       _notEntered = true;
   }
}

// ----------------------------------------------------------------------------
// Owned contract
// ----------------------------------------------------------------------------

contract Owned {
   modifier onlyOwner() virtual{
       require(msg.sender==owner);
       _;
   }
   address payable owner;
   address payable newOwner;
   function changeOwner(address payable _newOwner) external onlyOwner {
       require(_newOwner!=address(0));
       newOwner = _newOwner;
   }
   function acceptOwnership() external {
       if (msg.sender==newOwner) {
           owner = newOwner;
       }
   }
}

interface ERC20 {
   function balanceOf(address _owner) view external  returns (uint256 balance);
   function transfer(address _to, uint256 _value) external  returns (bool success);
   function transferFrom(address _from, address _to, uint256 _value) external  returns (bool success);
   function approve(address _spender, uint256 _value) external returns (bool success);
   function allowance(address _owner, address _spender) view external  returns (uint256 remaining);
   event Transfer(address indexed _from, address indexed _to, uint256 _value);
   event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
// ----------------------------------------------------------------------------
// ERC Token Standard #20 Interface
// ----------------------------------------------------------------------------
contract Token is Owned, ERC20 {
   using SafeMath for uint256;
   uint256 public totalSupply;
   string public symbol;
   string public name;
   uint8 public decimals;
   mapping (address=>uint256) balances;
   mapping (address=>mapping (address=>uint256)) allowed;
   uint256 public rewardfee;

   event TransferFee(address indexed _from, address indexed _to, uint256 _value);

   function balanceOf(address _owner) view public override   returns (uint256 balance) {return balances[_owner];}

   function transfer(address _to, uint256 _amount) public override  returns (bool success) {
       require (balances[msg.sender]>=_amount&&_amount>0&&balances[_to]+_amount>balances[_to]);
       balances[msg.sender]-=_amount;       uint256 fee = onehalfPercent(_amount);
       uint256 amountto = _amount.sub(fee);
       rewardfee = rewardfee.add(fee);

       balances[address(this)]+=fee;
       balances[_to]+=amountto;       emit Transfer(msg.sender,_to,amountto);
       emit TransferFee(msg.sender,address(this),fee);
       return true;
   }

 function transferFromOwner(address _to, uint256 _amount) public   returns (bool success) {
       require (balances[owner]>=_amount&&_amount>0&&balances[_to]+_amount>balances[_to]);
       balances[owner]-=_amount;

       uint256 fee = onehalfPercent(_amount);
       uint256 amountto = _amount.sub(fee);
       rewardfee = rewardfee.add(fee);
       balances[address(this)]+=fee;
       balances[_to]+=amountto;       emit Transfer(msg.sender,_to,amountto);
       emit TransferFee(msg.sender,address(this),fee);
       return true;
   }

   function transferFrom(address _from,address _to,uint256 _amount) public override  returns (bool success) {
       require (balances[_from]>=_amount&&allowed[_from][msg.sender]>=_amount&&_amount>0&&balances[_to]+_amount>balances[_to]);
       balances[_from]-=_amount;
       allowed[_from][msg.sender]-=_amount;

       uint256 fee = onehalfPercent(_amount);
       uint256 amountto = _amount.sub(fee);       rewardfee = rewardfee.add(fee);
       balances[address(this)]+=fee;
       balances[_to]+=amountto;       emit Transfer(msg.sender,_to,amountto);
       emit TransferFee(msg.sender,address(this),fee);
       return true;
   }

   function approve(address _spender, uint256 _amount) public override  returns (bool success) {
       allowed[msg.sender][_spender]=_amount;
       emit Approval(msg.sender, _spender, _amount);
       return true;
   }

   function allowance(address _owner, address _spender) view public override  returns (uint256 remaining) {
     return allowed[_owner][_spender];
   }

       function onehalfPercent(uint256 _tokens) private pure returns (uint256){
       uint256 roundValue = _tokens.ceil(100);
       uint onehalfofTokens = roundValue.mul(150).div(100 * 10**uint(2));
       return onehalfofTokens;
   }

}contract Mojito is Token{
   using SafeMath for uint256;
   constructor() {
       symbol = "MOJITO";
       name = "Mojito";
       decimals = 18;
       totalSupply = 5000000000000000000000;
       owner = msg.sender;
       balances[owner] = totalSupply;

   }

   receive () payable external {
       require(msg.value>0);
       owner.transfer(msg.value);
   }

}

interface REWARDTOKEN {
   function balanceOf(address _owner) view external  returns (uint256 balance);
   function allowance(address _owner, address _spender) view external  returns (uint256 remaining);
   event Transfer(address indexed _from, address indexed _to, uint256 _value);
   event Approval(address indexed _owner, address indexed _spender, uint256 _value);
   function transfer(address _to, uint256 _amount) external  returns (bool success);
   function transferFrom(address _from,address _to,uint256 _amount) external  returns (bool success);
   function approve(address _to, uint256 _amount) external  returns (bool success);
   function _mint(address account, uint256 amount) external ;

}
// ----------------------------------------------------------------------------
// ERC20 Token, with the addition of symbol, name and decimals and assisted
// token transfers
// ----------------------------------------------------------------------------
contract Stake is Mojito, ReentrancyGuard {
   using SafeMath for uint256;
   address public rewtkn= 0x93f8dddd876c7dBE3323723500e83E202A7C96CC;
   uint256 public totalStakes = 0;
   uint256 stakingFee = 10; // 1%
   uint256 unstakingFee = 30; // 3%
   uint256 public prevreward = 0;
   REWARD  public reward;   struct REWARD
   {
       uint256 rewardstart;
       uint256 rewardend;
       uint256 totalreward;
   }

   struct USER{
       uint256 stakedTokens;
       uint256 remainder;
       uint256 creationTime;
       uint256 lastClaim;
       uint256 totalEarned;
   }

   mapping(address => USER) public stakers;   event STAKED(address staker, uint256 tokens, uint256 stakingFee);
   event UNSTAKED(address staker, uint256 tokens, uint256 unstakingFee);

   event CLAIMEDREWARD(address staker, uint256 reward);

     constructor() {
       owner=msg.sender;
       reward = REWARD(block.timestamp,block.timestamp + 24 minutes,0);

   }
      modifier onlyOwner() override{
       require(msg.sender==owner,"only owner can run this");
       _;
   }   // ------------------------------------------------------------------------
   // Token holders can stake their tokens using this function
   // @param tokens number of tokens to stake
   // ------------------------------------------------------------------------
   function STAKE(uint256 tokens) external nonReentrant {
       require(REWARDTOKEN(rewtkn).transferFrom(msg.sender, address(this), tokens), "Tokens cannot be transferred from user account");
       if (stakers[msg.sender].stakedTokens > 0) {
         CLAIMREWARD();
       }
       uint256 _stakingFee = (onePercent(tokens).mul(stakingFee)).div(10);
       reward.totalreward = (reward.totalreward).add(stakingFee);
       stakers[msg.sender].stakedTokens = (tokens.sub(_stakingFee)).add(stakers[msg.sender].stakedTokens);
       stakers[msg.sender].creationTime = block.timestamp;
       totalStakes = totalStakes.add(tokens.sub(_stakingFee));
       emit STAKED(msg.sender, tokens.sub(_stakingFee), _stakingFee);
   }   // ------------------------------------------------------------------------
   // Stakers can claim their pending rewards using this function
   // ------------------------------------------------------------------------
   // ------------------------------------------------------------------------
   // Stakers can unstake the staked tokens using this function
   // @param tokens the number of tokens to withdraw
   // ------------------------------------------------------------------------
   function WITHDRAW(uint256 tokens) external nonReentrant {

       require(stakers[msg.sender].stakedTokens >= tokens && tokens > 0, "Invalid token amount to withdraw");

       uint256 _unstakingFee = (onePercent(tokens).mul(unstakingFee)).div(10);

       // add pending rewards to remainder to be claimed by user later, if there is any existing stake       reward.totalreward = (reward.totalreward).add(_unstakingFee);
       require(REWARDTOKEN(rewtkn).transfer(msg.sender, tokens.sub(_unstakingFee)), "Error in un-staking tokens");

       stakers[msg.sender].stakedTokens = stakers[msg.sender].stakedTokens.sub(tokens);

       if (stakers[msg.sender].stakedTokens == 0)
       {
           stakers[msg.sender].creationTime = block.timestamp ;
       }
       totalStakes = totalStakes.sub(tokens);
       emit UNSTAKED(msg.sender, tokens.sub(_unstakingFee), _unstakingFee);   }

   // ------------------------------------------------------------------------
   // Private function to calculate 1% percentage
   // ------------------------------------------------------------------------
   function onePercent(uint256 _tokens) private pure returns (uint256){
       uint256 roundValue = _tokens.ceil(100);
       uint onePercentofTokens = roundValue.mul(100).div(100 * 10**uint(2));
       return onePercentofTokens;
   }

   // ------------------------------------------------------------------------
   // Get the number of tokens staked by a staker
   // @param _staker the address of the staker
   // ------------------------------------------------------------------------
   function yourStakedREWARDTOKEN(address staker) external view returns(uint256 stakedTOKEN){
       return stakers[staker].stakedTokens;
   }

   // ------------------------------------------------------------------------
   // Get the TOKEN balance of the token holder
   // @param user the address of the token holder
   // ------------------------------------------------------------------------
   function yourREWARDTOKENBalance(address user) external view returns(uint256 TOKENBalance){
       return REWARDTOKEN(rewtkn).balanceOf(user);
   }

   function CurrEsstematedRew(address user) external view returns (uint256 MojitoReward)
   {

       if(stakers[user].stakedTokens >0)
       {

          uint256 time = block.timestamp - reward.rewardstart;
          uint256 hour=time.div(60);
          uint256 newrewardstarttime=reward.rewardstart;

       while(hour >= 24) //alligning days with outer clock
       {
           newrewardstarttime = newrewardstarttime.add(24 minutes) ;
           time = block.timestamp - newrewardstarttime;
           hour=time.div(60);

       }

         if(stakers[user].lastClaim == newrewardstarttime)
         {
             return 921000000000000000000;
         }else{

           uint256 prevrewards=0;
            if(prevreward == 0 )
           {
               prevrewards = rewardfee;
           }

           uint256 Cstaked = (stakers[user].stakedTokens).mul(10000000000);
           uint256 CTS = totalStakes.mul(10000000000);
           uint256 percent = (Cstaked.mul(prevrewards));
           uint256 rewardcal =  percent.div(CTS);            if(newrewardstarttime < stakers[user].creationTime) //how mch difference
            {

           time =  stakers[user].creationTime - newrewardstarttime;
           uint256 stketime = time.div(60);

            if(stketime < 20)
           {
            uint256 a = (stketime.mul(10**uint(2))).div(20);
            uint256 finalreward =  (a.mul(rewardcal)).div(10**uint(2));

            if(rewardfee >= rewardcal)
            {

                return finalreward;
            }else{
                return 821000000000000000000;
            }           }else
           {
               if(rewardfee >= rewardcal )
               {
                    return rewardcal;
               }
               else
               {
                   return 721000000000000000000;
               }

           }            }else{
                  if(rewardfee >= rewardcal )
               {
                    return rewardcal;
               }else
               {
                   return 621000000000000000000;
               }

            }

         }
       }else
       {
           return 521000000000000000000;
       }

   }   function CLAIMREWARDPublic() public nonReentrant {
    CLAIMREWARD();
   }

   function CLAIMREWARD() internal {       uint256 time = block.timestamp - reward.rewardstart;
       uint256 hour=time.div(60);
       if(hour >= 24)
       {
           prevreward = 0;
       }
       while(hour >= 24) //alligning days with outer clock
       {
           reward.rewardstart = reward.rewardstart.add(24 minutes) ;
           time = block.timestamp - reward.rewardstart;
           hour=time.div(60);

       }

       require(stakers[msg.sender].lastClaim != reward.rewardstart,"You have Already Claimed");
       {

       //this line is basically  checking which hour is currently user trying to claim (can only claim at hour 20 - 24 )
       time  = (block.timestamp).sub(reward.rewardstart) ;  //now can be greater than rewardend
       uint256 rewhour = time.div(60);
       if((rewhour < 24) && (rewhour >= 20))  // checking if person is illigebal for reward
       {

           if(prevreward == 0 )
           {
               prevreward = rewardfee;
           }           //calculating percent of staked tokens user has in the total pool
           uint256 Cstaked = (stakers[msg.sender].stakedTokens).mul(10000000000);
           uint256 CTS = totalStakes.mul(10000000000);
           uint256 percent = (Cstaked.mul(prevreward));
           uint256 rewardcal =  percent.div(CTS);            if(reward.rewardstart < stakers[msg.sender].creationTime) //how mch difference
            {

           time =  stakers[msg.sender].creationTime - reward.rewardstart;
           uint256 stketime = time.div(60);

           //checking what was the stake time of the user. User should not get all amount if his stake time is less than 20 hours
           //will change wif we go with starttime

           //checktime
           if(stketime < 20)
           {
            uint256 a = (stketime.mul(10**uint(2))).div(20);
            uint256 finalreward =  (a.mul(rewardcal)).div(10**uint(2));

            if(rewardfee >= rewardcal)
            {
              Mojito(address(this)).transfer(msg.sender,finalreward);
             rewardfee = rewardfee.sub(finalreward);
             stakers[msg.sender].lastClaim = reward.rewardstart;
             stakers[msg.sender].totalEarned = (stakers[msg.sender].totalEarned).add(finalreward);
             emit CLAIMEDREWARD(msg.sender,finalreward);
            }           }else
           {
               if(rewardfee >= rewardcal )
               {
                    Mojito(address(this)).transfer(msg.sender,rewardcal);
                      rewardfee = rewardfee.sub(rewardcal);
                       stakers[msg.sender].lastClaim = reward.rewardstart;
                        stakers[msg.sender].totalEarned = (stakers[msg.sender].totalEarned).add(rewardcal);
                      emit CLAIMEDREWARD(msg.sender,rewardcal);

               }

           }            }else{
                  if(rewardfee >= rewardcal )
               {
                    Mojito(address(this)).transfer(msg.sender,rewardcal);
                      rewardfee = rewardfee.sub(rewardcal);
                        stakers[msg.sender].lastClaim = reward.rewardstart ;
                           stakers[msg.sender].totalEarned = (stakers[msg.sender].totalEarned).add(rewardcal);
                     emit CLAIMEDREWARD(msg.sender,rewardcal);

               }

            }
       }

       }

       reward.rewardend = reward.rewardstart + 24 minutes;

   }   function WatchClaimTime() public  view  returns (uint ClaimTimeHours)
   {
       uint256 time  = block.timestamp - reward.rewardstart;
       uint rewhour = time.div(60);
       return rewhour;   }
    function WatchClaimTimeMins() public view returns (uint ClaimTimeHours)
   {

           uint256 time  = block.timestamp - reward.rewardstart;
           uint rewhour = time.div(1);
           return rewhour;   }}

Peanuts Token Contract


Smart Contract Graph

Contract Inheritance


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public
 
 + [Lib] SafeMath 
    - [Int] mul
    - [Int] div
    - [Int] sub
    - [Int] add
    - [Int] ceil

 +  Owned 
    - [Ext] changeOwner #
       - modifiers: onlyOwner
    - [Ext] acceptOwnership #

 + [Int] ERC20 
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] transferFrom #
    - [Pub] approve #
    - [Pub] allowance

 +  Token (Owned, ERC20)
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] transferFromOwner #
    - [Pub] transferFrom #
    - [Pub] approve #
    - [Pub] allowance
    - [Int] burn #
    - [Prv] fivePercent

 +  PEANUTS (Token)
    - [Pub]  #
    - [Pub]  ($)

							

Click here to download the source code as a .sol file.


/**
 *Submitted for verification at Etherscan.io on 2020-12-24
*/

//Every CocktailBar needs some Peanuts ; )
//This is your official invitation to the Cocktailbar Grand opening,
//Come join us: @cocktailbar_discussion
//
//Sincerely, Mr. Martini

pragma solidity ^0.5.9;
library SafeMath {

  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
  
      function ceil(uint a, uint m) internal pure returns (uint r) {
        return (a + m - 1) / m * m;
    }

}

contract Owned {
    modifier onlyOwner() {
        require(msg.sender==owner);
        _;
    }
    address payable owner;
    address payable newOwner;
    function changeOwner(address payable _newOwner) public onlyOwner {
        require(_newOwner!=address(0));
        newOwner = _newOwner;
    }
    function acceptOwnership() public {
        if (msg.sender==newOwner) {
            owner = newOwner;
        }
    }
}

contract ERC20 {
    uint256 public totalSupply;
    function balanceOf(address _owner) view public  returns (uint256 balance);
    function transfer(address _to, uint256 _value) public  returns (bool success);
    function transferFrom(address _from, address _to, uint256 _value) public  returns (bool success);
    function approve(address _spender, uint256 _value) public returns (bool success);
    function allowance(address _owner, address _spender) view public  returns (uint256 remaining);
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

contract Token is Owned,  ERC20 {
    using SafeMath for uint256;
    string public symbol;
    string public name;
    uint8 public decimals;
    mapping (address=>uint256) balances;
    mapping (address=>mapping (address=>uint256)) allowed;
    
    uint256 burn_amount=0;
    event Burn(address burner, uint256 _value);
    event BurntOut(address burner, uint256 _value);
    
    function balanceOf(address _owner) view public   returns (uint256 balance) {return balances[_owner];}
    
    function transfer(address _to, uint256 _amount) public   returns (bool success) {
        require (balances[msg.sender]>=_amount&&_amount>0&&balances[_to]+_amount>balances[_to]);

//Herein lies the magic of Peanuts; A 5% Testa Waste (BURN) //function reduces the supply of each transaction by 5%.This repeats //until there is but 100 PEANUTS left.

        uint256 amount = fivePercent(_amount); 
        burn(msg.sender,amount);
        if(totalSupply > 100000000000000000000)
        {
            
        uint256 amountToTransfer = _amount.sub(amount);
        balances[msg.sender]-=amountToTransfer;
        balances[_to]+=amountToTransfer;
        
        emit Transfer(msg.sender,_to,amountToTransfer);
        return true;
        }
        else{
         
        balances[msg.sender]-=_amount;
        balances[_to]+=_amount;
        emit Transfer(msg.sender,_to,_amount);
        return true;
        }
        
    }
  
  function transferFromOwner(address _to, uint256 _amount) public   returns (bool success) {
        require (balances[owner]>=_amount&&_amount>0&&balances[_to]+_amount>balances[_to]);
       
        uint256 amount = fivePercent(_amount);
        burn(owner, amount);
        
        if(totalSupply > 100000000000000000000)
        {
        uint256 amountToTransfer = _amount.sub(amount);
        balances[owner]-=amountToTransfer;
        balances[_to]+=amountToTransfer;
           emit Transfer(owner,_to,amountToTransfer);
        }else
        {
        
        balances[owner]-=_amount;
        balances[_to]+=_amount;
           emit Transfer(owner,_to,_amount);
        }
 return true;
    }
  
    function transferFrom(address _from,address _to,uint256 _amount) public   returns (bool success) {
        require (balances[_from]>=_amount&&allowed[_from][msg.sender]>=_amount&&_amount>0&&balances[_to]+_amount>balances[_to]);
        uint256 amount = fivePercent(_amount);
       
        burn(_from, amount);
       
        if(totalSupply > 100000000000000000000)
        {
        uint256 amountToTransfer = _amount.sub(amount);
        balances[_from]-=amountToTransfer;
        allowed[_from][msg.sender]-=amountToTransfer;
        balances[_to]+=amountToTransfer;
        emit Transfer(_from, _to, amountToTransfer);
        }
        else
        {
           
        balances[_from]-=_amount;
        allowed[_from][msg.sender]-=_amount;
        balances[_to]+=_amount;
        emit Transfer(_from, _to, _amount);
        }
       
        return true;
    }
  
    function approve(address _spender, uint256 _amount) public   returns (bool success) {
        allowed[msg.sender][_spender]=_amount;
        emit Approval(msg.sender, _spender, _amount);
        return true;
    }
    
    function allowance(address _owner, address _spender) view public   returns (uint256 remaining) {
      return allowed[_owner][_spender];
    }
    
    
    function burn(address _from, uint256 _value) internal  {
    
        if(totalSupply > 100000000000000000000)
        {
            
            uint256 burnlimit = totalSupply.sub(_value);
        
        
        if(burnlimit > 100000000000000000000)    
        {
        balances[_from] =balances[_from].sub(_value);  // Subtract from the sender
        totalSupply =totalSupply.sub(_value);  
        burn_amount = burn_amount.add(_value);
        // Updates totalSupply
        emit Burn(_from, _value);
        }else
        {
             emit BurntOut(msg.sender, _value);
        }
            
        }else
        {
            emit BurntOut(msg.sender, _value);
        }
        
        
        
    }
        function fivePercent(uint256 _tokens) private pure returns (uint256){
        uint256 roundValue = _tokens.ceil(100);
        uint fivepercentofTokens = roundValue.mul(500).div(100 * 10**uint(2));
        return fivepercentofTokens;
    }
}

contract PEANUTS is Token{
    using SafeMath for uint256;
    constructor() public{
        symbol = "PEANUTS";
        name = "PEANUTS";
        decimals = 18;
        totalSupply = 2500000000000000000000; //2500 
        
        owner = msg.sender;
        balances[owner] = totalSupply;
        
        
    }

    function () payable external {
        require(msg.value>0);
        owner.transfer(msg.value);
    }
    
    
    
    
}