Contract 0x0b21cfbe22b5730f050c2787379a8263fccd276b 6

 

Contract Overview

Balance:
0 ETH

ETH Value:
$0.00

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x3cea5c9ed6c29d0528eebe88884edfa5fbb8d7be9ba1b57e3ce5ff9a001434eaStake Reward961349652023-05-30 21:59:2215 mins ago0x213b112ec83daf5906b87689099990e706439702 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.000042820.1
0x6968434e1bbce27b28c98854d4f3e0e9490c1d229c3a80a7ad48e40da2759670Get Reward961119842023-05-30 20:22:521 hr 51 mins ago0x88d13f2b1dda2358c17426781affe45dc33484e7 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00005887 0.1
0xf911bccd583acf5abd3717bcf53ec33daef559412d5a23b0ffcd8999d25d2addWithdraw961118982023-05-30 20:22:311 hr 52 mins ago0x88d13f2b1dda2358c17426781affe45dc33484e7 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00008032 0.1
0xfa364d872f9c12647ee79961f4144feeffe711b40221291de553de2937d1a931Stake Reward960987692023-05-30 19:27:112 hrs 47 mins ago0x2e1440d9fb2930ea27b469ab699e1a973eecd562 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00005276 0.1
0xde099f5ad856c58835d93c1b6badb13ec1a7ebb35a61c79afe6af8a91ee65225Stake Reward959679422023-05-30 10:23:1411 hrs 51 mins ago0x7ba2ee8dfcd61c4995e10a3917ba6fcb917e0acc IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00004985 0.1
0x0bcd1aef18b6d3fd9d0a63bb1aa978e081702402b99468f2bdabf7212aa221cdGet Reward958813612023-05-30 4:16:3517 hrs 58 mins ago0xd25f3ff4d63179800dce837dc5412dac1ba6133f IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.000078590.1
0x002fc987f647e04364251ab10d6cbd1d46937036fe8eba7e2b24954825a2af82Get Reward958047912023-05-29 22:42:5523 hrs 31 mins ago0xb1fc39856c5ad39ed4d107767ce442c68d75b515 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00003847 0.1
0x3b04aea32583028946cc71eb2d0173f86b18e340be8b42edf8823394acb7a32fStake Reward957970812023-05-29 22:10:171 day 4 mins ago0x213b112ec83daf5906b87689099990e706439702 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.000040340.1
0xfa2cb811220bee5989a2c71bad5c1c6710059d4be764dd3cd25e1ee2240f1d80Get Reward957637622023-05-29 19:49:191 day 2 hrs ago0x156fe1286b7d94420dd99a257c8ee09cde8c0176 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00005018 0.1
0x0d80f7c2ec0b1cb58a94687ba9a6b254e1f5b40bb0f5fc72ffd4346401856438Stake Reward957431702023-05-29 18:22:471 day 3 hrs ago0x37e19f578d9ccdd41af8ff8af916a4673cd8096f IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00004602 0.1
0xa3f18f023577efbde5b2760e0ef00041d623cbaa1847b84cbd70c9d1b42f5449Stake Reward956273572023-05-29 10:20:511 day 11 hrs ago0x0a11acdd1ffbdb8adfc34a84f1836f360e6f3cce IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00004238 0.1
0xdc700cec1432b0b42408dd64737653f5dc216bfb86347476e82f675dee3225bcGet Reward956140212023-05-29 9:25:321 day 12 hrs ago0xe11a79bbd7a6de8f1a274a4d993d2dcb610b5354 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00004573 0.1
0xb71c9ac8ab51b449280c3f20ad7ede515ff3a8992c1f75cf71a0c4cf14cf0193Stake Reward954642942023-05-28 22:51:071 day 23 hrs ago0x213b112ec83daf5906b87689099990e706439702 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.000046230.1
0x1d42846d4aa4c6d3f61eeaae87084f45528d7345f0c987c3ce038d3e977c85a0Stake Reward952400212023-05-28 7:10:132 days 15 hrs ago0x098dee2f74df806d73002790eea003d77a48ebea IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00004203 0.1
0xd2835d2bae8e7f042b55a651bf46141cefaf0e2901fdc0531be23665cece5f2dStake Reward952255832023-05-28 6:09:512 days 16 hrs ago0x55e9fde8ddeb3952b1b2d30b8f95d8a59ede9241 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00003755 0.1
0xc55ed04d547ba9dd40a9e7c0513510d0a2c11521976d124c14fbcef259e1748bStake Reward951243412023-05-27 22:56:582 days 23 hrs ago0x213b112ec83daf5906b87689099990e706439702 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.000033520.1
0xbb1aadd7f1c2b38eaa19523ca04ae31837bcbb7e4c5763af6eafb633ba454f59Stake Reward950446862023-05-27 17:21:133 days 4 hrs ago0xd88013466c0f71989cce48f3e4e3cd9b2032f96a IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00003975 0.1
0x73b2d81bbb45c6175e22038525f0e1497019f7d6732e5a88ce4369784847c015Withdraw949651982023-05-27 11:49:293 days 10 hrs ago0x53a8bf04b0b952c62b3b969753212340d3a98e7b IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00004833 0.1
0x87ca87362e1ae05c297403083a2902d5d603e428a3491349bcde35d48ca1f1abStake Reward949491512023-05-27 10:42:333 days 11 hrs ago0xf6d26e6d0b2d51afe0375317e0d6a0f515acce53 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00003566 0.1
0x18af9d0c8cb97ed08feb8bcaa3f585f4750933d4ec0acb2f1f32896213eeaed2Stake Reward948577052023-05-27 4:20:153 days 17 hrs ago0xb50062492871804349ae8f7a5830a49fff0ceb11 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.0000462 0.1
0xf0500783103ff6717e04f12a382d8567512c663d130c5abe89b54a2d08f6d6efStake Reward947561552023-05-26 21:04:434 days 1 hr ago0x213b112ec83daf5906b87689099990e706439702 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.000042610.1
0xa24e1c8e0c0c40f86c054aeece9d0066a1cd9ea32d523a26ea77597309efa1e5Stake Reward945703332023-05-26 8:10:564 days 14 hrs ago0x2e1440d9fb2930ea27b469ab699e1a973eecd562 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.0000395 0.1
0x51aabe4f6d4123acbb85b0ecf8a14d4f895da6723552c84a7773618a21e95f25Stake Reward942809792023-05-25 12:07:055 days 10 hrs ago0x213b112ec83daf5906b87689099990e706439702 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.000041370.10842
0x1bca8a985cfab161f1f3a30bdb385ee6c46bd53f70a8d14547d801c04b375aeaDeposit942681482023-05-25 11:13:575 days 11 hrs ago0x586ba5c15b186a68f890cdc07bc9edfc82d959c1 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00007077 0.1
0xde318ea2b876a952226292e8315b067e2cce345ecad3809e7d454b2439ae151fGet Reward942669992023-05-25 11:09:125 days 11 hrs ago0x586ba5c15b186a68f890cdc07bc9edfc82d959c1 IN  0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH0.00004374 0.1
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xdbeaa6e8224a2acd1fe55034702b2f9325489f94e151ec77b4e06f0ed6846e2b720809422023-03-21 9:55:0670 days 12 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xe5ec24cde9543978dc8a8c291a694519ad5d1a55efa5c75e78566701978b42d5720539022023-03-21 8:04:1570 days 14 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xe5ec24cde9543978dc8a8c291a694519ad5d1a55efa5c75e78566701978b42d5720539022023-03-21 8:04:1570 days 14 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xe5ec24cde9543978dc8a8c291a694519ad5d1a55efa5c75e78566701978b42d5720539022023-03-21 8:04:1570 days 14 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xb63ffd6690069e289fcbf3874be700b8abfae26a6f58237f90ed352e05ecc156720496992023-03-21 7:47:0170 days 14 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x671b8e4d41e4c142aaadbf14982acd233c7abb272a8dd8333d00ca6eecdf6f6f720472132023-03-21 7:36:5170 days 14 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xafba9cde0176614e63552eca5db2dcb1bee72821961d65a3172790711a7897f4720374372023-03-21 6:56:4170 days 15 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xfb98104b536fb00a519e1c38c749eb391d4c5ae7ceb8762bb6e587cc241e3021720356652023-03-21 6:49:2670 days 15 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xd5d2ddab9d05a1df558c0405f96d61ad441d911611ab57fb411686467a97c10c720303052023-03-21 6:27:3070 days 15 hrs ago 0x87195340478b792cfb0986450c39b64846867716 0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH
0xa433f4c715e64942bad275bb3d08931d90ef43f9b1be920bac9702cadfa231f1720117882023-03-21 5:11:0670 days 17 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x93f838a377324d36b53e0708f63b1fe2ed82c579f64ac085d2d03bd057f3ed1e720041852023-03-21 4:39:4070 days 17 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x93f838a377324d36b53e0708f63b1fe2ed82c579f64ac085d2d03bd057f3ed1e720041852023-03-21 4:39:4070 days 17 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x93f838a377324d36b53e0708f63b1fe2ed82c579f64ac085d2d03bd057f3ed1e720041852023-03-21 4:39:4070 days 17 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xb8a215d63caa5de1ff38841e61fd78b9399d15449e8e89ba06cb4bcd56c70427720034732023-03-21 4:36:4670 days 17 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x0765d4b91618cc9824674366584852858d2ec72682a8a982816968b533b1f5fd720033152023-03-21 4:36:0770 days 17 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x0765d4b91618cc9824674366584852858d2ec72682a8a982816968b533b1f5fd720033152023-03-21 4:36:0770 days 17 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x0765d4b91618cc9824674366584852858d2ec72682a8a982816968b533b1f5fd720033152023-03-21 4:36:0770 days 17 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x0c4b104f55048ae5ec6835c0c36b888c606b4ca09401e033b77e6a500026feef719879812023-03-21 3:32:2070 days 18 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x0c4b104f55048ae5ec6835c0c36b888c606b4ca09401e033b77e6a500026feef719879812023-03-21 3:32:2070 days 18 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x5a3d17fee08f83b1578919ddeec4bd39d8c429fc019d2e69d1d9a4d4a473ed3c719878642023-03-21 3:31:5170 days 18 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0xa10c76cb067ccabee34e31126218b8c4fae9bbcf00eb12fe2006b2784dec5f21719793792023-03-21 2:56:4570 days 19 hrs ago 0x87195340478b792cfb0986450c39b64846867716 0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH
0x7b6b0bafecc4365966e06ebd8102f8d7e86eb793d371307683814d224d5a99fe719559192023-03-21 1:18:2670 days 20 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x65a3978cbd748febc04aa818f7516b50c3c9cab3e5a9f06e2c2c8967bb13f10b719557522023-03-21 1:17:4270 days 20 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x65a3978cbd748febc04aa818f7516b50c3c9cab3e5a9f06e2c2c8967bb13f10b719557522023-03-21 1:17:4270 days 20 hrs ago 0x0b21cfbe22b5730f050c2787379a8263fccd276b Vox Finance: VOX2.0 Token0 ETH
0x652d7e03c952a408adc8a72f711c136d9a6f6f97c232da764aa221ee5ecb73f5718721482023-03-20 19:21:0871 days 2 hrs ago 0x87195340478b792cfb0986450c39b64846867716 0x0b21cfbe22b5730f050c2787379a8263fccd276b0 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
VoxStakingPool

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/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 {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 2 of 10 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

File 3 of 10 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 4 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.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 `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, 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 `from` to `to` 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 from,
        address to,
        uint256 amount
    ) external returns (bool);
}

File 5 of 10 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 6 of 10 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 7 of 10 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.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 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 view virtual returns (address) {
        return msg.sender;
    }

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

File 8 of 10 : SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @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) {
        return a + b;
    }

    /**
     * @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 a - b;
    }

    /**
     * @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) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting 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 a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting 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) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * 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) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

File 9 of 10 : Pausable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

abstract contract Pausable is Ownable {
    uint public lastPauseTime;
    bool public paused;

    constructor() {
        // This contract is abstract, and thus cannot be instantiated directly
        require(owner() != address(0), "Owner must be set");
        // Paused will be false, and lastPauseTime will be 0 upon initialisation
    }

    /**
     * @notice Change the paused state of the contract
     * @dev Only the contract owner may call this.
     */
    function setPaused(bool _paused) public onlyOwner {
        // Ensure we're actually changing the state before we do anything
        if (_paused == paused) {
            return;
        }

        // Set our paused state.
        paused = _paused;

        // If applicable, set the last pause time.
        if (paused) {
            lastPauseTime = block.timestamp;
        }

        // Let everyone know that our pause state has changed.
        emit PauseChanged(paused);
    }

    event PauseChanged(bool isPaused);

    modifier notPaused {
        require(
            !paused,
            "This action cannot be performed while the contract is paused"
        );
        _;
    }
}

File 10 of 10 : VoxStakingPool.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./utils/Pausable.sol";

/*
    VOX FINANCE 2.0

    Website: https://vox.finance
    Twitter: https://twitter.com/RealVoxFinance
    Telegram: https://t.me/VoxFinance
 */

contract VoxStakingPool is ReentrancyGuard, Pausable {
    using SafeMath for uint;
    using SafeERC20 for IERC20;

    // STATE VARIABLES

    IERC20 public rewardsToken;
    IERC20 public stakingToken;
    address public treasury = address(0xB565A72868A70da734DA10e3750196Dd82Cb7f16);

    uint public periodFinish = 0;
    uint public rewardRate = 0;
    uint public rewardsDuration = 126144000; // 4 years
    uint public lastUpdateTime;
    uint public rewardPerTokenStored;

    mapping(address => uint) public userRewardPerTokenPaid;
    mapping(address => uint) public rewards;

    uint private _totalSupply;
    uint private _totalDeposited;
    uint private _totalLocked;
    mapping(address => uint) private _balances;
    mapping(address => uint) private _deposits;
    mapping(address => uint) private _locked;
    mapping(address => uint) private _periods;
    mapping(address => uint) private _locks;
    mapping(address => bool) private _pools;
    mapping(address => bool) private _privatePools;

    uint public withdrawalFee = 75; // 0.75 %
    uint public withdrawalFeeMax = 500;
    uint internal withdrawalFeeBase = 10000;

    uint private minimumLock = 2 weeks;
    uint private maximumLock = 52 weeks;

    uint public multiplier = 5; // 5 %
    uint private constant multiplierBase = 100;

    // CONSTRUCTOR

    constructor(
        address _rewardsToken,
        address _stakingToken
    ) {
        rewardsToken = IERC20(_rewardsToken);
        if (_stakingToken != address(0)) {
            stakingToken = IERC20(_stakingToken);
        }
    }

    // VIEWS

    function totalSupply() external view returns (uint) {
        return _totalSupply;
    }

    function totalDeposited() external view returns (uint) {
        return _totalDeposited;
    }

    function totalLocked() external view returns (uint) {
        return _totalLocked;
    }

    function balanceOf(address account) external view returns (uint) {
        return _balances[account];
    }

    function depositOf(address account) external view returns (uint) {
        return _deposits[account];
    }

    function lockedOf(address account) external view returns (uint) {
        return _locked[account];
    }

    function availableOf(address account) external view returns (uint) {
        return _balances[account].sub(_locked[account]);
    }

    function unlockedAt(address account) external view returns (uint) {
        return _locks[account];
    }

    function lockedFor(address account) external view returns (uint) {
        return _periods[account];
    }

    function lastTimeRewardApplicable() public view returns (uint) {
        return min(block.timestamp, periodFinish);
    }

    function rewardPerToken() public view returns (uint) {
        if (_totalSupply == 0) {
            return rewardPerTokenStored;
        }
        return
            rewardPerTokenStored.add(
                lastTimeRewardApplicable()
                    .sub(lastUpdateTime)
                    .mul(rewardRate)
                    .mul(1e18)
                    .div(_totalSupply)
            );
    }

    function earned(address account) public view returns (uint) {
        return
            _balances[account]
                .mul(rewardPerToken().sub(userRewardPerTokenPaid[account]))
                .div(1e18)
                .add(rewards[account]);
    }

    function getRewardForDuration() external view returns (uint) {
        return rewardRate.mul(rewardsDuration);
    }

    function min(uint a, uint b) public pure returns (uint) {
        return a < b ? a : b;
    }

    // PUBLIC FUNCTIONS

    function deposit(uint amount, uint lockPeriod)
        external
        nonReentrant
        notPaused
        updateReward(msg.sender)
    {
        require(amount > 0, "!stake-0");
        require(lockPeriod >= minimumLock, "!stake-<2weeks");

        if (_deposits[msg.sender] > 0) {
            require(lockPeriod >= _periods[msg.sender], "!stake-lock");
        }

        if (lockPeriod > maximumLock) {
            lockPeriod = maximumLock;
        }

        uint balBefore = stakingToken.balanceOf(address(this));
        stakingToken.safeTransferFrom(msg.sender, address(this), amount);
        uint balAfter = stakingToken.balanceOf(address(this));
        uint actualReceived = balAfter.sub(balBefore);

        // add already deposited amount to current deposit
        uint total = _deposits[msg.sender].add(actualReceived);
        uint shares = 0;

        // calculate multiplier: (lock weeks - two weeks) / 1 week + add base
        uint lockMultiplier = ((lockPeriod - minimumLock).div(1 weeks)).mul(multiplier).add(multiplierBase);

        // calculate shares: total deposited amount * multiplier / base
        shares = total.mul(lockMultiplier).div(multiplierBase);

        // update all balances
        _deposits[msg.sender] = total;
        _totalDeposited = _totalDeposited.add(actualReceived);

        _totalSupply = _totalSupply.sub(_balances[msg.sender]);
        _balances[msg.sender] = shares;
        _totalSupply = _totalSupply.add(shares);

        _periods[msg.sender] = lockPeriod;
        _locks[msg.sender] = block.timestamp.add(lockPeriod);
        emit Deposited(msg.sender, actualReceived, lockPeriod);
    }

    function withdraw(uint amount)
        public
        nonReentrant
        updateReward(msg.sender)
    {
        require(amount > 0, "!withdraw-0");
        require(_deposits[msg.sender] > 0, "!withdraw-nostake");
        require(amount <= _deposits[msg.sender], "!withdraw-amount");
        require(block.timestamp >= _locks[msg.sender], "!withdraw-lock");

        // Calculate percentage of principal being withdrawn
        uint percentage = (amount.mul(1e18).div(_deposits[msg.sender]));

        // Calculate amount of shares to be removed
        uint shares = _balances[msg.sender].mul(percentage).div(1e18);

        if (shares > _balances[msg.sender]) {
            shares = _balances[msg.sender];
        }

        require(_balances[msg.sender].sub(_locked[msg.sender]) >= shares, '!locked');

        _deposits[msg.sender] = _deposits[msg.sender].sub(amount);
        _totalDeposited = _totalDeposited.sub(amount);

        _balances[msg.sender] = _balances[msg.sender].sub(shares);
        _totalSupply = _totalSupply.sub(shares);

        uint fee = amount.mul(withdrawalFee).div(withdrawalFeeBase);
        stakingToken.safeTransfer(treasury, fee);
        stakingToken.safeTransfer(msg.sender, amount.sub(fee));

        emit Withdrawn(msg.sender, amount);
    }

    function lockShares(address account, uint shares)
        external
        notPaused
        updateReward(account)
    {
        require(shares > 0, '!shares');
        require(_privatePools[msg.sender], '!private');
        require(_balances[account].sub(_locked[account]) >= shares, '!locked');

        _locked[account] = _locked[account].add(shares);
        _totalLocked = _totalLocked.add(shares);
        emit Locked(account, shares);
    }

    function unlockShares(address account, uint shares)
        external
        updateReward(account)
    {
        require(shares > 0, '!shares');
        require(_privatePools[msg.sender], '!private');
        require(_locked[account] >= shares, '!locked');

        _locked[account] = _locked[account].sub(shares);
        _totalLocked = _totalLocked.sub(shares);
        emit Unlocked(account, shares);
    }

    function depositFor(address account, uint amount)
        external
        notPaused
        updateReward(account)
    {
        require(amount > 0, "!stake-0");
        require(_pools[msg.sender], '!pool');
        _deposit(account, amount);
    }

    function getReward() public nonReentrant updateReward(msg.sender) {
        uint reward = rewards[msg.sender];
        if (reward > 0) {
            rewards[msg.sender] = 0;
            rewardsToken.safeTransfer(msg.sender, reward);
            emit RewardPaid(msg.sender, reward);
        }
    }

    function stakeReward() public nonReentrant notPaused updateReward(msg.sender) {
        uint reward = rewards[msg.sender];
        if (reward > 0) {
            rewards[msg.sender] = 0;
            _deposit(msg.sender, reward);
            emit RewardStaked(msg.sender, reward);
        }
    }

    function exit() external {
        withdraw(_deposits[msg.sender]);
        getReward();
    }

    // INTERNAL FUNCTIONS

    function _deposit(address account, uint amount)
        internal
    {
        uint lockPeriod = _periods[account];
        if (lockPeriod <= 0 || _deposits[account] <= 0) {
            lockPeriod = minimumLock;
            _periods[account] = lockPeriod;
            _locks[account] = block.timestamp.add(lockPeriod);
        }

        // add already deposited amount to current deposit
        uint total = _deposits[account].add(amount);
        uint shares = 0;

        // calculate multiplier: (lock weeks - two weeks) / 1 week + add base
        uint lockMultiplier = ((lockPeriod - minimumLock).div(1 weeks)).mul(multiplier).add(multiplierBase);

        // calculate shares: total deposited amount * multiplier / base
        shares = total.mul(lockMultiplier).div(multiplierBase);

        // update all balances
        _deposits[account] = total;
        _totalDeposited = _totalDeposited.add(amount);

        _totalSupply = _totalSupply.sub(_balances[account]);
        _balances[account] = shares;
        _totalSupply = _totalSupply.add(shares);
    }

    // RESTRICTED FUNCTIONS

    function togglePool(address _pool)
        external
        restricted
    {
        _pools[_pool] = !_pools[_pool];
    }

    function togglePrivatePool(address _pool)
        external
        restricted
    {
        _privatePools[_pool] = !_privatePools[_pool];
    }

    function notifyRewardAmount(uint reward)
        external
        restricted
        updateReward(address(0))
    {
        uint oldBalance = rewardsToken.balanceOf(address(this));
        rewardsToken.safeTransferFrom(msg.sender, address(this), reward);
        uint newBalance = rewardsToken.balanceOf(address(this));
        uint actualReceived = newBalance - oldBalance;
        require(actualReceived == reward, "Whitelist the pool to exclude fees");

        if (block.timestamp >= periodFinish) {
            rewardRate = reward.div(rewardsDuration);
        } else {
            uint remaining = periodFinish.sub(block.timestamp);
            uint leftover = remaining.mul(rewardRate);
            rewardRate = reward.add(leftover).div(rewardsDuration);
        }

        // Ensure the provided reward amount is not more than the balance in the contract.
        // This keeps the reward rate in the right range, preventing overflows due to
        // very high values of rewardRate in the earned and rewardsPerToken functions;
        // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow.
        uint balance = rewardsToken.balanceOf(address(this));
        require(
            rewardRate <= balance.div(rewardsDuration),
            "Provided reward too high"
        );

        lastUpdateTime = block.timestamp;
        periodFinish = block.timestamp.add(rewardsDuration);
        emit RewardAdded(reward);
    }

    // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders
    function recoverERC20(address tokenAddress, uint tokenAmount)
        external
        onlyOwner
    {
        // Cannot recover the staking token or the rewards token
        require(
            tokenAddress != address(rewardsToken),
            "Cannot withdraw the staking or rewards tokens"
        );
        IERC20(tokenAddress).safeTransfer(owner(), tokenAmount);
        emit Recovered(tokenAddress, tokenAmount);
    }

    function setRewardsDuration(uint _rewardsDuration) external restricted {
        require(
            block.timestamp > periodFinish,
            "Previous rewards period must be complete before changing the duration for the new period"
        );
        rewardsDuration = _rewardsDuration;
        emit RewardsDurationUpdated(rewardsDuration);
    }

    function setTreasury(address _treasury)
        external
        restricted
    {
        require(msg.sender == address(treasury), "!treasury");
        treasury = _treasury;
    }

    function setWithdrawalFee(uint _withdrawalFee)
        external
        restricted
    {
        require(_withdrawalFee <= withdrawalFeeMax, "!withdrawalFee");
        withdrawalFee = _withdrawalFee;
    }

    function setLockingPeriods(uint _minimumLock, uint _maximumLock) external restricted {
        require(
            _maximumLock <= 52 weeks,
            '!maximumLock'
        );
        require(
            _minimumLock < _maximumLock,
            '!minLock>maxLock'
        );
        minimumLock = _minimumLock;
        maximumLock = _maximumLock;
    }

    function setMultiplier(uint _multiplier) external restricted {
        multiplier = _multiplier;
    }

    // *** MODIFIERS ***

    modifier updateReward(address account) {
        rewardPerTokenStored = rewardPerToken();
        lastUpdateTime = lastTimeRewardApplicable();
        if (account != address(0)) {
            rewards[account] = earned(account);
            userRewardPerTokenPaid[account] = rewardPerTokenStored;
        }

        _;
    }

    modifier restricted {
        require(
            msg.sender == owner(),
            '!restricted'
        );

        _;
    }

    // EVENTS

    event RewardAdded(uint reward);
    event Deposited(address indexed user, uint amount, uint lock);
    event Withdrawn(address indexed user, uint amount);
    event Locked(address indexed user, uint shares);
    event Unlocked(address indexed user, uint shares);
    event RewardPaid(address indexed user, uint reward);
    event RewardStaked(address indexed user, uint reward);
    event RewardsDurationUpdated(uint newDuration);
    event Recovered(address token, uint amount);
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"address","name":"_stakingToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lock","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Unlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawn","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"availableOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"lockPeriod","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"depositOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"lockShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"lockedFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"lockedOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"a","type":"uint256"},{"internalType":"uint256","name":"b","type":"uint256"}],"name":"min","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"multiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minimumLock","type":"uint256"},{"internalType":"uint256","name":"_maximumLock","type":"uint256"}],"name":"setLockingPeriods","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_multiplier","type":"uint256"}],"name":"setMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"setRewardsDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_withdrawalFee","type":"uint256"}],"name":"setWithdrawalFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"togglePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"togglePrivatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDeposited","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","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":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"unlockShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unlockedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawalFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawalFeeMax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405273b565a72868a70da734da10e3750196dd82cb7f16600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006006556000600755630784ce00600855604b6017556101f460185561271060195562127500601a556301dfe200601b556005601c553480156200009d57600080fd5b5060405162005918380380620059188339818101604052810190620000c391906200038e565b6001600081905550620000eb620000df6200022c60201b60201c565b6200023460201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff1662000113620002fa60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16036200016c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001639062000436565b60405180910390fd5b81600360016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614620002245780600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505062000458565b600033905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620003568262000329565b9050919050565b620003688162000349565b81146200037457600080fd5b50565b60008151905062000388816200035d565b92915050565b60008060408385031215620003a857620003a762000324565b5b6000620003b88582860162000377565b9250506020620003cb8582860162000377565b9150509250929050565b600082825260208201905092915050565b7f4f776e6572206d75737420626520736574000000000000000000000000000000600082015250565b60006200041e601183620003d5565b91506200042b82620003e6565b602082019050919050565b6000602082019050818103600083015262000451816200040f565b9050919050565b6154b080620004686000396000f3fe608060405234801561001057600080fd5b50600436106102d55760003560e01c80637b0a47ee11610182578063cc1a378f116100e9578063e9fad8ee116100a2578063f2fde38b1161007c578063f2fde38b14610872578063f9255c641461088e578063fa43a10e146108be578063ff50abdc146108dc576102d5565b8063e9fad8ee1461082e578063ebe2b12b14610838578063f0f4426014610856576102d5565b8063cc1a378f1461076c578063cd3daf9d14610788578063d1af0c7d146107a6578063d546da90146107c4578063df136d65146107f4578063e2bbb15814610812576102d5565b80638f2542b21161013b5780638f2542b2146106ac57806391b4ded9146106c8578063a1757699146106e6578063a5f1e28214610702578063ac1e502514610732578063c8f33c911461074e576102d5565b80637b0a47ee146105e857806380faa57d146106065780638980f11f146106245780638b876347146106405780638bc7e8c4146106705780638da5cb5b1461068e576102d5565b806335e73c771161024157806361d027b3116101fa578063715018a6116101d4578063715018a61461057457806372f702f31461057e57806376467da01461059c5780637ae2b5c7146105b8576102d5565b806361d027b31461050a578063641579a61461052857806370a0823114610544576102d5565b806335e73c771461046e578063386a95251461048a5780633c6b16ab146104a85780633d18b912146104c457806356891412146104ce5780635c975abb146104ec576102d5565b80631b3ed722116102935780631b3ed7221461039a5780631c1f78eb146103b857806323e3fbd5146103d65780632cf5db13146104065780632e1a7d4d146104365780632f4f21e214610452576102d5565b80628cc262146102da57806305fbf4481461030a5780630700037d1461032657806314f47dcc1461035657806316c38b3c1461036057806318160ddd1461037c575b600080fd5b6102f460048036038101906102ef9190614223565b6108fa565b6040516103019190614269565b60405180910390f35b610324600480360381019061031f91906142b0565b610a18565b005b610340600480360381019061033b9190614223565b610df1565b60405161034d9190614269565b60405180910390f35b61035e610e09565b005b61037a60048036038101906103759190614328565b61103c565b005b6103846110e0565b6040516103919190614269565b60405180910390f35b6103a26110ea565b6040516103af9190614269565b60405180910390f35b6103c06110f0565b6040516103cd9190614269565b60405180910390f35b6103f060048036038101906103eb9190614223565b61110e565b6040516103fd9190614269565b60405180910390f35b610420600480360381019061041b9190614223565b611157565b60405161042d9190614269565b60405180910390f35b610450600480360381019061044b9190614355565b6111a0565b005b61046c600480360381019061046791906142b0565b61194a565b005b61048860048036038101906104839190614382565b611b5c565b005b610492611c6c565b60405161049f9190614269565b60405180910390f35b6104c260048036038101906104bd9190614355565b611c72565b005b6104cc612192565b005b6104d66123b8565b6040516104e39190614269565b60405180910390f35b6104f46123c2565b60405161050191906143d1565b60405180910390f35b6105126123d5565b60405161051f91906143fb565b60405180910390f35b610542600480360381019061053d9190614355565b6123fb565b005b61055e60048036038101906105599190614223565b61247a565b60405161056b9190614269565b60405180910390f35b61057c6124c3565b005b6105866124d7565b6040516105939190614475565b60405180910390f35b6105b660048036038101906105b191906142b0565b6124fd565b005b6105d260048036038101906105cd9190614382565b612835565b6040516105df9190614269565b60405180910390f35b6105f061284e565b6040516105fd9190614269565b60405180910390f35b61060e612854565b60405161061b9190614269565b60405180910390f35b61063e600480360381019061063991906142b0565b612867565b005b61065a60048036038101906106559190614223565b61296e565b6040516106679190614269565b60405180910390f35b610678612986565b6040516106859190614269565b60405180910390f35b61069661298c565b6040516106a391906143fb565b60405180910390f35b6106c660048036038101906106c19190614223565b6129b6565b005b6106d0612ad2565b6040516106dd9190614269565b60405180910390f35b61070060048036038101906106fb9190614223565b612ad8565b005b61071c60048036038101906107179190614223565b612bf4565b6040516107299190614269565b60405180910390f35b61074c60048036038101906107479190614355565b612c3d565b005b610756612d01565b6040516107639190614269565b60405180910390f35b61078660048036038101906107819190614355565b612d07565b005b610790612e03565b60405161079d9190614269565b60405180910390f35b6107ae612e90565b6040516107bb9190614475565b60405180910390f35b6107de60048036038101906107d99190614223565b612eb6565b6040516107eb9190614269565b60405180910390f35b6107fc612f50565b6040516108099190614269565b60405180910390f35b61082c60048036038101906108279190614382565b612f56565b005b61083661367d565b005b6108406136cf565b60405161084d9190614269565b60405180910390f35b610870600480360381019061086b9190614223565b6136d5565b005b61088c60048036038101906108879190614223565b61381e565b005b6108a860048036038101906108a39190614223565b6138a1565b6040516108b59190614269565b60405180910390f35b6108c66138ea565b6040516108d39190614269565b60405180910390f35b6108e46138f0565b6040516108f19190614269565b60405180910390f35b6000610a11600c60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610a03670de0b6b3a76400006109f56109a7600b60008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610999612e03565b6138fa90919063ffffffff16565b601060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461391090919063ffffffff16565b61392690919063ffffffff16565b61393c90919063ffffffff16565b9050919050565b600360009054906101000a900460ff1615610a68576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a5f90614513565b60405180910390fd5b81610a71612e03565b600a81905550610a7f612854565b600981905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610b4c57610ac2816108fa565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a54600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b60008211610b8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b869061457f565b60405180910390fd5b601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610c1b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c12906145eb565b60405180910390fd5b81610cad601260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054601060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546138fa90919063ffffffff16565b1015610cee576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce590614657565b60405180910390fd5b610d4082601260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461393c90919063ffffffff16565b601260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610d9882600f5461393c90919063ffffffff16565b600f819055508273ffffffffffffffffffffffffffffffffffffffff167f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd6000883604051610de49190614269565b60405180910390a2505050565b600c6020528060005260406000206000915090505481565b610e11613952565b600360009054906101000a900460ff1615610e61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5890614513565b60405180910390fd5b33610e6a612e03565b600a81905550610e78612854565b600981905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f4557610ebb816108fa565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a54600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506000811115611030576000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610fe133826139a1565b3373ffffffffffffffffffffffffffffffffffffffff167f7d3a0ab251dfd8c04c691239edd99d2c124cce6971cebc4c2ed96a378d13d500826040516110279190614269565b60405180910390a25b505061103a613cc7565b565b611044613cd1565b600360009054906101000a900460ff16151581151503156110dd5780600360006101000a81548160ff021916908315150217905550600360009054906101000a900460ff161561109657426002819055505b7f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5600360009054906101000a900460ff166040516110d491906143d1565b60405180910390a15b50565b6000600d54905090565b601c5481565b600061110960085460075461391090919063ffffffff16565b905090565b6000601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000601460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6111a8613952565b336111b1612e03565b600a819055506111bf612854565b600981905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461128c57611202816108fa565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a54600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b600082116112cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c6906146c3565b60405180910390fd5b6000601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411611351576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113489061472f565b60405180910390fd5b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211156113d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ca9061479b565b60405180910390fd5b601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054421015611455576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144c90614807565b60405180910390fd5b60006114c3601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546114b5670de0b6b3a76400008661391090919063ffffffff16565b61392690919063ffffffff16565b90506000611533670de0b6b3a764000061152584601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461391090919063ffffffff16565b61392690919063ffffffff16565b9050601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548111156115bf57601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b80611651601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546138fa90919063ffffffff16565b1015611692576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161168990614657565b60405180910390fd5b6116e484601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546138fa90919063ffffffff16565b601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061173c84600e546138fa90919063ffffffff16565b600e8190555061179481601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546138fa90919063ffffffff16565b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506117ec81600d546138fa90919063ffffffff16565b600d81905550600061181d60195461180f6017548861391090919063ffffffff16565b61392690919063ffffffff16565b905061188e600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613d4f9092919063ffffffff16565b6118ed336118a583886138fa90919063ffffffff16565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613d4f9092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5866040516119339190614269565b60405180910390a250505050611947613cc7565b50565b600360009054906101000a900460ff161561199a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199190614513565b60405180910390fd5b816119a3612e03565b600a819055506119b1612854565b600981905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611a7e576119f4816108fa565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a54600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b60008211611ac1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab890614873565b60405180910390fd5b601560003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16611b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b44906148df565b60405180910390fd5b611b5783836139a1565b505050565b611b6461298c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611bd1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bc89061494b565b60405180910390fd5b6301dfe200811115611c18576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0f906149b7565b60405180910390fd5b808210611c5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5190614a23565b60405180910390fd5b81601a8190555080601b819055505050565b60085481565b611c7a61298c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ce7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cde9061494b565b60405180910390fd5b6000611cf1612e03565b600a81905550611cff612854565b600981905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611dcc57611d42816108fa565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a54600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611e2991906143fb565b602060405180830381865afa158015611e46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e6a9190614a58565b9050611ebb333085600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613dd5909392919063ffffffff16565b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611f1891906143fb565b602060405180830381865afa158015611f35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f599190614a58565b905060008282611f699190614ab4565b9050848114611fad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fa490614b5a565b60405180910390fd5b6006544210611fd657611fcb6008548661392690919063ffffffff16565b600781905550612038565b6000611fed426006546138fa90919063ffffffff16565b905060006120066007548361391090919063ffffffff16565b905061202f600854612021838a61393c90919063ffffffff16565b61392690919063ffffffff16565b60078190555050505b6000600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161209591906143fb565b602060405180830381865afa1580156120b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d69190614a58565b90506120ed6008548261392690919063ffffffff16565b6007541115612131576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161212890614bc6565b60405180910390fd5b4260098190555061214d6008544261393c90919063ffffffff16565b6006819055507fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d866040516121829190614269565b60405180910390a1505050505050565b61219a613952565b336121a3612e03565b600a819055506121b1612854565b600981905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461227e576121f4816108fa565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a54600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008111156123ac576000600c60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061235d3382600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613d4f9092919063ffffffff16565b3373ffffffffffffffffffffffffffffffffffffffff167fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486826040516123a39190614269565b60405180910390a25b50506123b6613cc7565b565b6000600f54905090565b600360009054906101000a900460ff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b61240361298c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612470576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124679061494b565b60405180910390fd5b80601c8190555050565b6000601060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6124cb613cd1565b6124d56000613e5e565b565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b81612506612e03565b600a81905550612514612854565b600981905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146125e157612557816108fa565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a54600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b60008211612624576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261b9061457f565b60405180910390fd5b601660003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166126b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a7906145eb565b60405180910390fd5b81601260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015612732576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161272990614657565b60405180910390fd5b61278482601260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546138fa90919063ffffffff16565b601260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506127dc82600f546138fa90919063ffffffff16565b600f819055508273ffffffffffffffffffffffffffffffffffffffff167f0f0bc5b519ddefdd8e5f9e6423433aa2b869738de2ae34d58ebc796fc749fa0d836040516128289190614269565b60405180910390a2505050565b60008183106128445781612846565b825b905092915050565b60075481565b600061286242600654612835565b905090565b61286f613cd1565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036128ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f690614c58565b60405180910390fd5b61293161290a61298c565b828473ffffffffffffffffffffffffffffffffffffffff16613d4f9092919063ffffffff16565b7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288282604051612962929190614c78565b60405180910390a15050565b600b6020528060005260406000206000915090505481565b60175481565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6129be61298c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612a2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a229061494b565b60405180910390fd5b601660008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615601660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60025481565b612ae061298c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b449061494b565b60405180910390fd5b601560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615601560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b612c4561298c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612cb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ca99061494b565b60405180910390fd5b601854811115612cf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cee90614ced565b60405180910390fd5b8060178190555050565b60095481565b612d0f61298c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612d7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d739061494b565b60405180910390fd5b6006544211612dc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612db790614da5565b60405180910390fd5b806008819055507ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d3600854604051612df89190614269565b60405180910390a150565b600080600d5403612e1857600a549050612e8d565b612e8a612e79600d54612e6b670de0b6b3a7640000612e5d600754612e4f600954612e41612854565b6138fa90919063ffffffff16565b61391090919063ffffffff16565b61391090919063ffffffff16565b61392690919063ffffffff16565b600a5461393c90919063ffffffff16565b90505b90565b600360019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000612f49601260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054601060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546138fa90919063ffffffff16565b9050919050565b600a5481565b612f5e613952565b600360009054906101000a900460ff1615612fae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612fa590614513565b60405180910390fd5b33612fb7612e03565b600a81905550612fc5612854565b600981905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161461309257613008816108fa565b600c60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600a54600b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b600083116130d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016130cc90614873565b60405180910390fd5b601a5482101561311a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161311190614e11565b60405180910390fd5b6000601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411156131e557601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548210156131e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016131db90614e7d565b60405180910390fd5b5b601b548211156131f557601b5491505b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161325291906143fb565b602060405180830381865afa15801561326f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132939190614a58565b90506132e4333086600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613dd5909392919063ffffffff16565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161334191906143fb565b602060405180830381865afa15801561335e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133829190614a58565b9050600061339983836138fa90919063ffffffff16565b905060006133ef82601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461393c90919063ffffffff16565b905060008061343e6064613430601c5461342262093a80601a548e6134149190614ab4565b61392690919063ffffffff16565b61391090919063ffffffff16565b61393c90919063ffffffff16565b90506134666064613458838661391090919063ffffffff16565b61392690919063ffffffff16565b915082601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506134c184600e5461393c90919063ffffffff16565b600e8190555061351b601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600d546138fa90919063ffffffff16565b600d8190555081601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061357a82600d5461393c90919063ffffffff16565b600d8190555087601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506135d7884261393c90919063ffffffff16565b601460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff167f73a19dd210f1a7f902193214c0ee91dd35ee5b4d920cba8d519eca65a7b488ca858a604051613662929190614e9d565b60405180910390a250505050505050613679613cc7565b5050565b6136c5601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546111a0565b6136cd612192565b565b60065481565b6136dd61298c565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461374a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137419061494b565b60405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146137da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137d190614f12565b60405180910390fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b613826613cd1565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603613895576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161388c90614fa4565b60405180910390fd5b61389e81613e5e565b50565b6000601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b60185481565b6000600e54905090565b600081836139089190614ab4565b905092915050565b6000818361391e9190614fc4565b905092915050565b600081836139349190615035565b905092915050565b6000818361394a9190615066565b905092915050565b600260005403613997576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161398e906150e6565b60405180910390fd5b6002600081905550565b6000601360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050600081111580613a3557506000601160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411155b15613ada57601a54905080601360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613a96814261393c90919063ffffffff16565b601460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b6000613b2e83601160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461393c90919063ffffffff16565b9050600080613b7d6064613b6f601c54613b6162093a80601a548a613b539190614ab4565b61392690919063ffffffff16565b61391090919063ffffffff16565b61393c90919063ffffffff16565b9050613ba56064613b97838661391090919063ffffffff16565b61392690919063ffffffff16565b915082601160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613c0085600e5461393c90919063ffffffff16565b600e81905550613c5a601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600d546138fa90919063ffffffff16565b600d8190555081601060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613cb982600d5461393c90919063ffffffff16565b600d81905550505050505050565b6001600081905550565b613cd9613f24565b73ffffffffffffffffffffffffffffffffffffffff16613cf761298c565b73ffffffffffffffffffffffffffffffffffffffff1614613d4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d4490615152565b60405180910390fd5b565b613dd08363a9059cbb60e01b8484604051602401613d6e929190614c78565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613f2c565b505050565b613e58846323b872dd60e01b858585604051602401613df693929190615172565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613f2c565b50505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b6000613f8e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16613ff39092919063ffffffff16565b9050600081511115613fee5780806020019051810190613fae91906151be565b613fed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613fe49061525d565b60405180910390fd5b5b505050565b6060614002848460008561400b565b90509392505050565b606082471015614050576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614047906152ef565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516140799190615380565b60006040518083038185875af1925050503d80600081146140b6576040519150601f19603f3d011682016040523d82523d6000602084013e6140bb565b606091505b50915091506140cc878383876140d8565b92505050949350505050565b6060831561413a576000835103614132576140f28561414d565b614131576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614128906153e3565b60405180910390fd5b5b829050614145565b6141448383614170565b5b949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000825111156141835781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016141b79190615458565b60405180910390fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006141f0826141c5565b9050919050565b614200816141e5565b811461420b57600080fd5b50565b60008135905061421d816141f7565b92915050565b600060208284031215614239576142386141c0565b5b60006142478482850161420e565b91505092915050565b6000819050919050565b61426381614250565b82525050565b600060208201905061427e600083018461425a565b92915050565b61428d81614250565b811461429857600080fd5b50565b6000813590506142aa81614284565b92915050565b600080604083850312156142c7576142c66141c0565b5b60006142d58582860161420e565b92505060206142e68582860161429b565b9150509250929050565b60008115159050919050565b614305816142f0565b811461431057600080fd5b50565b600081359050614322816142fc565b92915050565b60006020828403121561433e5761433d6141c0565b5b600061434c84828501614313565b91505092915050565b60006020828403121561436b5761436a6141c0565b5b60006143798482850161429b565b91505092915050565b60008060408385031215614399576143986141c0565b5b60006143a78582860161429b565b92505060206143b88582860161429b565b9150509250929050565b6143cb816142f0565b82525050565b60006020820190506143e660008301846143c2565b92915050565b6143f5816141e5565b82525050565b600060208201905061441060008301846143ec565b92915050565b6000819050919050565b600061443b614436614431846141c5565b614416565b6141c5565b9050919050565b600061444d82614420565b9050919050565b600061445f82614442565b9050919050565b61446f81614454565b82525050565b600060208201905061448a6000830184614466565b92915050565b600082825260208201905092915050565b7f5468697320616374696f6e2063616e6e6f7420626520706572666f726d65642060008201527f7768696c652074686520636f6e74726163742069732070617573656400000000602082015250565b60006144fd603c83614490565b9150614508826144a1565b604082019050919050565b6000602082019050818103600083015261452c816144f0565b9050919050565b7f2173686172657300000000000000000000000000000000000000000000000000600082015250565b6000614569600783614490565b915061457482614533565b602082019050919050565b600060208201905081810360008301526145988161455c565b9050919050565b7f2170726976617465000000000000000000000000000000000000000000000000600082015250565b60006145d5600883614490565b91506145e08261459f565b602082019050919050565b60006020820190508181036000830152614604816145c8565b9050919050565b7f216c6f636b656400000000000000000000000000000000000000000000000000600082015250565b6000614641600783614490565b915061464c8261460b565b602082019050919050565b6000602082019050818103600083015261467081614634565b9050919050565b7f2177697468647261772d30000000000000000000000000000000000000000000600082015250565b60006146ad600b83614490565b91506146b882614677565b602082019050919050565b600060208201905081810360008301526146dc816146a0565b9050919050565b7f2177697468647261772d6e6f7374616b65000000000000000000000000000000600082015250565b6000614719601183614490565b9150614724826146e3565b602082019050919050565b600060208201905081810360008301526147488161470c565b9050919050565b7f2177697468647261772d616d6f756e7400000000000000000000000000000000600082015250565b6000614785601083614490565b91506147908261474f565b602082019050919050565b600060208201905081810360008301526147b481614778565b9050919050565b7f2177697468647261772d6c6f636b000000000000000000000000000000000000600082015250565b60006147f1600e83614490565b91506147fc826147bb565b602082019050919050565b60006020820190508181036000830152614820816147e4565b9050919050565b7f217374616b652d30000000000000000000000000000000000000000000000000600082015250565b600061485d600883614490565b915061486882614827565b602082019050919050565b6000602082019050818103600083015261488c81614850565b9050919050565b7f21706f6f6c000000000000000000000000000000000000000000000000000000600082015250565b60006148c9600583614490565b91506148d482614893565b602082019050919050565b600060208201905081810360008301526148f8816148bc565b9050919050565b7f2172657374726963746564000000000000000000000000000000000000000000600082015250565b6000614935600b83614490565b9150614940826148ff565b602082019050919050565b6000602082019050818103600083015261496481614928565b9050919050565b7f216d6178696d756d4c6f636b0000000000000000000000000000000000000000600082015250565b60006149a1600c83614490565b91506149ac8261496b565b602082019050919050565b600060208201905081810360008301526149d081614994565b9050919050565b7f216d696e4c6f636b3e6d61784c6f636b00000000000000000000000000000000600082015250565b6000614a0d601083614490565b9150614a18826149d7565b602082019050919050565b60006020820190508181036000830152614a3c81614a00565b9050919050565b600081519050614a5281614284565b92915050565b600060208284031215614a6e57614a6d6141c0565b5b6000614a7c84828501614a43565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614abf82614250565b9150614aca83614250565b9250828203905081811115614ae257614ae1614a85565b5b92915050565b7f57686974656c6973742074686520706f6f6c20746f206578636c75646520666560008201527f6573000000000000000000000000000000000000000000000000000000000000602082015250565b6000614b44602283614490565b9150614b4f82614ae8565b604082019050919050565b60006020820190508181036000830152614b7381614b37565b9050919050565b7f50726f76696465642072657761726420746f6f20686967680000000000000000600082015250565b6000614bb0601883614490565b9150614bbb82614b7a565b602082019050919050565b60006020820190508181036000830152614bdf81614ba3565b9050919050565b7f43616e6e6f7420776974686472617720746865207374616b696e67206f72207260008201527f65776172647320746f6b656e7300000000000000000000000000000000000000602082015250565b6000614c42602d83614490565b9150614c4d82614be6565b604082019050919050565b60006020820190508181036000830152614c7181614c35565b9050919050565b6000604082019050614c8d60008301856143ec565b614c9a602083018461425a565b9392505050565b7f217769746864726177616c466565000000000000000000000000000000000000600082015250565b6000614cd7600e83614490565b9150614ce282614ca1565b602082019050919050565b60006020820190508181036000830152614d0681614cca565b9050919050565b7f50726576696f7573207265776172647320706572696f64206d7573742062652060008201527f636f6d706c657465206265666f7265206368616e67696e67207468652064757260208201527f6174696f6e20666f7220746865206e657720706572696f640000000000000000604082015250565b6000614d8f605883614490565b9150614d9a82614d0d565b606082019050919050565b60006020820190508181036000830152614dbe81614d82565b9050919050565b7f217374616b652d3c327765656b73000000000000000000000000000000000000600082015250565b6000614dfb600e83614490565b9150614e0682614dc5565b602082019050919050565b60006020820190508181036000830152614e2a81614dee565b9050919050565b7f217374616b652d6c6f636b000000000000000000000000000000000000000000600082015250565b6000614e67600b83614490565b9150614e7282614e31565b602082019050919050565b60006020820190508181036000830152614e9681614e5a565b9050919050565b6000604082019050614eb2600083018561425a565b614ebf602083018461425a565b9392505050565b7f2174726561737572790000000000000000000000000000000000000000000000600082015250565b6000614efc600983614490565b9150614f0782614ec6565b602082019050919050565b60006020820190508181036000830152614f2b81614eef565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614f8e602683614490565b9150614f9982614f32565b604082019050919050565b60006020820190508181036000830152614fbd81614f81565b9050919050565b6000614fcf82614250565b9150614fda83614250565b9250828202614fe881614250565b91508282048414831517614fff57614ffe614a85565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061504082614250565b915061504b83614250565b92508261505b5761505a615006565b5b828204905092915050565b600061507182614250565b915061507c83614250565b925082820190508082111561509457615093614a85565b5b92915050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006150d0601f83614490565b91506150db8261509a565b602082019050919050565b600060208201905081810360008301526150ff816150c3565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061513c602083614490565b915061514782615106565b602082019050919050565b6000602082019050818103600083015261516b8161512f565b9050919050565b600060608201905061518760008301866143ec565b61519460208301856143ec565b6151a1604083018461425a565b949350505050565b6000815190506151b8816142fc565b92915050565b6000602082840312156151d4576151d36141c0565b5b60006151e2848285016151a9565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000615247602a83614490565b9150615252826151eb565b604082019050919050565b600060208201905081810360008301526152768161523a565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006152d9602683614490565b91506152e48261527d565b604082019050919050565b60006020820190508181036000830152615308816152cc565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615343578082015181840152602081019050615328565b60008484015250505050565b600061535a8261530f565b615364818561531a565b9350615374818560208601615325565b80840191505092915050565b600061538c828461534f565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006153cd601d83614490565b91506153d882615397565b602082019050919050565b600060208201905081810360008301526153fc816153c0565b9050919050565b600081519050919050565b6000601f19601f8301169050919050565b600061542a82615403565b6154348185614490565b9350615444818560208601615325565b61544d8161540e565b840191505092915050565b60006020820190508181036000830152615472818461541f565b90509291505056fea2646970667358221220bf65ad8de846cca95565baabae2684c8bac64af598d0b96937299eb07daca4fd64736f6c63430008130033000000000000000000000000a0eebb0e5c3859a1c5412c2380c074f2f6725e2e000000000000000000000000a0eebb0e5c3859a1c5412c2380c074f2f6725e2e

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

000000000000000000000000a0eebb0e5c3859a1c5412c2380c074f2f6725e2e000000000000000000000000a0eebb0e5c3859a1c5412c2380c074f2f6725e2e

-----Decoded View---------------
Arg [0] : _rewardsToken (address): 0xa0eebb0e5c3859a1c5412c2380c074f2f6725e2e
Arg [1] : _stakingToken (address): 0xa0eebb0e5c3859a1c5412c2380c074f2f6725e2e

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


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