ETH Price: $2,619.12 (+0.77%)

Contract

0x7827cA5dB933635bad77Aa52C837Ee98BeB1206D
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Stake197412052024-04-26 18:07:11174 days ago1714154831IN
Egg.fi: Staking
0 ETH0.001193195.53164931
Stake197282182024-04-24 22:30:23176 days ago1713997823IN
Egg.fi: Staking
0 ETH0.001467888.01554626
Unstake197281062024-04-24 22:07:47176 days ago1713996467IN
Egg.fi: Staking
0 ETH0.0009561610.05920502
Stake197056592024-04-21 18:46:23179 days ago1713725183IN
Egg.fi: Staking
0 ETH0.001393927.61118021
Unstake197055952024-04-21 18:33:35179 days ago1713724415IN
Egg.fi: Staking
0 ETH0.000665958.54165231
Unstake194251882024-03-13 9:14:23219 days ago1710321263IN
Egg.fi: Staking
0 ETH0.0086198990.67274888
Unstake191461032024-02-03 6:39:59258 days ago1706942399IN
Egg.fi: Staking
0 ETH0.0012073915.48618043
Stake190569862024-01-21 18:20:23270 days ago1705861223IN
Egg.fi: Staking
0 ETH0.0037960516.84850662
Unstake190569492024-01-21 18:11:59270 days ago1705860719IN
Egg.fi: Staking
0 ETH0.0012138815.56941309
Unstake190568742024-01-21 17:56:47270 days ago1705859807IN
Egg.fi: Staking
0 ETH0.0012114215.53788659
Unstake185473022023-11-11 7:48:59342 days ago1699688939IN
Egg.fi: Staking
0 ETH0.0017429121.05839703
Stake184068592023-10-22 15:55:23361 days ago1697990123IN
Egg.fi: Staking
0 ETH0.0023213512.35144433
Unstake184068002023-10-22 15:43:23361 days ago1697989403IN
Egg.fi: Staking
0 ETH0.0015348219.68584883
Stake181616432023-09-18 8:27:23396 days ago1695025643IN
Egg.fi: Staking
0 ETH0.00191638.50536683
Stake181194022023-09-12 9:37:23402 days ago1694511443IN
Egg.fi: Staking
0 ETH0.0017210.35883305
Unstake181191682023-09-12 8:49:59402 days ago1694508599IN
Egg.fi: Staking
0 ETH0.0010596210.61042482
Stake179425072023-08-18 15:16:59426 days ago1692371819IN
Egg.fi: Staking
0 ETH0.0104275546.28442996
Unstake178614652023-08-07 7:07:23438 days ago1691392043IN
Egg.fi: Staking
0 ETH0.0011789214.24408241
Unstake177673692023-07-25 3:15:23451 days ago1690254923IN
Egg.fi: Staking
0 ETH0.0018476723.77530145
Stake173063272023-05-21 7:41:11516 days ago1684654871IN
Egg.fi: Staking
0 ETH0.005339628.41090466
Stake173062912023-05-21 7:33:59516 days ago1684654439IN
Egg.fi: Staking
0 ETH0.0052590827.98251125
Unstake173046042023-05-21 1:51:47516 days ago1684633907IN
Egg.fi: Staking
0 ETH0.0019563525.09247178
Stake171502952023-04-29 7:32:59538 days ago1682753579IN
Egg.fi: Staking
0 ETH0.0051165130.81456749
Unstake171501662023-04-29 7:06:59538 days ago1682752019IN
Egg.fi: Staking
0 ETH0.0029038835.08552718
Stake170610512023-04-16 17:55:23550 days ago1681667723IN
Egg.fi: Staking
0 ETH0.0044549523.70389218
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Staking

Compiler Version
v0.7.0+commit.9e61f92b

Optimization Enabled:
No with 200 runs

Other Settings:
byzantium EvmVersion
File 1 of 8 : Staking.sol
// SPDX-License-Identifier: Apache license 2.0

pragma solidity ^0.7.0;

import "../token/ERC20Mintable.sol";
import "../interfaces/IStaking.sol";
import "../libraries/SafeMathUint.sol";
import "../utils/Context.sol";
import "../utils/Ownable.sol";

/**
 * @dev Implementation of the {IStaking} interface.
 *
 * Provides a set of operations to enable staking of the {ERC20Mintable} token.
 */
