Contract 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 14

 

Contract Overview

Balance:
0.381031707450588525 ETH

ETH Value:
$1,402.20 (@ $3,680.01/ETH)
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xebfe3cc437078aea4566dddf0536f8d5ec8e1e70d226f7a19aecd2e092cec9a6Claim Reward1969189112024-04-02 20:02:5548 days 13 hrs ago0x864839328f6e25828e7807b39f3736ea65b8ed08 IN  0x300648a601c584e6379fa0d6a31cbbfcca6177e40 ETH0.00000584 0.01
0x7cf17652fda1fef9f961ce72c48d3b36eb91e7572fae394a5200cf9ce0c01d22Claim Reward1170663482023-08-01 11:09:01293 days 22 hrs ago0x4697c5f499eaf74d8914cb148c05aa1e80d5f534 IN  0x300648a601c584e6379fa0d6a31cbbfcca6177e40 ETH0.0000301 0.1
0x666355bd9afed5e928a2f5b86b340fb657f4c5314efacb266f67cb3de65e5fcfClaim Reward1101127032023-07-11 12:33:35314 days 21 hrs ago0xe645bb168a0f7588caa331e89d88acd22e1885c0 IN  0x300648a601c584e6379fa0d6a31cbbfcca6177e40 ETH0.00002287 0.1
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xa4bbab482d17c65d13a0e01a0793cb66d2bc9cb0430af7b274879086778a76cd2134152462024-05-21 4:20:275 hrs 40 mins ago 0xcd3e2adccf21198037e0eca780902e41f3c84838 0x300648a601c584e6379fa0d6a31cbbfcca6177e40.002756838634703196 ETH
0x8c2f32639d8db78571c86fb5abb542013557d08468d37a151d8a0c70d10396ca2123618392024-05-18 1:04:553 days 8 hrs ago 0xcd3e2adccf21198037e0eca780902e41f3c84838 0x300648a601c584e6379fa0d6a31cbbfcca6177e40.047765305218102414 ETH
0xd9adb22ae8fb7e86d2da234448012f68aa3d425b3973c5cf99f492069611421f2087999142024-05-07 14:05:1213 days 19 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40xd79850caa75647d868438005d44c33fce9d96ad90.000005787014207822 ETH
0x49b7cd36e92e02556bdb03bb0e01b9e6bedf9182018a25c743f880c9bb6f1eda2077723612024-05-04 14:20:0516 days 19 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40xe6ade88281cd978600d3b244f4b4c64a91abd1980.000141946686780361 ETH
0xf69de8a8d53043772ecc64df42352b482e5137a5ea6215be7a13ef5aef4a079d2075252082024-05-03 21:03:4417 days 12 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40xbe53f846025cb6c5cb141fc87b21de9f857874780.000450028592894472 ETH
0x8f24b1f582489c86254778aacffaa64ab577fa7a75eb1b7b31d230bbac369a8a2075244722024-05-03 21:00:4017 days 12 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x05ee0eb2b6a1ae3d6902572347e9b0d1e69d39020.000095859143077944 ETH
0x8f24b1f582489c86254778aacffaa64ab577fa7a75eb1b7b31d230bbac369a8a2075244722024-05-03 21:00:4017 days 12 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40x27c752b99c27d71ee9885b3b6d8eb7b38e45db140.000054883049292468 ETH
0x473513ede5f9534d71d1f99528181b89e99004afbf9bdd334a79d84d532d169c2073993332024-05-03 12:15:2917 days 21 hrs ago 0xcd3e2adccf21198037e0eca780902e41f3c84838 0x300648a601c584e6379fa0d6a31cbbfcca6177e40.004940251555395713 ETH
0x5c5769ab2264bc371c38312f4fbce6a1d88a8eb75bbe2e7941dfa8d29c73e47e2073987162024-05-03 12:12:5517 days 21 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x609f578ee4d0ba55a0325c6831a76d88fc30a98c0.004834152067246897 ETH
0x9dca61a617b02bf0b9e5ba9119d4567a1b7ad8c2dfef51af89f2c03b5804b3372073976312024-05-03 12:08:2317 days 21 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x34ecdad9090cd133e63cf6670f3a03aa7f04fa740.00000032022227572 ETH
0xcc9eabd2036ae2cc8e4a06bb73360a83fecb82f1e64ca040dc7f447b8777c3f92070919392024-05-02 14:47:5018 days 19 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40xd79850caa75647d868438005d44c33fce9d96ad90.000058454514138867 ETH
0xb3445b721beac498dca35912b7f7e17d1deef465ab015063ce688487339d22dd2068963142024-05-02 1:07:0319 days 8 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x05ee0eb2b6a1ae3d6902572347e9b0d1e69d39020.001230690763014403 ETH
0xb3445b721beac498dca35912b7f7e17d1deef465ab015063ce688487339d22dd2068963142024-05-02 1:07:0319 days 8 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40x27c752b99c27d71ee9885b3b6d8eb7b38e45db140.000674661010661477 ETH
0xef266824d0717cb263dc0f1f6a565009b571ac6d2d2c0aac73ecbfe77990f42a2068111032024-05-01 19:05:5519 days 14 hrs ago 0xcd3e2adccf21198037e0eca780902e41f3c84838 0x300648a601c584e6379fa0d6a31cbbfcca6177e40.043712258455936677 ETH
0x6b1e804d47f010b6521e8bb26f45219005e7823bf2e1b2b60cfbe142cdb38dda2068078402024-05-01 18:52:0119 days 15 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x609f578ee4d0ba55a0325c6831a76d88fc30a98c0.001988930716507416 ETH
0x6b1e804d47f010b6521e8bb26f45219005e7823bf2e1b2b60cfbe142cdb38dda2068078402024-05-01 18:52:0119 days 15 hrs ago 0xcd3e2adccf21198037e0eca780902e41f3c84838 0x300648a601c584e6379fa0d6a31cbbfcca6177e40.00724109710456621 ETH
0x0b5b7a7e31dc46bef4e882621e94fc6abf732c44ccbf1f0f79d550b0d21a06a82064431392024-04-30 17:09:0420 days 16 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40xd79850caa75647d868438005d44c33fce9d96ad90.000008639949783129 ETH
0x779fb115c399de4ce2760bb31fc66d0c5787646b5b4cb85544013b66e4f6cfb12064343212024-04-30 16:31:4620 days 17 hrs ago 0xcd3e2adccf21198037e0eca780902e41f3c84838 0x300648a601c584e6379fa0d6a31cbbfcca6177e40.0099 ETH
0x779fb115c399de4ce2760bb31fc66d0c5787646b5b4cb85544013b66e4f6cfb12064343212024-04-30 16:31:4620 days 17 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x609f578ee4d0ba55a0325c6831a76d88fc30a98c0.000165311313228521 ETH
0x876016ea3689b974bf647ac5667fe2c29ceee2f920d205fb5eebaa676faa20f72059733872024-04-29 8:02:3322 days 1 hr ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40xd79850caa75647d868438005d44c33fce9d96ad90.000000961001994599 ETH
0x2e5fb237d365f0ce7a48c51c4c0dee06960334d6e9eb4a963546e95171946fcd2053993122024-04-27 15:45:2623 days 18 hrs ago 0xcd3e2adccf21198037e0eca780902e41f3c84838 0x300648a601c584e6379fa0d6a31cbbfcca6177e40.001533277220447902 ETH
0x76d2e9cb84a240c776b432b73dab94fdf95c6796eec9c01b53c24da8e903d39d2053990342024-04-27 15:44:1623 days 18 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x609f578ee4d0ba55a0325c6831a76d88fc30a98c0.000169658840637165 ETH
0xbcdf6a5e93348b94f3e9496e1cbdf10bcd07ba60c470f926347717f962ec13712053977242024-04-27 15:38:4523 days 18 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x34ecdad9090cd133e63cf6670f3a03aa7f04fa740.000000003609799402 ETH
0x9bdbb9ec517490c73e93400323772c9b8522248517d558b3fb1cb9517fff56f92051713032024-04-26 23:44:1624 days 10 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e4 0x05ee0eb2b6a1ae3d6902572347e9b0d1e69d39020.000031989139110688 ETH
0x9bdbb9ec517490c73e93400323772c9b8522248517d558b3fb1cb9517fff56f92051713032024-04-26 23:44:1624 days 10 hrs ago 0x300648a601c584e6379fa0d6a31cbbfcca6177e40x27c752b99c27d71ee9885b3b6d8eb7b38e45db140.000016538438468732 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
LendingRewards

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 4 : IRewardsTracker.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

