creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "/contracts/EsgSHIPV4.sol": {
        "content": "pragma solidity >=0.5.16;\npragma experimental ABIEncoderV2;\n\nimport \"./EIP20Interface.sol\";\nimport \"./SafeMath.sol\";\n\ncontract EsgSHIPV4 {\n    using SafeMath for uint256;\n\n    /// @notice ESG token\n    EIP20Interface public esg;\n\n    /// @notice Emitted when ESG is staked  \n    event EsgStaked(address account, uint amount);\n\n    /// @notice Emitted when ESG is withdrawn \n    event EsgWithdrawn(address account, uint amount);\n\n    /// @notice Emitted when ESG is claimed \n    event EsgClaimed(address account, uint amount);\n\n    // @notice The rate every day. \n    uint256 public dayEsgRate; \n\n    // @notice A checkpoint for staking\n    struct Checkpoint {\n        uint256 deposit_time; //last check time\n        uint256 total_staked;\n        uint256 bonus_unclaimed;\n    }\n\n    // @notice staking struct of every account\n    mapping (address => Checkpoint) public stakings;\n\n    address public owner;\n    modifier onlyOwner() {\n        require(msg.sender == owner, \"Only owner can call this function.\");\n        _;\n    }\n\n    // @notice total stake amount\n    uint256 public total_deposited;\n    uint256 public total_user;\n\n    constructor(address esgAddress) public {\n        owner = msg.sender;\n        dayEsgRate = 1.5e15;\n        esg = EIP20Interface(esgAddress);\n    }\n\n    /**\n     * @notice Stake ESG token to contract \n     * @param amount The amount of address to be staked \n     * @return Success indicator for whether staked \n     */\n    function stake(uint256 amount) public returns (bool) {\n        require(amount > 0, \"No zero.\");\n        require(amount <= esg.balanceOf(msg.sender), \"Insufficient ESG token.\");\n\n        Checkpoint storage cp = stakings[msg.sender];\n        esg.transferFrom(msg.sender, address(this), amount);\n\n        if(cp.deposit_time > 0)\n        {\n            uint256 bonus = block.timestamp.sub(cp.deposit_time).mul(cp.total_staked).mul(dayEsgRate).div(1e18).div(86400);\n            cp.bonus_unclaimed = cp.bonus_unclaimed.add(bonus);\n            cp.total_staked = cp.total_staked.add(amount);\n            cp.deposit_time = block.timestamp;\n        }else\n        {\n            cp.total_staked = amount;\n            cp.deposit_time = block.timestamp;\n            total_user = total_user + 1;\n        }\n        total_deposited = total_deposited.add(amount);\n        emit EsgStaked(msg.sender, amount);\n\n        return true;\n    }\n\n    /**\n     * @notice withdraw all ESG token staked in contract \n     * @return Success indicator for success \n     */\n    function withdraw(uint256 amount) public returns (bool) {\n        require(amount > 0, \"Amount must be greater than 0\");\n        Checkpoint storage cp = stakings[msg.sender];\n        require(cp.total_staked >= amount, \"Amount can not greater than total_staked\");\n        uint256 total_bonus = cp.bonus_unclaimed;\n        uint256 bonus = block.timestamp.sub(cp.deposit_time).mul(cp.total_staked).mul(dayEsgRate).div(1e18).div(86400);\n        total_bonus = total_bonus.add(bonus);\n        if(cp.total_staked == amount){\n            cp.total_staked = 0;\n            cp.deposit_time = 0;\n        }else{\n            cp.total_staked = cp.total_staked.sub(amount);\n            cp.deposit_time = block.timestamp;\n        }\n        \n        total_deposited = total_deposited.sub(amount);\n        amount = amount.add(total_bonus);\n        esg.transfer(msg.sender, amount);\n        cp.bonus_unclaimed = 0;\n\n        emit EsgWithdrawn(msg.sender, amount); \n\n        return true;\n    }\n\n    /**\n     * @notice claim all ESG token bonus in contract \n     * @return Success indicator for success \n     */\n    function claim() public returns (bool) {\n        Checkpoint storage cp = stakings[msg.sender];\n        require(cp.total_staked > 0, \"No staked!\");\n        uint256 amount = cp.bonus_unclaimed;\n        if(cp.deposit_time > 0)\n        {\n            uint256 bonus = block.timestamp.sub(cp.deposit_time).mul(cp.total_staked).mul(dayEsgRate).div(1e18).div(86400);\n            amount = amount.add(bonus);\n            cp.bonus_unclaimed = 0; \n            cp.deposit_time = block.timestamp;\n            \n        }else{\n            //has beed withdrawn\n            cp.bonus_unclaimed = 0;\n        }\n        esg.transfer(msg.sender, amount);\n        emit EsgClaimed (msg.sender, amount); \n\n        return true;\n    }\n\n    // set the dayrate\n    function setDayEsgRate(uint256 dayRate) onlyOwner public  {\n        dayEsgRate = dayRate;\n    }\n\n    function changeUserStaked(address account, uint256 depositTime, uint256 totalStaked, uint256 bonusUnclaimed) onlyOwner public returns (bool) {\n        Checkpoint storage cp = stakings[account];\n        cp.deposit_time = depositTime;\n        cp.total_staked = totalStaked;\n        cp.bonus_unclaimed = bonusUnclaimed;\n        return true;\n    }\n\n    function changeTotalNum(uint256 totalDeposited, uint256 totalUser) onlyOwner public returns (bool) {\n        total_deposited = totalDeposited;\n        total_user = totalUser;\n        return true;\n    }\n\n    /**\n     * @notice Returns the balance of ESG an account has staked\n     * @param account The address of the account \n     * @return balance of ESG \n     */\n    function getStakingBalance(address account) public view returns (uint256) {\n        Checkpoint memory cp = stakings[account];\n        return cp.total_staked;\n    }\n\n    /**\n     * @notice Return the unclaimed bonus ESG of staking \n     * @param account The address of the account \n     * @return The amount of unclaimed ESG \n     */\n    function getUnclaimedEsg(address account) public view returns (uint256) {\n        Checkpoint memory cp = stakings[account];\n        uint256 amount = cp.bonus_unclaimed;\n        if(cp.deposit_time > 0)\n        {\n            uint256 bonus = block.timestamp.sub(cp.deposit_time).mul(cp.total_staked).mul(dayEsgRate).div(1e18).div(86400);\n            amount = amount.add(bonus);\n        }\n        return amount;\n    }\n}"
      },
      "/contracts/SafeMath.sol": {
        "content": "pragma solidity ^0.5.16;\n\n// From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol\n// Subject to the MIT license.\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting with custom message on overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, errorMessage);\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot underflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction underflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot underflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, errorMessage);\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers.\n     * Reverts on division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers.\n     * Reverts with custom message on division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        // Solidity only automatically asserts when dividing by 0\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n\n    /**\n   * @dev gives square root of given x.\n   */\n  function sqrt(uint256 x) internal pure returns(uint256 y) {\n        uint256 z = ((add(x, 1)) / 2);\n        y = x;\n        while (z < y) {\n            y = z;\n            z = ((add((x / z), z)) / 2);\n        }\n  }\n\n  /**\n   * @dev gives square. multiplies x by x\n   */\n  function sq(uint256 x) internal pure returns(uint256) {\n       return (mul(x, x));\n  }\n\n  /**\n   * @dev x to the power of y\n   */\n  function pwr(uint256 x, uint256 y) internal pure returns(uint256) {\n    if (x == 0)\n      return (0);\n    else if (y == 0)\n      return (1);\n    else {\n      uint256 z = x;\n      for (uint256 i = 1; i < y; i++)\n        z = mul(z, x);\n      return (z);\n    }\n  }\n}"
      },
      "/contracts/EIP20Interface.sol": {
        "content": "pragma solidity ^0.5.16;\n\n/**\n * @title ERC 20 Token Standard Interface\n *  https://eips.ethereum.org/EIPS/eip-20\n */\ninterface EIP20Interface {\n    function name() external view returns (string memory);\n    function symbol() external view returns (string memory);\n    function decimals() external view returns (uint8);\n\n    /**\n      * @notice Get the total number of tokens in circulation\n      * @return The supply of tokens\n      */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @notice Gets the balance of the specified address\n     * @param owner The address from which the balance will be retrieved\n     * @return The balance\n     */\n    function balanceOf(address owner) external view returns (uint256 balance);\n\n    /**\n      * @notice Transfer `amount` tokens from `msg.sender` to `dst`\n      * @param dst The address of the destination account\n      * @param amount The number of tokens to transfer\n      * @return Whether or not the transfer succeeded\n      */\n    function transfer(address dst, uint256 amount) external returns (bool success);\n\n    /**\n      * @notice Transfer `amount` tokens from `src` to `dst`\n      * @param src The address of the source account\n      * @param dst The address of the destination account\n      * @param amount The number of tokens to transfer\n      * @return Whether or not the transfer succeeded\n      */\n    function transferFrom(address src, address dst, uint256 amount) external returns (bool success);\n\n    /**\n      * @notice Approve `spender` to transfer up to `amount` from `src`\n      * @dev This will overwrite the approval amount for `spender`\n      *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)\n      * @param spender The address of the account which may transfer tokens\n      * @param amount The number of tokens that are approved (-1 means infinite)\n      * @return Whether or not the approval succeeded\n      */\n    function approve(address spender, uint256 amount) external returns (bool success);\n\n    /**\n      * @notice Get the current allowance from `owner` for `spender`\n      * @param owner The address of the account which owns the tokens to be spent\n      * @param spender The address of the account which may transfer tokens\n      * @return The number of tokens allowed to be spent (-1 means infinite)\n      */\n    function allowance(address owner, address spender) external view returns (uint256 remaining);\n\n    event Transfer(address indexed from, address indexed to, uint256 amount);\n    event Approval(address indexed owner, address indexed spender, uint256 amount);\n}"
      }
    },
    "settings": {
      "remappings": [],
      "optimizer": {
        "enabled": true,
        "runs": 300
      },
      "evmVersion": "istanbul",
      "libraries": {},
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}