contract Staking is IStaking, Context, Ownable {
  using SafeMathUint for uint256;

  ERC20Mintable _stakingToken;

  // To save on gas, rather than create a separate mapping for totalStakedFor & personalStakes,
  // both data structures are stored in a single mapping for a given addresses.
  // It's possible to have a non-existing personalStakes, but have tokens in totalStakedFor
  // if other users are staking on behalf of a given address.
  mapping(address => StakeContract) public _stakeHolders;
  mapping(uint256 => StakeOption[]) private _stakeOptions;
  uint256 private _currentStakeOptionArrayIndex;

  // Struct for staking options
  // stakeDuration - seconds to pass before the stake unlocks
  // stakePercentageBasisPoints - the staking reward percentage (basis points)
  struct StakeOption {
    uint256 stakeDuration;
    uint16 stakePercentageBasisPoints;
  }

  // Struct for personal stakes (i.e., stakes made by this address)
  // unlockedTimestamp - when the stake unlocks (in seconds since Unix epoch)
  // actualAmount - the amount of tokens in the stake
  // stakedFor - the address the stake was staked for
  struct Stake {
    uint256 unlockedTimestamp;
    uint256 actualAmount;
    address stakedFor;
    uint256 stakePercentageBasisPoints;
  }

  // Struct for all stake metadata at a particular address
  // totalStakedFor - the number of tokens staked for this address
  // personalStakesLastIndex - index of the last stake in the personalStakes mapping
  // personalStakes - append only mapping of stakes made by this address
  // exists - whether or not there are stakes that involve this address
  struct StakeContract {
    uint256 totalStakedFor;
    uint256 personalStakesLastIndex;
    mapping(uint256 => Stake) personalStakes;
    bool exists;
  }

  /**
   * @dev Sets the {ERC20Mintable} staking token.
   */
  constructor(ERC20Mintable stakingToken) {
    _stakingToken = stakingToken;
  }

  /**
   * @dev See {IStaking-setStakingOptions}
   *
   * Requirements:
   *
   * - `stakeDurations` and `stakePercentageBasisPoints` arrays passed to
   * this function cannot be empty or have a different length.
   */
  function setStakingOptions(
    uint256[] memory stakeDurations,
    uint16[] memory stakePercentageBasisPoints
  ) external override onlyOwner {
    require(
      stakeDurations.length == stakePercentageBasisPoints.length && stakeDurations.length > 0,
      "Staking: stake duration and percentage basis points arrays should be equal in size and non-empty"
    );

    _currentStakeOptionArrayIndex = _currentStakeOptionArrayIndex.add(1);
    for (uint256 i = 0; i < stakeDurations.length; i++) {
      _stakeOptions[_currentStakeOptionArrayIndex].push(
        StakeOption(stakeDurations[i], stakePercentageBasisPoints[i])
      );
    }
  }

  /**
   * @dev See {IStaking-getStakingOptions}
   */
  function getStakingOptions()
    external
    override
    view
    returns (
      uint256[] memory stakeOptionIndexes,
      uint256[] memory stakeDurations,
      uint16[] memory stakePercentageBasisPoints
    )
  {
    stakeOptionIndexes = new uint256[](_stakeOptions[_currentStakeOptionArrayIndex].length);
    stakeDurations = new uint256[](_stakeOptions[_currentStakeOptionArrayIndex].length);
    stakePercentageBasisPoints = new uint16[](_stakeOptions[_currentStakeOptionArrayIndex].length);

    for (uint256 i = 0; i < _stakeOptions[_currentStakeOptionArrayIndex].length; i++) {
      stakeOptionIndexes[i] = i;
      stakeDurations[i] = _stakeOptions[_currentStakeOptionArrayIndex][i].stakeDuration;
      stakePercentageBasisPoints[i] = _stakeOptions[_currentStakeOptionArrayIndex][i]
        .stakePercentageBasisPoints;
    }

    return (stakeOptionIndexes, stakeDurations, stakePercentageBasisPoints);
  }

  /**
   * @dev See {IStaking-getPersonalStakeIndexes}
   */
  function getPersonalStakeIndexes(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external override view returns (uint256[] memory) {
    uint256[] memory indexes;
    (indexes, , , , ) = getPersonalStakes(user, amountToRetrieve, offset);

    return indexes;
  }

  /**
   * @dev See {IStaking-getPersonalStakeUnlockedTimestamps}
   */
  function getPersonalStakeUnlockedTimestamps(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external override view returns (uint256[] memory) {
    uint256[] memory timestamps;
    (, timestamps, , , ) = getPersonalStakes(user, amountToRetrieve, offset);

    return timestamps;
  }

  /**
   * @dev See {IStaking-getPersonalStakeActualAmounts}
   */
  function getPersonalStakeActualAmounts(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external override view returns (uint256[] memory) {
    uint256[] memory actualAmounts;
    (, , actualAmounts, , ) = getPersonalStakes(user, amountToRetrieve, offset);

    return actualAmounts;
  }

  /**
   * @dev See {IStaking-getPersonalStakeForAddresses}
   */
  function getPersonalStakeForAddresses(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external override view returns (address[] memory) {
    address[] memory stakedFor;
    (, , , stakedFor, ) = getPersonalStakes(user, amountToRetrieve, offset);

    return stakedFor;
  }

  /**
   * @dev See {IStaking-getPersonalStakePercentageBasisPoints}
   */
  function getPersonalStakePercentageBasisPoints(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external override view returns (uint256[] memory) {
    uint256[] memory stakePercentageBasisPoints;
    (, , , , stakePercentageBasisPoints) = getPersonalStakes(user, amountToRetrieve, offset);

    return stakePercentageBasisPoints;
  }

  /**
   * @dev Helper function to get specific properties of all of the personal stakes created by the `user`
   * @param user address The address to query
   * @return (uint256[], uint256[], address[], uint256[] memory)
   *  timestamps array, actualAmounts array, stakedFor array, stakePercentageBasisPoints array
   */
  function getPersonalStakes(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  )
    public
    view
    returns (
      uint256[] memory,
      uint256[] memory,
      uint256[] memory,
      address[] memory,
      uint256[] memory
    )
  {
    StakeContract storage stakeContract = _stakeHolders[user];

    uint256 offsetStakeAmount = stakeContract.personalStakesLastIndex.sub(offset);
    if (amountToRetrieve > offsetStakeAmount) {
      amountToRetrieve = offsetStakeAmount;
    }
    uint256[] memory stakeIndexes = new uint256[](amountToRetrieve);
    uint256[] memory unlockedTimestamps = new uint256[](amountToRetrieve);
    uint256[] memory actualAmounts = new uint256[](amountToRetrieve);
    address[] memory stakedFor = new address[](amountToRetrieve);
    uint256[] memory stakePercentageBasisPoints = new uint256[](amountToRetrieve);

    uint256 retrieved;
    for (uint256 i = stakeContract.personalStakesLastIndex.sub(1).sub(offset); i >= 0; i--) {
      stakeIndexes[retrieved] = i;
      unlockedTimestamps[retrieved] = stakeContract.personalStakes[i].unlockedTimestamp;
      actualAmounts[retrieved] = stakeContract.personalStakes[i].actualAmount;
      stakedFor[retrieved] = stakeContract.personalStakes[i].stakedFor;
      stakePercentageBasisPoints[retrieved] = stakeContract.personalStakes[i]
        .stakePercentageBasisPoints;

      if (++retrieved >= amountToRetrieve) {
        break;
      }
    }

    return (stakeIndexes, unlockedTimestamps, actualAmounts, stakedFor, stakePercentageBasisPoints);
  }

  /**
   * @dev See {IStaking-stake}
   */
  function stake(
    uint8 stakeOptionIndex,
    uint256 amount,
    bytes calldata data
  ) external override validStakeOption(stakeOptionIndex) {
    createStake(
      _msgSender(),
      amount,
      _stakeOptions[_currentStakeOptionArrayIndex][stakeOptionIndex].stakeDuration,
      _stakeOptions[_currentStakeOptionArrayIndex][stakeOptionIndex].stakePercentageBasisPoints,
      data
    );
  }

  /**
   * @dev See {IStaking-stakeFor}
   */
  function stakeFor(
    uint8 stakeOptionIndex,
    address user,
    uint256 amount,
    bytes calldata data
  ) public override validStakeOption(stakeOptionIndex) {
    createStake(
      user,
      amount,
      _stakeOptions[_currentStakeOptionArrayIndex][stakeOptionIndex].stakeDuration,
      _stakeOptions[_currentStakeOptionArrayIndex][stakeOptionIndex].stakePercentageBasisPoints,
      data
    );
  }

  /**
   * @dev See {IStaking-unstake}
   */
  function unstake(uint256 personalStakeIndex, bytes calldata data) external override {
    withdrawStake(personalStakeIndex, data);
  }

  /**
   * @dev See {IStaking-totalStakedFor}
   */
  function totalStakedFor(address user) public override view returns (uint256) {
    return _stakeHolders[user].totalStakedFor;
  }

  /**
   * @dev See {IStaking-totalStaked}
   */
  function totalStaked() external override view returns (uint256) {
    return _stakingToken.balanceOf(address(this));
  }

  /**
   * @dev See {IStaking-token}
   */
  function token() external override view returns (address) {
    return address(_stakingToken);
  }

  /**
   * @dev See {IStaking-supportsHistory}
   *
   * Since we don't implement the optional interface, this always returns false
   */
  function supportsHistory() external override pure returns (bool) {
    return false;
  }

  /**
   * @dev Helper function to create stakes for a given address
   * @param user address The address the stake is being created for
   * @param amount uint256 The number of tokens being staked
   * @param lockInDuration uint256 The duration to lock the tokens for
   * @param data bytes optional data to include in the Stake event
   * @param stakePercentageBasisPoints uint16 stake reward percentage (basis points)
   *
   * Requirements:
   *
   * - `_stakingToken` allowance should be granted to {Staking} contract
   * address in order for the stake creation to be successful.
   */
  function createStake(
    address user,
    uint256 amount,
    uint256 lockInDuration,
    uint16 stakePercentageBasisPoints,
    bytes calldata data
  ) internal {
    require(
      _stakingToken.transferFrom(_msgSender(), address(this), amount),
      "Staking: stake required"
    );

    if (!_stakeHolders[user].exists) {
      _stakeHolders[user].exists = true;
    }

    uint256 unlockedTimestamp = block.timestamp.add(lockInDuration);
    _stakeHolders[user].totalStakedFor = _stakeHolders[user].totalStakedFor.add(amount);
    _stakeHolders[user].personalStakes[_stakeHolders[user].personalStakesLastIndex] = Stake({
      unlockedTimestamp: unlockedTimestamp,
      actualAmount: amount,
      stakedFor: user,
      stakePercentageBasisPoints: stakePercentageBasisPoints
    });

    emit LogStaked(
      user,
      amount,
      _stakeHolders[user].personalStakesLastIndex,
      unlockedTimestamp,
      stakePercentageBasisPoints,
      totalStakedFor(user),
      data
    );
    _stakeHolders[user].personalStakesLastIndex = _stakeHolders[user].personalStakesLastIndex.add(
      1
    );
  }

  /**
   * @dev Helper function to withdraw stakes for the msg.sender
   * @param personalStakeIndex uint256 index of the stake to withdraw in the personalStakes mapping
   * @param data bytes optional data to include in the Unstake event
   *
   * Requirements:
   *
   * - valid personal stake index is passed.
   * - stake should not be already withdrawn.
   * - `_stakingToken` should transfer the stake amount successfully.
   * - `_stakingToken` should {mint} the stake reward successfully
   * if function is called after the stake's `unlockTimestamp`.
   */
  function withdrawStake(uint256 personalStakeIndex, bytes calldata data) internal {
    require(
      personalStakeIndex <= _stakeHolders[_msgSender()].personalStakesLastIndex.sub(1),
      "Staking: passed the wrong personal stake index"
    );

    Stake storage personalStake = _stakeHolders[_msgSender()].personalStakes[personalStakeIndex];

    require(personalStake.actualAmount > 0, "Staking: already withdrawn this stake");

    require(
      _stakingToken.transfer(_msgSender(), personalStake.actualAmount),
      "Staking: unable to withdraw the stake"
    );

    uint256 stakeReward = 0;
    if (personalStake.unlockedTimestamp <= block.timestamp) {
      stakeReward = personalStake.actualAmount.mul(personalStake.stakePercentageBasisPoints).div(
        uint256(10000)
      );
      require(
        _stakingToken.mint(_msgSender(), stakeReward),
        "Staking: unable to mint the stake reward"
      );
    }

    _stakeHolders[personalStake.stakedFor].totalStakedFor = _stakeHolders[personalStake.stakedFor]
      .totalStakedFor
      .sub(personalStake.actualAmount);

    emit LogUnstaked(
      personalStake.stakedFor,
      personalStake.actualAmount,
      personalStakeIndex,
      stakeReward,
      totalStakedFor(personalStake.stakedFor),
      data
    );

    personalStake.actualAmount = 0;
  }

  /**
   * @dev Modifier that checks if passed `stakeOptionIndex` is valid.
   *
   * Requirements:
   *
   * - `_stakeOptions[_currentStakeOptionArrayIndex]` should not be empty,
   * which means there are valid staking options at the moment.
   * - `stakeOptionIndex` should be a valid index of any stake option
   * in `_stakeOptions[_currentStakeOptionArrayIndex]`.
   */
  modifier validStakeOption(uint8 stakeOptionIndex) {
    require(
      _currentStakeOptionArrayIndex > 0 && _stakeOptions[_currentStakeOptionArrayIndex].length > 0,
      "Staking: no available staking options at the moment."
    );
    require(
      stakeOptionIndex < _stakeOptions[_currentStakeOptionArrayIndex].length,
      "Staking: passed a non-valid stake option index."
    );
    _;
  }
}

File 2 of 8 : IERC20.sol
// SPDX-License-Identifier: Apache license 2.0

pragma solidity ^0.7.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
  /**
   * @dev Emitted when `value` tokens are moved from one account (`from`) to
   * another (`to`).
   *
   * Note that `value` may be zero.
   */
  event Transfer(address indexed from, address indexed to, uint256 value);

  /**
   * @dev Emitted when the allowance of a `spender` for an `owner` is set by
   * a call to {approve}. `value` is the new allowance.
   */
  event Approval(address indexed owner, address indexed spender, uint256 value);

  /**
   * @dev Returns the amount of tokens in existence.
   */
  function totalSupply() external view returns (uint256);

  /**
   * @dev Returns the amount of tokens owned by `account`.
   */
  function balanceOf(address account) external view returns (uint256);

  /**
   * @dev Moves `amount` tokens from the caller's account to `recipient`.
   *
   * Returns a boolean value indicating whether the operation succeeded.
   *
   * Emits a {Transfer} event.
   */
  function transfer(address recipient, uint256 amount) external returns (bool);

  /**
   * @dev Returns the remaining number of tokens that `spender` will be
   * allowed to spend on behalf of `owner` through {transferFrom}. This is
   * zero by default.
   *
   * This value changes when {approve} or {transferFrom} are called.
   */
  function allowance(address owner, address spender) external view returns (uint256);

  /**
   * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
   *
   * Returns a boolean value indicating whether the operation succeeded.
   *
   * IMPORTANT: Beware that changing an allowance with this method brings the risk
   * that someone may use both the old and the new allowance by unfortunate
   * transaction ordering. One possible solution to mitigate this race
   * condition is to first reduce the spender's allowance to 0 and set the
   * desired value afterwards:
   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   *
   * Emits an {Approval} event.
   */
  function approve(address spender, uint256 amount) external returns (bool);

  /**
   * @dev Moves `amount` tokens from `sender` to `recipient` using the
   * allowance mechanism. `amount` is then deducted from the caller's
   * allowance.
   *
   * Returns a boolean value indicating whether the operation succeeded.
   *
   * Emits a {Transfer} event.
   */
  function transferFrom(
    address sender,
    address recipient,
    uint256 amount
  ) external returns (bool);
}

File 3 of 8 : IStaking.sol
// SPDX-License-Identifier: Apache license 2.0

pragma solidity ^0.7.0;

/**
 * @dev Interface of the ERC900 standard with custom modifications.
 *
 * See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-900.md
 */
interface IStaking {
  /**
   * @dev Emitted when the `user` stakes an `amount` of tokens and
   * passes arbitrary `data`, therefore `total` is changed as well,
   * `personalStakeIndex`, `unlockedTimestamp` and `stakePercentageBasisPoints` are captured
   * according to the chosen stake option.
   */
  event LogStaked(
    address indexed user,
    uint256 amount,
    uint256 personalStakeIndex,
    uint256 unlockedTimestamp,
    uint16 stakePercentageBasisPoints,
    uint256 total,
    bytes data
  );

  /**
   * @dev Emitted when the `user` unstakes an `amount` of tokens and
   * passes arbitrary `data`, therefore `total` is changed as well,
   * `personalStakeIndex` and `stakeReward` are captured.
   */
  event LogUnstaked(
    address indexed user,
    uint256 amount,
    uint256 personalStakeIndex,
    uint256 stakeReward,
    uint256 total,
    bytes data
  );

  /**
   * @notice Stakes a certain amount of tokens, this MUST transfer the given amount from the user
   * @notice MUST trigger Staked event
   * @param stakeOptionIndex uint8 the chosen stake option
   * @param amount uint256 the amount of tokens to stake
   * @param data bytes optional data to include in the Stake event
   */
  function stake(
    uint8 stakeOptionIndex,
    uint256 amount,
    bytes calldata data
  ) external;

  /**
   * @notice Stakes a certain amount of tokens, this MUST transfer the given amount from the caller
   * @notice MUST trigger Staked event
   * @param stakeOptionIndex uint8 the chosen stake option
   * @param user address the address the tokens are staked for
   * @param amount uint256 the amount of tokens to stake
   * @param data bytes optional data to include in the Stake event
   */
  function stakeFor(
    uint8 stakeOptionIndex,
    address user,
    uint256 amount,
    bytes calldata data
  ) external;

  /**
   * @notice Unstakes tokens, this SHOULD return the given amount of tokens to the user,
   * if unstaking is currently not possible the function MUST revert
   * @notice MUST trigger Unstaked event
   * @dev Unstaking tokens is an atomic operation—either all of the tokens in a stake, or none of the tokens.
   * @dev Stake reward is minted if function is called after the stake's `unlockTimestamp`.
   * @param personalStakeIndex uint256 index of the stake to withdraw in the personalStakes mapping
   * @param data bytes optional data to include in the Unstake event
   */
  function unstake(uint256 personalStakeIndex, bytes calldata data) external;

  /**
   * @notice Returns the current total of tokens staked for an address
   * @param addr address The address to query
   * @return uint256 The number of tokens staked for the given address
   */
  function totalStakedFor(address addr) external view returns (uint256);

  /**
   * @notice Returns the current total of tokens staked
   * @return uint256 The number of tokens staked in the contract
   */
  function totalStaked() external view returns (uint256);

  /**
   * @notice Address of the token being used by the staking interface
   * @return address The address of the ERC20 token used for staking
   */
  function token() external view returns (address);

  /**
   * @notice MUST return true if the optional history functions are implemented, otherwise false
   * @dev Since we don't implement the optional interface, this always returns false
   * @return bool Whether or not the optional history functions are implemented
   */
  function supportsHistory() external pure returns (bool);

  /**
   * @notice Sets the pairs of currently available staking options,
   * which will regulate the stake duration and reward percentage.
   * Stakes that were created through the old stake options will remain unchanged.
   * @param stakeDurations uint256[] array of stake option durations
   * @param stakePercentageBasisPoints uint16[] array of stake rewarding percentages (basis points)
   */
  function setStakingOptions(
    uint256[] memory stakeDurations,
    uint16[] memory stakePercentageBasisPoints
  ) external;

  /**
   * @notice Returns the pairs of currently available staking options,
   * so that staker can choose a suitable combination of
   * stake duration and reward percentage.
   * @return stakeOptionIndexes uint256[] array of the stake option indexes used in other functions of this contract
   * @return stakeDurations uint256[] array of stake option durations
   * @return stakePercentageBasisPoints uint16[] array of stake rewarding percentages (basis points)
   */
  function getStakingOptions()
    external
    view
    returns (
      uint256[] memory stakeOptionIndexes,
      uint256[] memory stakeDurations,
      uint16[] memory stakePercentageBasisPoints
    );

  /**
   * @dev Returns the stake indexes for
   * the last `amountToRetrieve` (with `offset` for pagination)
   * personal stakes created by `user`.
   * @param user address The address to query
   * @param amountToRetrieve uint256 Configures the amount of stakes to gather data for
   * @param offset uint256 Configures the offset for results pagination
   * @return uint256[] stake indexes array
   */
  function getPersonalStakeIndexes(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external view returns (uint256[] memory);

  /**
   * @dev Returns the stake unlock timestamps for
   * the last `amountToRetrieve` (with `offset` for pagination)
   * personal stakes created by `user`.
   * @param user address The address to query
   * @param amountToRetrieve uint256 Configures the amount of stakes to gather data for
   * @param offset uint256 Configures the offset for results pagination
   * @return uint256[] stake unlock timestamps array
   */
  function getPersonalStakeUnlockedTimestamps(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external view returns (uint256[] memory);

  /**
   * @dev Returns the stake values of
   * the last `amountToRetrieve` (with `offset` for pagination)
   * the personal stakes created by `user`.
   * @param user address The address to query
   * @param amountToRetrieve uint256 Configures the amount of stakes to gather data for
   * @param offset uint256 Configures the offset for results pagination
   * @return uint256[] stake values array
   */
  function getPersonalStakeActualAmounts(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external view returns (uint256[] memory);

  /**
   * @dev Returns the adresses of stake owners of
   * the last `amountToRetrieve` (with `offset` for pagination)
   * personal stakes created by `user`.
   * @param user address The address to query
   * @param amountToRetrieve uint256 Configures the amount of stakes to gather data for
   * @param offset uint256 Configures the offset for results pagination
   * @return address[] addresses of stake owners array
   */
  function getPersonalStakeForAddresses(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external view returns (address[] memory);

  /**
   * @dev Returns the stake rewards percentage (basis points) of
   * the last `amountToRetrieve` (with `offset` for pagination)
   * personal stakes created by `user`.
   * @param user address The address to query
   * @param amountToRetrieve uint256 Configures the amount of stakes to gather data for
   * @param offset uint256 Configures the offset for results pagination
   * @return uint256[] stake rewards percentage (basis points) array
   */
  function getPersonalStakePercentageBasisPoints(
    address user,
    uint256 amountToRetrieve,
    uint256 offset
  ) external view returns (uint256[] memory);
}

File 4 of 8 : SafeMathUint.sol
// SPDX-License-Identifier: Apache license 2.0

pragma solidity ^0.7.0;

/**
 * @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.
 * `SafeMathUint` 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 SafeMathUint {
  /**
   * @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) {
    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;

    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;
  }

  /**
   * @dev Converts an unsigned integer to a signed integer,
   * Reverts when convertation overflows.
   *
   * Requirements:
   *
   * - Operation cannot overflow.
   */
  function toInt256Safe(uint256 a) internal pure returns (int256) {
    int256 b = int256(a);
    require(b >= 0, "SafeMath: convertation overflow");
    return b;
  }
}

File 5 of 8 : ERC20.sol
// SPDX-License-Identifier: Apache license 2.0

pragma solidity ^0.7.0;

import "../utils/Context.sol";
import "../interfaces/IERC20.sol";
import "../libraries/SafeMathUint.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * Functions revert instead of returning `false` on failure.
 * This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * The non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
  using SafeMathUint for uint256;

  mapping(address => uint256) internal _balances;

  mapping(address => mapping(address => uint256)) private _allowances;

  uint256 internal _totalSupply;

  string private _name;
  string private _symbol;
  uint8 private _decimals;

  /**
   * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
   * a default value of 18.
   *
   * To select a different value for {decimals}, use {_setupDecimals}.
   *
   * All three of these values are immutable: they can only be set once during
   * construction.
   */
  constructor(string memory name, string memory symbol) {
    _name = name;
    _symbol = symbol;
    _decimals = 18;
  }

  /**
   * @dev Returns the name of the token.
   */
  function name() public view returns (string memory) {
    return _name;
  }

  /**
   * @dev Returns the symbol of the token, usually a shorter version of the
   * name.
   */
  function symbol() public view returns (string memory) {
    return _symbol;
  }

  /**
   * @dev Returns the number of decimals used to get its user representation.
   * For example, if `decimals` equals `2`, a balance of `505` tokens should
   * be displayed to a user as `5,05` (`505 / 10 ** 2`).
   *
   * Tokens usually opt for a value of 18, imitating the relationship between
   * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
   * called.
   *
   * NOTE: This information is only used for _display_ purposes: it in
   * no way affects any of the arithmetic of the contract, including
   * {IERC20-balanceOf} and {IERC20-transfer}.
   */
  function decimals() public view returns (uint8) {
    return _decimals;
  }

  /**
   * @dev See {IERC20-totalSupply}.
   */
  function totalSupply() public override view returns (uint256) {
    return _totalSupply;
  }

  /**
   * @dev See {IERC20-balanceOf}.
   */
  function balanceOf(address account) public override view returns (uint256) {
    return _balances[account];
  }

  /**
   * @dev See {IERC20-transfer}.
   *
   * Requirements:
   *
   * - `recipient` cannot be the zero address.
   * - the caller must have a balance of at least `amount`.
   */
  function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
    _transfer(_msgSender(), recipient, amount);
    return true;
  }

  /**
   * @dev See {IERC20-allowance}.
   */
  function allowance(address owner, address spender)
    public
    virtual
    override
    view
    returns (uint256)
  {
    return _allowances[owner][spender];
  }

  /**
   * @dev See {IERC20-approve}.
   *
   * Requirements:
   *
   * - `spender` cannot be the zero address.
   */
  function approve(address spender, uint256 amount) public virtual override returns (bool) {
    _approve(_msgSender(), spender, amount);
    return true;
  }

  /**
   * @dev See {IERC20-transferFrom}.
   *
   * Emits an {Approval} event indicating the updated allowance. This is not
   * required by the EIP. See the note at the beginning of {ERC20}.
   *
   * Requirements:
   *
   * - `sender` and `recipient` cannot be the zero address.
   * - `sender` must have a balance of at least `amount`.
   * - the caller must have allowance for ``sender``'s tokens of at least
   * `amount`.
   */
  function transferFrom(
    address sender,
    address recipient,
    uint256 amount
  ) public virtual override returns (bool) {
    _transfer(sender, recipient, amount);
    _approve(
      sender,
      _msgSender(),
      _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")
    );
    return true;
  }

  /**
   * @dev Atomically increases the allowance granted to `spender` by the caller.
   *
   * This is an alternative to {approve} that can be used as a mitigation for
   * problems described in {IERC20-approve}.
   *
   * Emits an {Approval} event indicating the updated allowance.
   *
   * Requirements:
   *
   * - `spender` cannot be the zero address.
   */
  function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
    _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
    return true;
  }

  /**
   * @dev Atomically decreases the allowance granted to `spender` by the caller.
   *
   * This is an alternative to {approve} that can be used as a mitigation for
   * problems described in {IERC20-approve}.
   *
   * Emits an {Approval} event indicating the updated allowance.
   *
   * Requirements:
   *
   * - `spender` cannot be the zero address.
   * - `spender` must have allowance for the caller of at least
   * `subtractedValue`.
   */
  function decreaseAllowance(address spender, uint256 subtractedValue)
    public
    virtual
    returns (bool)
  {
    _approve(
      _msgSender(),
      spender,
      _allowances[_msgSender()][spender].sub(
        subtractedValue,
        "ERC20: decreased allowance below zero"
      )
    );
    return true;
  }

  /**
   * @dev Moves tokens `amount` from `sender` to `recipient`.
   *
   * This is internal function is equivalent to {transfer}, and can be used to
   * e.g. implement automatic token fees, slashing mechanisms, etc.
   *
   * Emits a {Transfer} event.
   *
   * Requirements:
   *
   * - `sender` cannot be the zero address.
   * - `recipient` cannot be the zero address.
   * - `sender` must have a balance of at least `amount`.
   */
  function _transfer(
    address sender,
    address recipient,
    uint256 amount
  ) internal virtual {
    require(sender != address(0), "ERC20: transfer from the zero address");
    require(recipient != address(0), "ERC20: transfer to the zero address");

    _beforeTokenTransfer(sender, recipient, amount);

    _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
    _balances[recipient] = _balances[recipient].add(amount);
    emit Transfer(sender, recipient, amount);
  }

  /** @dev Creates `amount` tokens and assigns them to `account`, increasing
   * the total supply.
   *
   * Emits a {Transfer} event with `from` set to the zero address.
   *
   * Requirements:
   *
   * - `to` cannot be the zero address.
   */
  function _mint(address account, uint256 amount) internal virtual {
    require(account != address(0), "ERC20: mint to the zero address");

    _beforeMint();
    _beforeTokenTransfer(address(0), account, amount);

    _totalSupply = _totalSupply.add(amount);
    _balances[account] = _balances[account].add(amount);
    emit Transfer(address(0), account, amount);
  }

  /**
   * @dev Destroys `amount` tokens from `account`, reducing the
   * total supply.
   *
   * Emits a {Transfer} event with `to` set to the zero address.
   *
   * Requirements:
   *
   * - `account` cannot be the zero address.
   * - `account` must have at least `amount` tokens.
   */
  function _burn(address account, uint256 amount) internal virtual {
    require(account != address(0), "ERC20: burn from the zero address");

    _beforeTokenTransfer(account, address(0), amount);

    _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
    _totalSupply = _totalSupply.sub(amount);
    emit Transfer(account, address(0), amount);
  }

  /**
   * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
   *
   * This internal function is equivalent to `approve`, and can be used to
   * e.g. set automatic allowances for certain subsystems, etc.
   *
   * Emits an {Approval} event.
   *
   * Requirements:
   *
   * - `owner` cannot be the zero address.
   * - `spender` cannot be the zero address.
   */
  function _approve(
    address owner,
    address spender,
    uint256 amount
  ) internal virtual {
    require(owner != address(0), "ERC20: approve from the zero address");
    require(spender != address(0), "ERC20: approve to the zero address");

    _allowances[owner][spender] = amount;
    emit Approval(owner, spender, amount);
  }

  /**
   * @dev Hook that is called before any transfer of tokens. This includes
   * minting and burning.
   */
  function _beforeTokenTransfer(
    address from,
    address to,
    uint256 amount
  ) internal virtual {}

  /**
   * @dev Hook that is called before any token mint.
   */
  function _beforeMint() internal virtual {}
}

File 6 of 8 : ERC20Mintable.sol
// SPDX-License-Identifier: Apache license 2.0

pragma solidity ^0.7.0;

import "../utils/Context.sol";
import "./ERC20.sol";

/**
 * @dev Extension of {ERC20} that allows new tokens to be created,
 * in a way that can be recognized off-chain (via event analysis).
 */
abstract contract ERC20Mintable is Context, ERC20 {
  /**
   * @dev Creates `amount` tokens for `account`.
   *
   * See {ERC20-_mint}.
   */
  function mint(address account, uint256 amount) external virtual returns (bool success) {
    _mint(account, amount);
    return true;
  }
}

File 7 of 8 : Context.sol
// SPDX-License-Identifier: Apache license 2.0

pragma solidity ^0.7.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
  function _msgSender() internal virtual view returns (address payable) {
    return msg.sender;
  }

  function _msgData() internal virtual view returns (bytes memory) {
    this;
    return msg.data;
  }
}

File 8 of 8 : Ownable.sol
// SPDX-License-Identifier: Apache license 2.0

pragma solidity ^0.7.0;

import "./Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
  event LogOwnershipTransferred(address indexed previousOwner, address indexed newOwner);

  address private _owner;

  /**
   * @dev Initializes the contract setting the deployer as the initial owner.
   */
  constructor() {
    _owner = _msgSender();
  }

  /**
   * @dev Returns the address of the current owner.
   */
  function owner() public view returns (address) {
    return _owner;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(_msgSender() == _owner, "Ownable: only contract owner can call this function.");
    _;
  }

  /**
   * @dev Checks if transaction sender account is an owner.
   */
  function isOwner() external view returns (bool) {
    return _msgSender() == _owner;
  }

  /**
   * @dev Transfers ownership of the contract to a new account (`newOwner`).
   * Can only be called by the current owner.
   */
  function transferOwnership(address newOwner) external onlyOwner {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    emit LogOwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
  }
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "evmVersion": "byzantium",
  "libraries": {
    "": {}
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract ERC20Mintable","name":"stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"LogOwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"personalStakeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlockedTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint16","name":"stakePercentageBasisPoints","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"LogStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"personalStakeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stakeReward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"LogUnstaked","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_stakeHolders","outputs":[{"internalType":"uint256","name":"totalStakedFor","type":"uint256"},{"internalType":"uint256","name":"personalStakesLastIndex","type":"uint256"},{"internalType":"bool","name":"exists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amountToRetrieve","type":"uint256"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"getPersonalStakeActualAmounts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amountToRetrieve","type":"uint256"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"getPersonalStakeForAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amountToRetrieve","type":"uint256"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"getPersonalStakeIndexes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amountToRetrieve","type":"uint256"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"getPersonalStakePercentageBasisPoints","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amountToRetrieve","type":"uint256"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"getPersonalStakeUnlockedTimestamps","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amountToRetrieve","type":"uint256"},{"internalType":"uint256","name":"offset","type":"uint256"}],"name":"getPersonalStakes","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingOptions","outputs":[{"internalType":"uint256[]","name":"stakeOptionIndexes","type":"uint256[]"},{"internalType":"uint256[]","name":"stakeDurations","type":"uint256[]"},{"internalType":"uint16[]","name":"stakePercentageBasisPoints","type":"uint16[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"stakeDurations","type":"uint256[]"},{"internalType":"uint16[]","name":"stakePercentageBasisPoints","type":"uint16[]"}],"name":"setStakingOptions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"stakeOptionIndex","type":"uint8"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"stakeOptionIndex","type":"uint8"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"stakeFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"supportsHistory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"totalStakedFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"personalStakeIndex","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162002deb38038062002deb833981810160405260208110156200003757600080fd5b810190808051906020019092919050505062000061620000e8640100000000026401000000009004565b6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050620000f0565b600033905090565b612ceb80620001006000396000f3fe608060405234801561001057600080fd5b506004361061013e576000357c010000000000000000000000000000000000000000000000000000000090048063a56e8bd7116100ca578063efc661e41161008e578063efc661e414610975578063f2fde38b14610a64578063f35eeb0514610aa8578063fc0c546a14610b55578063fe58d18614610b895761013e565b8063a56e8bd7146106a0578063ae0580d614610708578063b43f965e14610798578063c8fd6ed014610845578063df0dbe94146108c85761013e565b806378d807151161011157806378d80715146104d4578063817b1cd2146105815780638da5cb5b1461059f5780638f32d59b146105d35780639e7bc8e8146105f35761013e565b8063155b9901146101435780634b341aed146103105780635be7e0ab146103685780637033e4a6146104b4575b600080fd5b6101996004803603606081101561015957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610c39565b60405180806020018060200180602001806020018060200186810386528b818151815260200191508051906020019060200280838360005b838110156101ec5780820151818401526020810190506101d1565b5050505090500186810385528a818151815260200191508051906020019060200280838360005b8381101561022e578082015181840152602081019050610213565b50505050905001868103845289818151815260200191508051906020019060200280838360005b83811015610270578082015181840152602081019050610255565b50505050905001868103835288818151815260200191508051906020019060200280838360005b838110156102b2578082015181840152602081019050610297565b50505050905001868103825287818151815260200191508051906020019060200280838360005b838110156102f45780820151818401526020810190506102d9565b505050509050019a505050505050505050505060405180910390f35b6103526004803603602081101561032657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fc8565b6040518082815260200191505060405180910390f35b6104b26004803603604081101561037e57600080fd5b810190808035906020019064010000000081111561039b57600080fd5b8201836020820111156103ad57600080fd5b803590602001918460208302840111640100000000831117156103cf57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184602083028401116401000000008311171561046357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050611014565b005b6104bc61120c565b60405180821515815260200191505060405180910390f35b61052a600480360360608110156104ea57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050611211565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561056d578082015181840152602081019050610552565b505050509050019250505060405180910390f35b610589611238565b6040518082815260200191505060405180910390f35b6105a761131f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105db611348565b60405180821515815260200191505060405180910390f35b6106496004803603606081101561060957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506113a6565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561068c578082015181840152602081019050610671565b505050509050019250505060405180910390f35b6106e2600480360360208110156106b657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113cf565b604051808481526020018381526020018215158152602001935050505060405180910390f35b6107966004803603606081101561071e57600080fd5b81019080803560ff169060200190929190803590602001909291908035906020019064010000000081111561075257600080fd5b82018360208201111561076457600080fd5b8035906020019184600183028401116401000000008311171561078657600080fd5b9091929391929390505050611406565b005b6107ee600480360360608110156107ae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919050505061158b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610831578082015181840152602081019050610816565b505050509050019250505060405180910390f35b6108c66004803603604081101561085b57600080fd5b81019080803590602001909291908035906020019064010000000081111561088257600080fd5b82018360208201111561089457600080fd5b803590602001918460018302840111640100000000831117156108b657600080fd5b90919293919293905050506115b6565b005b61091e600480360360608110156108de57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506115c6565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610961578082015181840152602081019050610946565b505050509050019250505060405180910390f35b61097d6115f0565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156109c85780820151818401526020810190506109ad565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015610a0a5780820151818401526020810190506109ef565b50505050905001848103825285818151815260200191508051906020019060200280838360005b83811015610a4c578082015181840152602081019050610a31565b50505050905001965050505050505060405180910390f35b610aa660048036036020811015610a7a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611813565b005b610afe60048036036060811015610abe57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050611a01565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610b41578082015181840152602081019050610b26565b505050509050019250505060405180910390f35b610b5d611a29565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c3760048036036080811015610b9f57600080fd5b81019080803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610bf357600080fd5b820183602082011115610c0557600080fd5b80359060200191846001830284011164010000000083111715610c2757600080fd5b9091929391929390505050611a53565b005b60608060608060606000600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000610c9d888360010154611bd290919063ffffffff16565b905080891115610cab578098505b60608967ffffffffffffffff81118015610cc457600080fd5b50604051908082528060200260200182016040528015610cf35781602001602082028036833780820191505090505b50905060608a67ffffffffffffffff81118015610d0f57600080fd5b50604051908082528060200260200182016040528015610d3e5781602001602082028036833780820191505090505b50905060608b67ffffffffffffffff81118015610d5a57600080fd5b50604051908082528060200260200182016040528015610d895781602001602082028036833780820191505090505b50905060608c67ffffffffffffffff81118015610da557600080fd5b50604051908082528060200260200182016040528015610dd45781602001602082028036833780820191505090505b50905060608d67ffffffffffffffff81118015610df057600080fd5b50604051908082528060200260200182016040528015610e1f5781602001602082028036833780820191505090505b509050600080610e4f8f610e4160018c60010154611bd290919063ffffffff16565b611bd290919063ffffffff16565b90505b60008110610fa55780878381518110610e6757fe5b60200260200101818152505088600201600082815260200190815260200160002060000154868381518110610e9857fe5b60200260200101818152505088600201600082815260200190815260200160002060010154858381518110610ec957fe5b60200260200101818152505088600201600082815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848381518110610f1a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505088600201600082815260200190815260200160002060030154838381518110610f7957fe5b6020026020010181815250508f8260010192508210610f9757610fa5565b808060019003915050610e52565b5085858585859c509c509c509c509c505050505050505050939792965093509350565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611053611c1c565b73ffffffffffffffffffffffffffffffffffffffff16146110bf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180612c046034913960400191505060405180910390fd5b805182511480156110d1575060008251115b611126576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526060815260200180612b266060913960600191505060405180910390fd5b61113c6001600454611c2490919063ffffffff16565b60048190555060005b825181101561120757600360006004548152602001908152602001600020604051806040016040528085848151811061117a57fe5b6020026020010151815260200184848151811061119357fe5b602002602001015161ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff16021790555050508080600101915050611145565b505050565b600090565b60608061121f858585610c39565b9091925090915090505080915050809150509392505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156112df57600080fd5b505afa1580156112f3573d6000803e3d6000fd5b505050506040513d602081101561130957600080fd5b8101908080519060200190929190505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661138a611c1c565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b6060806113b4858585610c39565b90919293509091925090505080915050809150509392505050565b60026020528060005260406000206000915090508060000154908060010154908060030160009054906101000a900460ff16905083565b8360006004541180156114315750600060036000600454815260200190815260200160002080549050115b611486576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180612c826034913960400191505060405180910390fd5b600360006004548152602001908152602001600020805490508160ff16106114f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180612b86602f913960400191505060405180910390fd5b611584611504611c1c565b856003600060045481526020019081526020016000208860ff168154811061152857fe5b9060005260206000209060020201600001546003600060045481526020019081526020016000208960ff168154811061155d57fe5b906000526020600020906002020160010160009054906101000a900461ffff168787611cac565b5050505050565b606080611599858585610c39565b909192935090919250909150905080915050809150509392505050565b6115c183838361225c565b505050565b6060806115d4858585610c39565b9091929350909192509091505080915050809150509392505050565b60608060606003600060045481526020019081526020016000208054905067ffffffffffffffff8111801561162457600080fd5b506040519080825280602002602001820160405280156116535781602001602082028036833780820191505090505b5092506003600060045481526020019081526020016000208054905067ffffffffffffffff8111801561168557600080fd5b506040519080825280602002602001820160405280156116b45781602001602082028036833780820191505090505b5091506003600060045481526020019081526020016000208054905067ffffffffffffffff811180156116e657600080fd5b506040519080825280602002602001820160405280156117155781602001602082028036833780820191505090505b50905060005b6003600060045481526020019081526020016000208054905081101561180d578084828151811061174857fe5b602002602001018181525050600360006004548152602001908152602001600020818154811061177457fe5b90600052602060002090600202016000015483828151811061179257fe5b60200260200101818152505060036000600454815260200190815260200160002081815481106117be57fe5b906000526020600020906002020160010160009054906101000a900461ffff168282815181106117ea57fe5b602002602001019061ffff16908161ffff1681525050808060010191505061171b565b50909192565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611852611c1c565b73ffffffffffffffffffffffffffffffffffffffff16146118be576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180612c046034913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611944576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612b006026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fdb6d05f3295cede580affa301a1eb5297528f3b3f6a56b075887ce6f61c45f2160405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b606080611a0f858585610c39565b909192935090915090505080915050809150509392505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b846000600454118015611a7e5750600060036000600454815260200190815260200160002080549050115b611ad3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180612c826034913960400191505060405180910390fd5b600360006004548152602001908152602001600020805490508160ff1610611b46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180612b86602f913960400191505060405180910390fd5b611bca85856003600060045481526020019081526020016000208960ff1681548110611b6e57fe5b9060005260206000209060020201600001546003600060045481526020019081526020016000208a60ff1681548110611ba357fe5b906000526020600020906002020160010160009054906101000a900461ffff168787611cac565b505050505050565b6000611c1483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612881565b905092915050565b600033905090565b600080828401905083811015611ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd611cf2611c1c565b30886040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611d8057600080fd5b505af1158015611d94573d6000803e3d6000fd5b505050506040513d6020811015611daa57600080fd5b8101908080519060200190929190505050611e2d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f5374616b696e673a207374616b6520726571756972656400000000000000000081525060200191505060405180910390fd5b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900460ff16611edd576001600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548160ff0219169083151502179055505b6000611ef28542611c2490919063ffffffff16565b9050611f4986600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154611c2490919063ffffffff16565b600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555060405180608001604052808281526020018781526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018561ffff16815250600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301559050508673ffffffffffffffffffffffffffffffffffffffff167f55a20c8b55e395fe1a8cce75cb621f8547805ed2eaadf64c69dd0d2992bf4b9887600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154848861214e8d610fc8565b8989604051808881526020018781526020018681526020018561ffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509850505050505050505060405180910390a261220d6001600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154611c2490919063ffffffff16565b600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555050505050505050565b6122b960016002600061226d611c1c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154611bd290919063ffffffff16565b831115612311576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612bb5602e913960400191505060405180910390fd5b60006002600061231f611c1c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000858152602001908152602001600020905060008160010154116123cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612c5d6025913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb612412611c1c565b83600101546040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561248657600080fd5b505af115801561249a573d6000803e3d6000fd5b505050506040513d60208110156124b057600080fd5b8101908080519060200190929190505050612516576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612c386025913960400191505060405180910390fd5b60004282600001541161269b576125526127106125448460030154856001015461294190919063ffffffff16565b6129c790919063ffffffff16565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1961259a611c1c565b836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561260a57600080fd5b505af115801561261e573d6000803e3d6000fd5b505050506040513d602081101561263457600080fd5b810190808051906020019092919050505061269a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612ad86028913960400191505060405180910390fd5b5b6127188260010154600260008560020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154611bd290919063ffffffff16565b600260008460020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055508160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f3ea3f0d7183a0f2501a84ae9c038cf7997ce1662a9a4d5309e3e233df0f3a40d836001015487846128128760020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610fc8565b898960405180878152602001868152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505097505050505050505060405180910390a2600082600101819055505050505050565b600083831115829061292e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156128f35780820151818401526020810190506128d8565b50505050905090810190601f1680156129205780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008083141561295457600090506129c1565b600082840290508284828161296557fe5b04146129bc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612be36021913960400191505060405180910390fd5b809150505b92915050565b6000612a0983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612a11565b905092915050565b60008083118290612abd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612a82578082015181840152602081019050612a67565b50505050905090810190601f168015612aaf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612ac957fe5b04905080915050939250505056fe5374616b696e673a20756e61626c6520746f206d696e7420746865207374616b65207265776172644f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735374616b696e673a207374616b65206475726174696f6e20616e642070657263656e7461676520626173697320706f696e7473206172726179732073686f756c6420626520657175616c20696e2073697a6520616e64206e6f6e2d656d7074795374616b696e673a207061737365642061206e6f6e2d76616c6964207374616b65206f7074696f6e20696e6465782e5374616b696e673a20706173736564207468652077726f6e6720706572736f6e616c207374616b6520696e646578536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a206f6e6c7920636f6e7472616374206f776e65722063616e2063616c6c20746869732066756e6374696f6e2e5374616b696e673a20756e61626c6520746f20776974686472617720746865207374616b655374616b696e673a20616c72656164792077697468647261776e2074686973207374616b655374616b696e673a206e6f20617661696c61626c65207374616b696e67206f7074696f6e7320617420746865206d6f6d656e742ea2646970667358221220e0f5f4ccd7aa623cc71ae5a36384adcb39e02809c403a6c86f2a54ca2a5a60d964736f6c63430007000033000000000000000000000000d0983dd6a0334c71d0478255d1f794508026b888

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061013e576000357c010000000000000000000000000000000000000000000000000000000090048063a56e8bd7116100ca578063efc661e41161008e578063efc661e414610975578063f2fde38b14610a64578063f35eeb0514610aa8578063fc0c546a14610b55578063fe58d18614610b895761013e565b8063a56e8bd7146106a0578063ae0580d614610708578063b43f965e14610798578063c8fd6ed014610845578063df0dbe94146108c85761013e565b806378d807151161011157806378d80715146104d4578063817b1cd2146105815780638da5cb5b1461059f5780638f32d59b146105d35780639e7bc8e8146105f35761013e565b8063155b9901146101435780634b341aed146103105780635be7e0ab146103685780637033e4a6146104b4575b600080fd5b6101996004803603606081101561015957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610c39565b60405180806020018060200180602001806020018060200186810386528b818151815260200191508051906020019060200280838360005b838110156101ec5780820151818401526020810190506101d1565b5050505090500186810385528a818151815260200191508051906020019060200280838360005b8381101561022e578082015181840152602081019050610213565b50505050905001868103845289818151815260200191508051906020019060200280838360005b83811015610270578082015181840152602081019050610255565b50505050905001868103835288818151815260200191508051906020019060200280838360005b838110156102b2578082015181840152602081019050610297565b50505050905001868103825287818151815260200191508051906020019060200280838360005b838110156102f45780820151818401526020810190506102d9565b505050509050019a505050505050505050505060405180910390f35b6103526004803603602081101561032657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fc8565b6040518082815260200191505060405180910390f35b6104b26004803603604081101561037e57600080fd5b810190808035906020019064010000000081111561039b57600080fd5b8201836020820111156103ad57600080fd5b803590602001918460208302840111640100000000831117156103cf57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184602083028401116401000000008311171561046357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050611014565b005b6104bc61120c565b60405180821515815260200191505060405180910390f35b61052a600480360360608110156104ea57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050611211565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561056d578082015181840152602081019050610552565b505050509050019250505060405180910390f35b610589611238565b6040518082815260200191505060405180910390f35b6105a761131f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6105db611348565b60405180821515815260200191505060405180910390f35b6106496004803603606081101561060957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506113a6565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b8381101561068c578082015181840152602081019050610671565b505050509050019250505060405180910390f35b6106e2600480360360208110156106b657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113cf565b604051808481526020018381526020018215158152602001935050505060405180910390f35b6107966004803603606081101561071e57600080fd5b81019080803560ff169060200190929190803590602001909291908035906020019064010000000081111561075257600080fd5b82018360208201111561076457600080fd5b8035906020019184600183028401116401000000008311171561078657600080fd5b9091929391929390505050611406565b005b6107ee600480360360608110156107ae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919050505061158b565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610831578082015181840152602081019050610816565b505050509050019250505060405180910390f35b6108c66004803603604081101561085b57600080fd5b81019080803590602001909291908035906020019064010000000081111561088257600080fd5b82018360208201111561089457600080fd5b803590602001918460018302840111640100000000831117156108b657600080fd5b90919293919293905050506115b6565b005b61091e600480360360608110156108de57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506115c6565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610961578082015181840152602081019050610946565b505050509050019250505060405180910390f35b61097d6115f0565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156109c85780820151818401526020810190506109ad565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015610a0a5780820151818401526020810190506109ef565b50505050905001848103825285818151815260200191508051906020019060200280838360005b83811015610a4c578082015181840152602081019050610a31565b50505050905001965050505050505060405180910390f35b610aa660048036036020811015610a7a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611813565b005b610afe60048036036060811015610abe57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050611a01565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610b41578082015181840152602081019050610b26565b505050509050019250505060405180910390f35b610b5d611a29565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610c3760048036036080811015610b9f57600080fd5b81019080803560ff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610bf357600080fd5b820183602082011115610c0557600080fd5b80359060200191846001830284011164010000000083111715610c2757600080fd5b9091929391929390505050611a53565b005b60608060608060606000600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000610c9d888360010154611bd290919063ffffffff16565b905080891115610cab578098505b60608967ffffffffffffffff81118015610cc457600080fd5b50604051908082528060200260200182016040528015610cf35781602001602082028036833780820191505090505b50905060608a67ffffffffffffffff81118015610d0f57600080fd5b50604051908082528060200260200182016040528015610d3e5781602001602082028036833780820191505090505b50905060608b67ffffffffffffffff81118015610d5a57600080fd5b50604051908082528060200260200182016040528015610d895781602001602082028036833780820191505090505b50905060608c67ffffffffffffffff81118015610da557600080fd5b50604051908082528060200260200182016040528015610dd45781602001602082028036833780820191505090505b50905060608d67ffffffffffffffff81118015610df057600080fd5b50604051908082528060200260200182016040528015610e1f5781602001602082028036833780820191505090505b509050600080610e4f8f610e4160018c60010154611bd290919063ffffffff16565b611bd290919063ffffffff16565b90505b60008110610fa55780878381518110610e6757fe5b60200260200101818152505088600201600082815260200190815260200160002060000154868381518110610e9857fe5b60200260200101818152505088600201600082815260200190815260200160002060010154858381518110610ec957fe5b60200260200101818152505088600201600082815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16848381518110610f1a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505088600201600082815260200190815260200160002060030154838381518110610f7957fe5b6020026020010181815250508f8260010192508210610f9757610fa5565b808060019003915050610e52565b5085858585859c509c509c509c509c505050505050505050939792965093509350565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001549050919050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611053611c1c565b73ffffffffffffffffffffffffffffffffffffffff16146110bf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180612c046034913960400191505060405180910390fd5b805182511480156110d1575060008251115b611126576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526060815260200180612b266060913960600191505060405180910390fd5b61113c6001600454611c2490919063ffffffff16565b60048190555060005b825181101561120757600360006004548152602001908152602001600020604051806040016040528085848151811061117a57fe5b6020026020010151815260200184848151811061119357fe5b602002602001015161ffff1681525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010160006101000a81548161ffff021916908361ffff16021790555050508080600101915050611145565b505050565b600090565b60608061121f858585610c39565b9091925090915090505080915050809150509392505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156112df57600080fd5b505afa1580156112f3573d6000803e3d6000fd5b505050506040513d602081101561130957600080fd5b8101908080519060200190929190505050905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1661138a611c1c565b73ffffffffffffffffffffffffffffffffffffffff1614905090565b6060806113b4858585610c39565b90919293509091925090505080915050809150509392505050565b60026020528060005260406000206000915090508060000154908060010154908060030160009054906101000a900460ff16905083565b8360006004541180156114315750600060036000600454815260200190815260200160002080549050115b611486576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180612c826034913960400191505060405180910390fd5b600360006004548152602001908152602001600020805490508160ff16106114f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180612b86602f913960400191505060405180910390fd5b611584611504611c1c565b856003600060045481526020019081526020016000208860ff168154811061152857fe5b9060005260206000209060020201600001546003600060045481526020019081526020016000208960ff168154811061155d57fe5b906000526020600020906002020160010160009054906101000a900461ffff168787611cac565b5050505050565b606080611599858585610c39565b909192935090919250909150905080915050809150509392505050565b6115c183838361225c565b505050565b6060806115d4858585610c39565b9091929350909192509091505080915050809150509392505050565b60608060606003600060045481526020019081526020016000208054905067ffffffffffffffff8111801561162457600080fd5b506040519080825280602002602001820160405280156116535781602001602082028036833780820191505090505b5092506003600060045481526020019081526020016000208054905067ffffffffffffffff8111801561168557600080fd5b506040519080825280602002602001820160405280156116b45781602001602082028036833780820191505090505b5091506003600060045481526020019081526020016000208054905067ffffffffffffffff811180156116e657600080fd5b506040519080825280602002602001820160405280156117155781602001602082028036833780820191505090505b50905060005b6003600060045481526020019081526020016000208054905081101561180d578084828151811061174857fe5b602002602001018181525050600360006004548152602001908152602001600020818154811061177457fe5b90600052602060002090600202016000015483828151811061179257fe5b60200260200101818152505060036000600454815260200190815260200160002081815481106117be57fe5b906000526020600020906002020160010160009054906101000a900461ffff168282815181106117ea57fe5b602002602001019061ffff16908161ffff1681525050808060010191505061171b565b50909192565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611852611c1c565b73ffffffffffffffffffffffffffffffffffffffff16146118be576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180612c046034913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611944576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612b006026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fdb6d05f3295cede580affa301a1eb5297528f3b3f6a56b075887ce6f61c45f2160405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b606080611a0f858585610c39565b909192935090915090505080915050809150509392505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b846000600454118015611a7e5750600060036000600454815260200190815260200160002080549050115b611ad3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526034815260200180612c826034913960400191505060405180910390fd5b600360006004548152602001908152602001600020805490508160ff1610611b46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180612b86602f913960400191505060405180910390fd5b611bca85856003600060045481526020019081526020016000208960ff1681548110611b6e57fe5b9060005260206000209060020201600001546003600060045481526020019081526020016000208a60ff1681548110611ba357fe5b906000526020600020906002020160010160009054906101000a900461ffff168787611cac565b505050505050565b6000611c1483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612881565b905092915050565b600033905090565b600080828401905083811015611ca2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd611cf2611c1c565b30886040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611d8057600080fd5b505af1158015611d94573d6000803e3d6000fd5b505050506040513d6020811015611daa57600080fd5b8101908080519060200190929190505050611e2d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f5374616b696e673a207374616b6520726571756972656400000000000000000081525060200191505060405180910390fd5b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900460ff16611edd576001600260008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548160ff0219169083151502179055505b6000611ef28542611c2490919063ffffffff16565b9050611f4986600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154611c2490919063ffffffff16565b600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555060405180608001604052808281526020018781526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018561ffff16815250600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606082015181600301559050508673ffffffffffffffffffffffffffffffffffffffff167f55a20c8b55e395fe1a8cce75cb621f8547805ed2eaadf64c69dd0d2992bf4b9887600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154848861214e8d610fc8565b8989604051808881526020018781526020018681526020018561ffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509850505050505050505060405180910390a261220d6001600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154611c2490919063ffffffff16565b600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555050505050505050565b6122b960016002600061226d611c1c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154611bd290919063ffffffff16565b831115612311576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612bb5602e913960400191505060405180910390fd5b60006002600061231f611c1c565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206002016000858152602001908152602001600020905060008160010154116123cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612c5d6025913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb612412611c1c565b83600101546040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561248657600080fd5b505af115801561249a573d6000803e3d6000fd5b505050506040513d60208110156124b057600080fd5b8101908080519060200190929190505050612516576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180612c386025913960400191505060405180910390fd5b60004282600001541161269b576125526127106125448460030154856001015461294190919063ffffffff16565b6129c790919063ffffffff16565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166340c10f1961259a611c1c565b836040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561260a57600080fd5b505af115801561261e573d6000803e3d6000fd5b505050506040513d602081101561263457600080fd5b810190808051906020019092919050505061269a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180612ad86028913960400191505060405180910390fd5b5b6127188260010154600260008560020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154611bd290919063ffffffff16565b600260008460020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055508160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f3ea3f0d7183a0f2501a84ae9c038cf7997ce1662a9a4d5309e3e233df0f3a40d836001015487846128128760020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16610fc8565b898960405180878152602001868152602001858152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505097505050505050505060405180910390a2600082600101819055505050505050565b600083831115829061292e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156128f35780820151818401526020810190506128d8565b50505050905090810190601f1680156129205780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008083141561295457600090506129c1565b600082840290508284828161296557fe5b04146129bc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612be36021913960400191505060405180910390fd5b809150505b92915050565b6000612a0983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612a11565b905092915050565b60008083118290612abd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612a82578082015181840152602081019050612a67565b50505050905090810190601f168015612aaf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581612ac957fe5b04905080915050939250505056fe5374616b696e673a20756e61626c6520746f206d696e7420746865207374616b65207265776172644f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573735374616b696e673a207374616b65206475726174696f6e20616e642070657263656e7461676520626173697320706f696e7473206172726179732073686f756c6420626520657175616c20696e2073697a6520616e64206e6f6e2d656d7074795374616b696e673a207061737365642061206e6f6e2d76616c6964207374616b65206f7074696f6e20696e6465782e5374616b696e673a20706173736564207468652077726f6e6720706572736f6e616c207374616b6520696e646578536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a206f6e6c7920636f6e7472616374206f776e65722063616e2063616c6c20746869732066756e6374696f6e2e5374616b696e673a20756e61626c6520746f20776974686472617720746865207374616b655374616b696e673a20616c72656164792077697468647261776e2074686973207374616b655374616b696e673a206e6f20617661696c61626c65207374616b696e67206f7074696f6e7320617420746865206d6f6d656e742ea2646970667358221220e0f5f4ccd7aa623cc71ae5a36384adcb39e02809c403a6c86f2a54ca2a5a60d964736f6c63430007000033

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

000000000000000000000000d0983dd6a0334c71d0478255d1f794508026b888

-----Decoded View---------------
Arg [0] : stakingToken (address): 0xd0983dD6a0334c71d0478255D1F794508026b888

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d0983dd6a0334c71d0478255d1f794508026b888


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.