interface IRewardsTracker {
  function claimReward() external;

  function depositRewards() external payable;

  function getShares(address wallet) external view returns (uint256);

  function setShare(
    address shareholder,
    uint256 balanceUpdate,
    bool isRemoving
  ) external;
}

File 2 of 4 : LendingRewards.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

import './RewardsTracker.sol';

contract LendingRewards is RewardsTracker {
  constructor(address _token) RewardsTracker(_token) {}
}

File 3 of 4 : BokkyPooBahsDateTimeLibrary.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

// ----------------------------------------------------------------------------
// BokkyPooBah's DateTime Library v1.00
//
// A gas-efficient Solidity date and time library
//
// https://github.com/bokkypoobah/BokkyPooBahsDateTimeLibrary
//
// Tested date range 1970/01/01 to 2345/12/31
//
// Conventions:
// Unit      | Range         | Notes
// :-------- |:-------------:|:-----
// timestamp | >= 0          | Unix timestamp, number of seconds since 1970/01/01 00:00:00 UTC
// year      | 1970 ... 2345 |
// month     | 1 ... 12      |
// day       | 1 ... 31      |
// hour      | 0 ... 23      |
// minute    | 0 ... 59      |
// second    | 0 ... 59      |
// dayOfWeek | 1 ... 7       | 1 = Monday, ..., 7 = Sunday
//
//
// Enjoy. (c) BokkyPooBah / Bok Consulting Pty Ltd 2018.
//
// GNU Lesser General Public License 3.0
// https://www.gnu.org/licenses/lgpl-3.0.en.html
// ----------------------------------------------------------------------------

library BokkyPooBahsDateTimeLibrary {
  uint constant SECONDS_PER_DAY = 24 * 60 * 60;
  uint constant SECONDS_PER_HOUR = 60 * 60;
  uint constant SECONDS_PER_MINUTE = 60;
  int constant OFFSET19700101 = 2440588;

  uint constant DOW_MON = 1;
  uint constant DOW_TUE = 2;
  uint constant DOW_WED = 3;
  uint constant DOW_THU = 4;
  uint constant DOW_FRI = 5;
  uint constant DOW_SAT = 6;
  uint constant DOW_SUN = 7;

  // ------------------------------------------------------------------------
  // Calculate the number of days from 1970/01/01 to year/month/day using
  // the date conversion algorithm from
  //   http://aa.usno.navy.mil/faq/docs/JD_Formula.php
  // and subtracting the offset 2440588 so that 1970/01/01 is day 0
  //
  // days = day
  //      - 32075
  //      + 1461 * (year + 4800 + (month - 14) / 12) / 4
  //      + 367 * (month - 2 - (month - 14) / 12 * 12) / 12
  //      - 3 * ((year + 4900 + (month - 14) / 12) / 100) / 4
  //      - offset
  // ------------------------------------------------------------------------
  function _daysFromDate(
    uint year,
    uint month,
    uint day
  ) internal pure returns (uint _days) {
    require(year >= 1970);
    int _year = int(year);
    int _month = int(month);
    int _day = int(day);

    int __days = _day -
      32075 +
      (1461 * (_year + 4800 + (_month - 14) / 12)) /
      4 +
      (367 * (_month - 2 - ((_month - 14) / 12) * 12)) /
      12 -
      (3 * ((_year + 4900 + (_month - 14) / 12) / 100)) /
      4 -
      OFFSET19700101;

    _days = uint(__days);
  }

  // ------------------------------------------------------------------------
  // Calculate year/month/day from the number of days since 1970/01/01 using
  // the date conversion algorithm from
  //   http://aa.usno.navy.mil/faq/docs/JD_Formula.php
  // and adding the offset 2440588 so that 1970/01/01 is day 0
  //
  // int L = days + 68569 + offset
  // int N = 4 * L / 146097
  // L = L - (146097 * N + 3) / 4
  // year = 4000 * (L + 1) / 1461001
  // L = L - 1461 * year / 4 + 31
  // month = 80 * L / 2447
  // dd = L - 2447 * month / 80
  // L = month / 11
  // month = month + 2 - 12 * L
  // year = 100 * (N - 49) + year + L
  // ------------------------------------------------------------------------
  function _daysToDate(
    uint _days
  ) internal pure returns (uint year, uint month, uint day) {
    int __days = int(_days);

    int L = __days + 68569 + OFFSET19700101;
    int N = (4 * L) / 146097;
    L = L - (146097 * N + 3) / 4;
    int _year = (4000 * (L + 1)) / 1461001;
    L = L - (1461 * _year) / 4 + 31;
    int _month = (80 * L) / 2447;
    int _day = L - (2447 * _month) / 80;
    L = _month / 11;
    _month = _month + 2 - 12 * L;
    _year = 100 * (N - 49) + _year + L;

    year = uint(_year);
    month = uint(_month);
    day = uint(_day);
  }

  function timestampFromDate(
    uint year,
    uint month,
    uint day
  ) internal pure returns (uint timestamp) {
    timestamp = _daysFromDate(year, month, day) * SECONDS_PER_DAY;
  }

  function timestampFromDateTime(
    uint year,
    uint month,
    uint day,
    uint hour,
    uint minute,
    uint second
  ) internal pure returns (uint timestamp) {
    timestamp =
      _daysFromDate(year, month, day) *
      SECONDS_PER_DAY +
      hour *
      SECONDS_PER_HOUR +
      minute *
      SECONDS_PER_MINUTE +
      second;
  }

  function timestampToDate(
    uint timestamp
  ) internal pure returns (uint year, uint month, uint day) {
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
  }

  function timestampToDateTime(
    uint timestamp
  )
    internal
    pure
    returns (
      uint year,
      uint month,
      uint day,
      uint hour,
      uint minute,
      uint second
    )
  {
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    uint secs = timestamp % SECONDS_PER_DAY;
    hour = secs / SECONDS_PER_HOUR;
    secs = secs % SECONDS_PER_HOUR;
    minute = secs / SECONDS_PER_MINUTE;
    second = secs % SECONDS_PER_MINUTE;
  }

  function isValidDate(
    uint year,
    uint month,
    uint day
  ) internal pure returns (bool valid) {
    if (year >= 1970 && month > 0 && month <= 12) {
      uint daysInMonth = _getDaysInMonth(year, month);
      if (day > 0 && day <= daysInMonth) {
        valid = true;
      }
    }
  }

  function isValidDateTime(
    uint year,
    uint month,
    uint day,
    uint hour,
    uint minute,
    uint second
  ) internal pure returns (bool valid) {
    if (isValidDate(year, month, day)) {
      if (hour < 24 && minute < 60 && second < 60) {
        valid = true;
      }
    }
  }

  function isLeapYear(uint timestamp) internal pure returns (bool leapYear) {
    uint year;
    uint month;
    uint day;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    leapYear = _isLeapYear(year);
  }

  function _isLeapYear(uint year) internal pure returns (bool leapYear) {
    leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
  }

  function isWeekDay(uint timestamp) internal pure returns (bool weekDay) {
    weekDay = getDayOfWeek(timestamp) <= DOW_FRI;
  }

  function isWeekEnd(uint timestamp) internal pure returns (bool weekEnd) {
    weekEnd = getDayOfWeek(timestamp) >= DOW_SAT;
  }

  function getDaysInMonth(
    uint timestamp
  ) internal pure returns (uint daysInMonth) {
    uint year;
    uint month;
    uint day;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    daysInMonth = _getDaysInMonth(year, month);
  }

  function _getDaysInMonth(
    uint year,
    uint month
  ) internal pure returns (uint daysInMonth) {
    if (
      month == 1 ||
      month == 3 ||
      month == 5 ||
      month == 7 ||
      month == 8 ||
      month == 10 ||
      month == 12
    ) {
      daysInMonth = 31;
    } else if (month != 2) {
      daysInMonth = 30;
    } else {
      daysInMonth = _isLeapYear(year) ? 29 : 28;
    }
  }

  // 1 = Monday, 7 = Sunday
  function getDayOfWeek(uint timestamp) internal pure returns (uint dayOfWeek) {
    uint _days = timestamp / SECONDS_PER_DAY;
    dayOfWeek = ((_days + 3) % 7) + 1;
  }

  function getYear(uint timestamp) internal pure returns (uint year) {
    uint month;
    uint day;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
  }

  function getMonth(uint timestamp) internal pure returns (uint month) {
    uint year;
    uint day;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
  }

  function getDay(uint timestamp) internal pure returns (uint day) {
    uint year;
    uint month;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
  }

  function getHour(uint timestamp) internal pure returns (uint hour) {
    uint secs = timestamp % SECONDS_PER_DAY;
    hour = secs / SECONDS_PER_HOUR;
  }

  function getMinute(uint timestamp) internal pure returns (uint minute) {
    uint secs = timestamp % SECONDS_PER_HOUR;
    minute = secs / SECONDS_PER_MINUTE;
  }

  function getSecond(uint timestamp) internal pure returns (uint second) {
    second = timestamp % SECONDS_PER_MINUTE;
  }

  function addYears(
    uint timestamp,
    uint _years
  ) internal pure returns (uint newTimestamp) {
    uint year;
    uint month;
    uint day;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    year += _years;
    uint daysInMonth = _getDaysInMonth(year, month);
    if (day > daysInMonth) {
      day = daysInMonth;
    }
    newTimestamp =
      _daysFromDate(year, month, day) *
      SECONDS_PER_DAY +
      (timestamp % SECONDS_PER_DAY);
    require(newTimestamp >= timestamp);
  }

  function addMonths(
    uint timestamp,
    uint _months
  ) internal pure returns (uint newTimestamp) {
    uint year;
    uint month;
    uint day;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    month += _months;
    year += (month - 1) / 12;
    month = ((month - 1) % 12) + 1;
    uint daysInMonth = _getDaysInMonth(year, month);
    if (day > daysInMonth) {
      day = daysInMonth;
    }
    newTimestamp =
      _daysFromDate(year, month, day) *
      SECONDS_PER_DAY +
      (timestamp % SECONDS_PER_DAY);
    require(newTimestamp >= timestamp);
  }

  function addDays(
    uint timestamp,
    uint _days
  ) internal pure returns (uint newTimestamp) {
    newTimestamp = timestamp + _days * SECONDS_PER_DAY;
    require(newTimestamp >= timestamp);
  }

  function addHours(
    uint timestamp,
    uint _hours
  ) internal pure returns (uint newTimestamp) {
    newTimestamp = timestamp + _hours * SECONDS_PER_HOUR;
    require(newTimestamp >= timestamp);
  }

  function addMinutes(
    uint timestamp,
    uint _minutes
  ) internal pure returns (uint newTimestamp) {
    newTimestamp = timestamp + _minutes * SECONDS_PER_MINUTE;
    require(newTimestamp >= timestamp);
  }

  function addSeconds(
    uint timestamp,
    uint _seconds
  ) internal pure returns (uint newTimestamp) {
    newTimestamp = timestamp + _seconds;
    require(newTimestamp >= timestamp);
  }

  function subYears(
    uint timestamp,
    uint _years
  ) internal pure returns (uint newTimestamp) {
    uint year;
    uint month;
    uint day;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    year -= _years;
    uint daysInMonth = _getDaysInMonth(year, month);
    if (day > daysInMonth) {
      day = daysInMonth;
    }
    newTimestamp =
      _daysFromDate(year, month, day) *
      SECONDS_PER_DAY +
      (timestamp % SECONDS_PER_DAY);
    require(newTimestamp <= timestamp);
  }

  function subMonths(
    uint timestamp,
    uint _months
  ) internal pure returns (uint newTimestamp) {
    uint year;
    uint month;
    uint day;
    (year, month, day) = _daysToDate(timestamp / SECONDS_PER_DAY);
    uint yearMonth = year * 12 + (month - 1) - _months;
    year = yearMonth / 12;
    month = (yearMonth % 12) + 1;
    uint daysInMonth = _getDaysInMonth(year, month);
    if (day > daysInMonth) {
      day = daysInMonth;
    }
    newTimestamp =
      _daysFromDate(year, month, day) *
      SECONDS_PER_DAY +
      (timestamp % SECONDS_PER_DAY);
    require(newTimestamp <= timestamp);
  }

  function subDays(
    uint timestamp,
    uint _days
  ) internal pure returns (uint newTimestamp) {
    newTimestamp = timestamp - _days * SECONDS_PER_DAY;
    require(newTimestamp <= timestamp);
  }

  function subHours(
    uint timestamp,
    uint _hours
  ) internal pure returns (uint newTimestamp) {
    newTimestamp = timestamp - _hours * SECONDS_PER_HOUR;
    require(newTimestamp <= timestamp);
  }

  function subMinutes(
    uint timestamp,
    uint _minutes
  ) internal pure returns (uint newTimestamp) {
    newTimestamp = timestamp - _minutes * SECONDS_PER_MINUTE;
    require(newTimestamp <= timestamp);
  }

  function subSeconds(
    uint timestamp,
    uint _seconds
  ) internal pure returns (uint newTimestamp) {
    newTimestamp = timestamp - _seconds;
    require(newTimestamp <= timestamp);
  }

  function diffYears(
    uint fromTimestamp,
    uint toTimestamp
  ) internal pure returns (uint _years) {
    require(fromTimestamp <= toTimestamp);
    uint fromYear;
    uint fromMonth;
    uint fromDay;
    uint toYear;
    uint toMonth;
    uint toDay;
    (fromYear, fromMonth, fromDay) = _daysToDate(
      fromTimestamp / SECONDS_PER_DAY
    );
    (toYear, toMonth, toDay) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
    _years = toYear - fromYear;
  }

  function diffMonths(
    uint fromTimestamp,
    uint toTimestamp
  ) internal pure returns (uint _months) {
    require(fromTimestamp <= toTimestamp);
    uint fromYear;
    uint fromMonth;
    uint fromDay;
    uint toYear;
    uint toMonth;
    uint toDay;
    (fromYear, fromMonth, fromDay) = _daysToDate(
      fromTimestamp / SECONDS_PER_DAY
    );
    (toYear, toMonth, toDay) = _daysToDate(toTimestamp / SECONDS_PER_DAY);
    _months = toYear * 12 + toMonth - fromYear * 12 - fromMonth;
  }

  function diffDays(
    uint fromTimestamp,
    uint toTimestamp
  ) internal pure returns (uint _days) {
    require(fromTimestamp <= toTimestamp);
    _days = (toTimestamp - fromTimestamp) / SECONDS_PER_DAY;
  }

  function diffHours(
    uint fromTimestamp,
    uint toTimestamp
  ) internal pure returns (uint _hours) {
    require(fromTimestamp <= toTimestamp);
    _hours = (toTimestamp - fromTimestamp) / SECONDS_PER_HOUR;
  }

  function diffMinutes(
    uint fromTimestamp,
    uint toTimestamp
  ) internal pure returns (uint _minutes) {
    require(fromTimestamp <= toTimestamp);
    _minutes = (toTimestamp - fromTimestamp) / SECONDS_PER_MINUTE;
  }

  function diffSeconds(
    uint fromTimestamp,
    uint toTimestamp
  ) internal pure returns (uint _seconds) {
    require(fromTimestamp <= toTimestamp);
    _seconds = toTimestamp - fromTimestamp;
  }
}

File 4 of 4 : RewardsTracker.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.6;

import './interfaces/IRewardsTracker.sol';
import './libraries/BokkyPooBahsDateTimeLibrary.sol';

contract RewardsTracker is IRewardsTracker {
  uint256 constant MULTIPLIER = 10 ** 36;
  address public token;
  uint256 public totalStakedUsers;
  uint256 public totalSharesDeposited;

  struct Share {
    uint256 amount;
    uint256 stakedTime;
  }
  struct Reward {
    uint256 totalExcluded;
    uint256 totalRealized;
  }
  mapping(address => Share) private shares;
  mapping(address => Reward) public rewards;

  uint256 public rewardsPerShare;
  uint256 public totalDistributed;
  uint256 public totalRewards;
  mapping(uint256 => uint256) public monthlyRewards;

  event AddShares(address indexed user, uint256 amount);
  event RemoveShares(address indexed user, uint256 amount);
  event ClaimReward(address user);
  event DistributeReward(address indexed user, uint256 amount);
  event DepositRewards(address indexed user, uint256 amountTokens);

  modifier onlyToken() {
    require(msg.sender == token, 'ONLYTOKEN');
    _;
  }

  constructor(address _token) {
    token = _token;
  }

  function setShare(
    address shareholder,
    uint256 balanceUpdate,
    bool isRemoving
  ) public override onlyToken {
    _setShare(shareholder, balanceUpdate, isRemoving);
  }

  function _setShare(
    address shareholder,
    uint256 balanceUpdate,
    bool isRemoving
  ) internal {
    if (isRemoving) {
      _removeShares(shareholder, balanceUpdate);
      emit RemoveShares(shareholder, balanceUpdate);
    } else {
      _addShares(shareholder, balanceUpdate);
      emit AddShares(shareholder, balanceUpdate);
    }
  }

  function _addShares(address shareholder, uint256 amount) private {
    if (shares[shareholder].amount > 0) {
      _distributeReward(shareholder);
    }

    uint256 sharesBefore = shares[shareholder].amount;

    totalSharesDeposited += amount;
    shares[shareholder].amount += amount;
    shares[shareholder].stakedTime = block.timestamp;
    if (sharesBefore == 0 && shares[shareholder].amount > 0) {
      totalStakedUsers++;
    }
    rewards[shareholder].totalExcluded = _cumulativeRewards(
      shares[shareholder].amount
    );
  }

  function _removeShares(address shareholder, uint256 amount) private {
    require(
      shares[shareholder].amount > 0 && amount <= shares[shareholder].amount,
      'REMOVE: no shares'
    );
    _distributeReward(shareholder);

    totalSharesDeposited -= amount;
    shares[shareholder].amount -= amount;
    if (shares[shareholder].amount == 0) {
      totalStakedUsers--;
    }
    rewards[shareholder].totalExcluded = _cumulativeRewards(
      shares[shareholder].amount
    );
  }

  function depositRewards() external payable override {
    _depositRewards(msg.value);
  }

  function _depositRewards(uint256 _amount) internal {
    require(_amount > 0, 'DEPOSIT: no ETH');
    require(totalSharesDeposited > 0, 'DEPOSIT: no shares');

    totalRewards += _amount;
    uint256 _month = beginningOfMonth(block.timestamp);
    monthlyRewards[_month] += _amount;
    rewardsPerShare += (MULTIPLIER * _amount) / totalSharesDeposited;
    emit DepositRewards(msg.sender, _amount);
  }

  function _distributeReward(address shareholder) internal {
    if (shares[shareholder].amount == 0) {
      return;
    }

    uint256 amount = getUnpaid(shareholder);
    rewards[shareholder].totalRealized += amount;
    rewards[shareholder].totalExcluded = _cumulativeRewards(
      shares[shareholder].amount
    );

    if (amount > 0) {
      totalDistributed += amount;
      uint256 _balBefore = address(this).balance;
      (bool success, ) = payable(shareholder).call{ value: amount }('');
      require(success, 'DIST: could not distribute');
      require(address(this).balance >= _balBefore - amount, 'DIST: too much');
      emit DistributeReward(shareholder, amount);
    }
  }

  function claimReward() external override {
    _distributeReward(msg.sender);
    emit ClaimReward(msg.sender);
  }

  function getUnpaid(address shareholder) public view returns (uint256) {
    if (shares[shareholder].amount == 0) {
      return 0;
    }
    uint256 earnedRewards = _cumulativeRewards(shares[shareholder].amount);
    uint256 rewardsExcluded = rewards[shareholder].totalExcluded;
    if (earnedRewards <= rewardsExcluded) {
      return 0;
    }
    return earnedRewards - rewardsExcluded;
  }

  function beginningOfMonth(uint256 _timestamp) public view returns (uint256) {
    (, , uint256 _dayOfMonth) = BokkyPooBahsDateTimeLibrary.timestampToDate(
      _timestamp
    );
    return
      _timestamp - ((_dayOfMonth - 1) * 24 * 60 * 60) - (_timestamp % 1 days);
  }

  function _cumulativeRewards(uint256 share) internal view returns (uint256) {
    return (share * rewardsPerShare) / MULTIPLIER;
  }

  function getShares(address user) external view override returns (uint256) {
    return shares[user].amount;
  }
}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AddShares","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"user","type":"address"}],"name":"ClaimReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"}],"name":"DepositRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DistributeReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RemoveShares","type":"event"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"beginningOfMonth","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"depositRewards","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"}],"name":"getUnpaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"monthlyRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"totalExcluded","type":"uint256"},{"internalType":"uint256","name":"totalRealized","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsPerShare","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"shareholder","type":"address"},{"internalType":"uint256","name":"balanceUpdate","type":"uint256"},{"internalType":"bool","name":"isRemoving","type":"bool"}],"name":"setShare","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalDistributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSharesDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakedUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50604051610b68380380610b688339818101604052602081101561003357600080fd5b5051600080546001600160a01b039092166001600160a01b0319909216919091179055610b03806100656000396000f3fe6080604052600436106100dd5760003560e01c806389d969171161007f578063d076eabc11610059578063d076eabc14610251578063efca2eed1461027b578063f04da65b14610290578063fc0c546a146102c3576100dd565b806389d96917146101f4578063b88a802f14610227578063c7e1d0b11461023c576100dd565b8063152111f7116100bb578063152111f71461017f57806329cc05cf146101895780633c6e6789146101ca57806380bb4055146101df576100dd565b8063058df06d146100e25780630700037d1461011e5780630e15561a1461016a575b600080fd5b3480156100ee57600080fd5b5061010c6004803603602081101561010557600080fd5b50356102f4565b60408051918252519081900360200190f35b34801561012a57600080fd5b506101516004803603602081101561014157600080fd5b50356001600160a01b0316610306565b6040805192835260208301919091528051918290030190f35b34801561017657600080fd5b5061010c61031f565b610187610325565b005b34801561019557600080fd5b50610187600480360360608110156101ac57600080fd5b506001600160a01b0381351690602081013590604001351515610330565b3480156101d657600080fd5b5061010c61038b565b3480156101eb57600080fd5b5061010c610391565b34801561020057600080fd5b5061010c6004803603602081101561021757600080fd5b50356001600160a01b0316610397565b34801561023357600080fd5b50610187610416565b34801561024857600080fd5b5061010c610454565b34801561025d57600080fd5b5061010c6004803603602081101561027457600080fd5b503561045a565b34801561028757600080fd5b5061010c61048f565b34801561029c57600080fd5b5061010c600480360360208110156102b357600080fd5b50356001600160a01b0316610495565b3480156102cf57600080fd5b506102d86104b0565b604080516001600160a01b039092168252519081900360200190f35b60086020526000908152604090205481565b6004602052600090815260409020805460019091015482565b60075481565b61032e346104bf565b565b6000546001600160a01b0316331461037b576040805162461bcd60e51b815260206004820152600960248201526827a7262caa27a5a2a760b91b604482015290519081900360640190fd5b6103868383836105e0565b505050565b60025481565b60015481565b6001600160a01b0381166000908152600360205260408120546103bc57506000610411565b6001600160a01b0382166000908152600360205260408120546103de90610682565b6001600160a01b03841660009081526004602052604090205490915080821161040c57600092505050610411565b900390505b919050565b61041f336106a7565b6040805133815290517f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e89181900360200190a1565b60055481565b6000806104668361086a565b9250505062015180838161047657fe5b0662015180600019909201919091028303039050919050565b60065481565b6001600160a01b031660009081526003602052604090205490565b6000546001600160a01b031681565b60008111610506576040805162461bcd60e51b815260206004820152600f60248201526e0888aa09ea692a87440dcde408aa89608b1b604482015290519081900360640190fd5b600060025411610552576040805162461bcd60e51b81526020600482015260126024820152714445504f5349543a206e6f2073686172657360701b604482015290519081900360640190fd5b600780548201905560006105654261045a565b60008181526008602052604090208054840190556002549091506ec097ce7bc90715b34b9f100000000083028161059857fe5b600580549290910491909101905560408051838152905133917fb9ad861b752f80117b35bea6dec99933d8a5ae360f2839ee8784b750d5613409919081900360200190a25050565b8015610634576105f08383610889565b6040805183815290516001600160a01b038516917fae0577e1c96b26fbc0b9df702431f5470979d001d24f136eded791b8b6521d6f919081900360200190a2610386565b61063e8383610991565b6040805183815290516001600160a01b038516917fba8f3777cf908803bf1f3dd58e7f4b7d3de4dbe3c234c4ccab0975d98f7cd388919081900360200190a2505050565b60006ec097ce7bc90715b34b9f10000000006005548302816106a057fe5b0492915050565b6001600160a01b0381166000908152600360205260409020546106c957610867565b60006106d482610397565b6001600160a01b0383166000908152600460209081526040808320600101805485019055600390915290205490915061070c90610682565b6001600160a01b038316600090815260046020526040902055801561086557600680548201905560405147906000906001600160a01b0385169084908381818185875af1925050503d8060008114610780576040519150601f19603f3d011682016040523d82523d6000602084013e610785565b606091505b50509050806107db576040805162461bcd60e51b815260206004820152601a60248201527f444953543a20636f756c64206e6f742064697374726962757465000000000000604482015290519081900360640190fd5b828203471015610823576040805162461bcd60e51b815260206004820152600e60248201526d08892a6a87440e8dede40daeac6d60931b604482015290519081900360640190fd5b6040805184815290516001600160a01b038616917fe8b160e373db99a103e0a2abfa029b9c3fc8b328984a1ead8a65ae68ae646db7919081900360200190a250505b505b50565b6000808061087c620151808504610a60565b9196909550909350915050565b6001600160a01b038216600090815260036020526040902054158015906108c857506001600160a01b0382166000908152600360205260409020548111155b61090d576040805162461bcd60e51b815260206004820152601160248201527052454d4f56453a206e6f2073686172657360781b604482015290519081900360640190fd5b610916826106a7565b6002805482900390556001600160a01b038216600090815260036020526040902080548290039081905561094f57600180546000190190555b6001600160a01b03821660009081526003602052604090205461097190610682565b6001600160a01b0390921660009081526004602052604090209190915550565b6001600160a01b038216600090815260036020526040902054156109b8576109b8826106a7565b6001600160a01b0382166000908152600360205260409020805460028054840190558154830182554260019092019190915580158015610a0f57506001600160a01b03831660009081526003602052604090205415155b15610a1d5760018054810190555b6001600160a01b038316600090815260036020526040902054610a3f90610682565b6001600160a01b039093166000908152600460205260409020929092555050565b60008080836226496581018262023ab1600483020590506004600362023ab18302010590910390600062164b09610fa0600185010205905060046105b58202058303601f019250600061098f8460500281610ab757fe5b0590506000605061098f83020585039050600b820560301994909401606402929092018301996002600c9094029091039290920197509550935050505056fea164736f6c6343000706000a00000000000000000000000085225ed797fd4128ac45a992c46ea4681a7a15da

Deployed Bytecode

0x6080604052600436106100dd5760003560e01c806389d969171161007f578063d076eabc11610059578063d076eabc14610251578063efca2eed1461027b578063f04da65b14610290578063fc0c546a146102c3576100dd565b806389d96917146101f4578063b88a802f14610227578063c7e1d0b11461023c576100dd565b8063152111f7116100bb578063152111f71461017f57806329cc05cf146101895780633c6e6789146101ca57806380bb4055146101df576100dd565b8063058df06d146100e25780630700037d1461011e5780630e15561a1461016a575b600080fd5b3480156100ee57600080fd5b5061010c6004803603602081101561010557600080fd5b50356102f4565b60408051918252519081900360200190f35b34801561012a57600080fd5b506101516004803603602081101561014157600080fd5b50356001600160a01b0316610306565b6040805192835260208301919091528051918290030190f35b34801561017657600080fd5b5061010c61031f565b610187610325565b005b34801561019557600080fd5b50610187600480360360608110156101ac57600080fd5b506001600160a01b0381351690602081013590604001351515610330565b3480156101d657600080fd5b5061010c61038b565b3480156101eb57600080fd5b5061010c610391565b34801561020057600080fd5b5061010c6004803603602081101561021757600080fd5b50356001600160a01b0316610397565b34801561023357600080fd5b50610187610416565b34801561024857600080fd5b5061010c610454565b34801561025d57600080fd5b5061010c6004803603602081101561027457600080fd5b503561045a565b34801561028757600080fd5b5061010c61048f565b34801561029c57600080fd5b5061010c600480360360208110156102b357600080fd5b50356001600160a01b0316610495565b3480156102cf57600080fd5b506102d86104b0565b604080516001600160a01b039092168252519081900360200190f35b60086020526000908152604090205481565b6004602052600090815260409020805460019091015482565b60075481565b61032e346104bf565b565b6000546001600160a01b0316331461037b576040805162461bcd60e51b815260206004820152600960248201526827a7262caa27a5a2a760b91b604482015290519081900360640190fd5b6103868383836105e0565b505050565b60025481565b60015481565b6001600160a01b0381166000908152600360205260408120546103bc57506000610411565b6001600160a01b0382166000908152600360205260408120546103de90610682565b6001600160a01b03841660009081526004602052604090205490915080821161040c57600092505050610411565b900390505b919050565b61041f336106a7565b6040805133815290517f63e32091e4445d16e29c33a6b264577c2d86694021aa4e6f4dd590048f5792e89181900360200190a1565b60055481565b6000806104668361086a565b9250505062015180838161047657fe5b0662015180600019909201919091028303039050919050565b60065481565b6001600160a01b031660009081526003602052604090205490565b6000546001600160a01b031681565b60008111610506576040805162461bcd60e51b815260206004820152600f60248201526e0888aa09ea692a87440dcde408aa89608b1b604482015290519081900360640190fd5b600060025411610552576040805162461bcd60e51b81526020600482015260126024820152714445504f5349543a206e6f2073686172657360701b604482015290519081900360640190fd5b600780548201905560006105654261045a565b60008181526008602052604090208054840190556002549091506ec097ce7bc90715b34b9f100000000083028161059857fe5b600580549290910491909101905560408051838152905133917fb9ad861b752f80117b35bea6dec99933d8a5ae360f2839ee8784b750d5613409919081900360200190a25050565b8015610634576105f08383610889565b6040805183815290516001600160a01b038516917fae0577e1c96b26fbc0b9df702431f5470979d001d24f136eded791b8b6521d6f919081900360200190a2610386565b61063e8383610991565b6040805183815290516001600160a01b038516917fba8f3777cf908803bf1f3dd58e7f4b7d3de4dbe3c234c4ccab0975d98f7cd388919081900360200190a2505050565b60006ec097ce7bc90715b34b9f10000000006005548302816106a057fe5b0492915050565b6001600160a01b0381166000908152600360205260409020546106c957610867565b60006106d482610397565b6001600160a01b0383166000908152600460209081526040808320600101805485019055600390915290205490915061070c90610682565b6001600160a01b038316600090815260046020526040902055801561086557600680548201905560405147906000906001600160a01b0385169084908381818185875af1925050503d8060008114610780576040519150601f19603f3d011682016040523d82523d6000602084013e610785565b606091505b50509050806107db576040805162461bcd60e51b815260206004820152601a60248201527f444953543a20636f756c64206e6f742064697374726962757465000000000000604482015290519081900360640190fd5b828203471015610823576040805162461bcd60e51b815260206004820152600e60248201526d08892a6a87440e8dede40daeac6d60931b604482015290519081900360640190fd5b6040805184815290516001600160a01b038616917fe8b160e373db99a103e0a2abfa029b9c3fc8b328984a1ead8a65ae68ae646db7919081900360200190a250505b505b50565b6000808061087c620151808504610a60565b9196909550909350915050565b6001600160a01b038216600090815260036020526040902054158015906108c857506001600160a01b0382166000908152600360205260409020548111155b61090d576040805162461bcd60e51b815260206004820152601160248201527052454d4f56453a206e6f2073686172657360781b604482015290519081900360640190fd5b610916826106a7565b6002805482900390556001600160a01b038216600090815260036020526040902080548290039081905561094f57600180546000190190555b6001600160a01b03821660009081526003602052604090205461097190610682565b6001600160a01b0390921660009081526004602052604090209190915550565b6001600160a01b038216600090815260036020526040902054156109b8576109b8826106a7565b6001600160a01b0382166000908152600360205260409020805460028054840190558154830182554260019092019190915580158015610a0f57506001600160a01b03831660009081526003602052604090205415155b15610a1d5760018054810190555b6001600160a01b038316600090815260036020526040902054610a3f90610682565b6001600160a01b039093166000908152600460205260409020929092555050565b60008080836226496581018262023ab1600483020590506004600362023ab18302010590910390600062164b09610fa0600185010205905060046105b58202058303601f019250600061098f8460500281610ab757fe5b0590506000605061098f83020585039050600b820560301994909401606402929092018301996002600c9094029091039290920197509550935050505056fea164736f6c6343000706000a

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000085225ed797fd4128ac45a992c46ea4681a7a15da

-----Decoded View---------------
Arg [0] : _token (address): 0x85225Ed797fd4128Ac45A992C46eA4681a7A15dA

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000085225ed797fd4128ac45a992c46ea4681a7a15da


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.