Contract 0x80789d252a288e93b01d82373d767d71a75d9f16 1

 

Contract Overview

Dopex: veDPX
Balance:
0 ETH

ETH Value:
$0.00

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x781d536592b6985adea00dbfdf28c8d2de6f7e251c086b7ed6fb750de18d364dCreate_lock438951422022-12-05 19:45:4934 mins ago0xfaf17da56c797dad9cbde6b6ebd61d09ed4e75dc IN  Dopex: veDPX0 ETH0.00005924
0xaf512c2ae3e37e22f921c4bff28cc46bfad2276bff74bb1fee30b9a5864bd02cCreate_lock438950342022-12-05 19:45:1035 mins ago0x52b4868b362adc3365b9a110ecbfe71e2b36bab2 IN  Dopex: veDPX0 ETH0.00005924
0x4ae4918912401f3a5e647d94f05a0699b01faaa0e31503bdab3bc2c295e5bff2Create_lock438938192022-12-05 19:38:1842 mins ago0x26dcf8f68f806ce71082bce6c46d843f7db1e65c IN  Dopex: veDPX0 ETH0.00005575
0xc64f59609166050edcde7057be1a2bbcd42d46f2c3648026017247e2077fce7aCreate_lock438928762022-12-05 19:33:2847 mins ago0xc8799a66ce56b6317bd26d9b43522234038ee80c IN  Dopex: veDPX0 ETH0.00004877
0xdccaecbb2f4dcc74668cace550dd7837d8aa00372a265f3d7c0c7f87182970bcCreate_lock438915642022-12-05 19:26:5253 mins ago0x3f3054acb590148d33dbcd4f2a2ba60cf27d4868 IN  Dopex: veDPX0 ETH0.00004928
0x2e2e6f937a15468ed0dd5130e085dd064836293069ed2b9bb9cf6464fe6a6a84Create_lock438904942022-12-05 19:21:4158 mins ago0x9430841140050f2d96269eeb7387b989bd9056e9 IN  Dopex: veDPX0 ETH0.00005098
0x41b913fa939acd5930bbcdbf6e83f88cc06fbb3b834fc37e98edfbfb988cbf85Create_lock438872972022-12-05 19:05:431 hr 14 mins ago0x444a3511b082fcdb7fc38b4ae4b514c05cce4bec IN  Dopex: veDPX0 ETH0.00005166
0x035440bb946ffae491615a95bda2594fabf8ed5ab4dfa8d393f3973db1ec8b66Create_lock438852932022-12-05 18:55:071 hr 25 mins ago0x922629f4d6eb62d09941f6e03d93006791bdf670 IN  Dopex: veDPX0 ETH0.00005095
0xeda8bbef833b614e1e4fe0f510cba80a5170581bec9d1c79b65e0e796e72e19bCreate_lock438843912022-12-05 18:50:251 hr 30 mins ago0xdceeb0e5a4e8090c3fd30eca413c1a5282281d13 IN  Dopex: veDPX0 ETH0.00005095
0xe08f67d5b1684224786171da204d35e477e31acdaab013dbdde93acb7ed1613bCreate_lock438826862022-12-05 18:41:521 hr 38 mins ago0x5612a14174c1743f32ee73783ba43afabf63a281 IN  Dopex: veDPX0 ETH0.00005267
0x9b4aa86f4d4c241c36ab9c805d5a2316d5d208153810e7a1312fbf16f80f3e1dCreate_lock438815112022-12-05 18:36:141 hr 44 mins ago0x12f1a20e79ad85476dace0918ef012a3d69189e7 IN  Dopex: veDPX0 ETH0.00005171
0x441f9617ecc10f1a0174d83d5b29ebbc7e34dcae0bd79cbb1ad03d9c82878641Create_lock438806932022-12-05 18:32:161 hr 48 mins ago0x56463d50e1d58b2036b0dad19784df57d1aa6e9b IN  Dopex: veDPX0 ETH0.00005074
0x30ad479a11b0a144af64429b9cc62923e47e7d6618538edcbd69a6b001970f2bWithdraw438803212022-12-05 18:30:251 hr 50 mins ago0x56463d50e1d58b2036b0dad19784df57d1aa6e9b IN  Dopex: veDPX0 ETH0.00003478
0x0a5eade020927b9eabdd1d333fb637e94ccc0860a95c61d81f5da79480031b00Increase_unlock_...438800282022-12-05 18:28:541 hr 51 mins ago0x7a16e350ab5929a40cd9a6f51957d5a45a6e361b IN  Dopex: veDPX0 ETH0.00003972
0x09293ce480fa3d287d5a8540b85b73bb346b4103f4d1b23d472599fb5a103546Create_lock438785142022-12-05 18:21:181 hr 59 mins ago0x2fa9c2f0e50800fb9a826b0a3cd0383df1ed9ff8 IN  Dopex: veDPX0 ETH0.00005018
0x451ab676b12155326d97573a83215d3012965823c15c126c8db58be83c250924Increase_amount438618782022-12-05 17:00:573 hrs 19 mins ago0x7f2fccaf717128bdf5efabd67a8ea9a812d5813e IN  Dopex: veDPX0 ETH0.00004954
0x4b84c38a9d205391070f0bf7ac097402d673230760ef7ebee96318082123d004Increase_amount438599402022-12-05 16:51:433 hrs 28 mins ago0x518613775c7583b68ed4d1e849bf99610363a3df IN  Dopex: veDPX0 ETH0.00005212
0xfc8a13a19278f75c1350309195183f9fc17da5a4ffde12ea3db6781e49c786e0Create_lock438425332022-12-05 15:30:034 hrs 50 mins ago0x943afd7f245fec672ae52294b8c41f634cf2429e IN  Dopex: veDPX0 ETH0.00007014
0x15d2154cfe5fefe4fead21edd1beb9113aa793c323077665af81b59632d008c6Create_lock438400072022-12-05 15:18:595 hrs 1 min ago0xa7f17fdfadd349da1533c01784eeb59c9c6deb6f IN  Dopex: veDPX0 ETH0.00004347
0x95b836090358d7eb0b1f18dd3e6c0aae69e6258d8a26fbc0d5ac79d0a4adf035Increase_amount438306682022-12-05 14:38:215 hrs 42 mins ago0x07874782e4a5c9d20fdad003082a60a4dfe2ea29 IN  Dopex: veDPX0 ETH0.00003716
0x9376e4a25e817cb71c07e8a2bd1c40ca8231852c81649f3afe398de51cbc797bCreate_lock438242412022-12-05 14:10:386 hrs 9 mins ago0xfb1d2eba21b0b58523f36041348c0a2e6c830eb5 IN  Dopex: veDPX0 ETH0.00004297
0x61f770f1bd86b35bc2bd592648c7aeb25c4b54835a8b12f4c97d942f8541216dIncrease_amount_...438233892022-12-05 14:07:016 hrs 13 mins ago0x6af5be7d013766f201bbd9377287b303488fc691 IN  Dopex: veDPX0 ETH0.00005428
0x848b6c175b53d0dc31cd670e3cf81d62fc556c90cf1964908d4c5fe6fdbb9f0dCreate_lock438170822022-12-05 13:40:056 hrs 40 mins ago0x1facc5303e0dcab71f878309c21cac6f8daba040 IN  Dopex: veDPX0 ETH0.00004437
0x7dd568d028d373d7d1346461d3e069e5e6aacb7b864bd205afa28c28b92e4d7cCreate_lock437764132022-12-05 10:38:069 hrs 42 mins ago0x9570904d5e47940e65b8dbf8f34cd215a036c700 IN  Dopex: veDPX0 ETH0.0000464
0x599ea478dfabe2434414c0d989194599c84a7cf6aaf4a9f5860c0f540b54ea56Increase_amount_...437712532022-12-05 10:07:4010 hrs 12 mins ago0xa73018c8c64d8b58f692da632255c8ac907c8d58 IN  Dopex: veDPX0 ETH0.00005596
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xe2d801b781f86e713bf15302060a90b29d4b4073d2c73bd13ff0faa8d5f62d62439006742022-12-05 20:16:104 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xe2d801b781f86e713bf15302060a90b29d4b4073d2c73bd13ff0faa8d5f62d62439006742022-12-05 20:16:104 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xe2d801b781f86e713bf15302060a90b29d4b4073d2c73bd13ff0faa8d5f62d62439006742022-12-05 20:16:104 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xe2d801b781f86e713bf15302060a90b29d4b4073d2c73bd13ff0faa8d5f62d62439006742022-12-05 20:16:104 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xe2d801b781f86e713bf15302060a90b29d4b4073d2c73bd13ff0faa8d5f62d62439006742022-12-05 20:16:104 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x4898f5b06cc6f645b12dd27508bc81bb0fd1d9b9f8671ede0b8b0e0da146d16d439000322022-12-05 20:12:298 mins ago Dopex: veDPXDopex: DPX Token0 ETH
0x4898f5b06cc6f645b12dd27508bc81bb0fd1d9b9f8671ede0b8b0e0da146d16d439000322022-12-05 20:12:298 mins ago 0x6de5bec59ed2575a799f2ac0a0aeaaaf59e61c3d Dopex: veDPX0 ETH
0x7f752bc8448a4d23de4cf19206426cf20eb2d1b09a664014a95cc2719628d183438994442022-12-05 20:09:0811 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x7f752bc8448a4d23de4cf19206426cf20eb2d1b09a664014a95cc2719628d183438994442022-12-05 20:09:0811 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x7f752bc8448a4d23de4cf19206426cf20eb2d1b09a664014a95cc2719628d183438994442022-12-05 20:09:0811 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x7f752bc8448a4d23de4cf19206426cf20eb2d1b09a664014a95cc2719628d183438994442022-12-05 20:09:0811 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x7f752bc8448a4d23de4cf19206426cf20eb2d1b09a664014a95cc2719628d183438994442022-12-05 20:09:0811 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xeb0648364e8f06e20ced6c7b764e0e2742e878d8a9d4aa47977244389dcec0e7438994052022-12-05 20:08:5311 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xeb0648364e8f06e20ced6c7b764e0e2742e878d8a9d4aa47977244389dcec0e7438994052022-12-05 20:08:5311 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xeb0648364e8f06e20ced6c7b764e0e2742e878d8a9d4aa47977244389dcec0e7438994052022-12-05 20:08:5311 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xeb0648364e8f06e20ced6c7b764e0e2742e878d8a9d4aa47977244389dcec0e7438994052022-12-05 20:08:5311 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xeb0648364e8f06e20ced6c7b764e0e2742e878d8a9d4aa47977244389dcec0e7438994052022-12-05 20:08:5311 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x32ecc33faca06accaa860d43ff111ab2059eb71f3d5d4899f97543ca1e5b6e9c438991472022-12-05 20:07:3213 mins ago Dopex: veDPXDopex: DPX Token0 ETH
0x32ecc33faca06accaa860d43ff111ab2059eb71f3d5d4899f97543ca1e5b6e9c438991472022-12-05 20:07:3213 mins ago 0x6de5bec59ed2575a799f2ac0a0aeaaaf59e61c3d Dopex: veDPX0 ETH
0x4b6f6dd02073c81b62375506a00ee7a000096f1d72c8d256a78acf3e4b65d151438989552022-12-05 20:06:3214 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x4b6f6dd02073c81b62375506a00ee7a000096f1d72c8d256a78acf3e4b65d151438989552022-12-05 20:06:3214 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x4b6f6dd02073c81b62375506a00ee7a000096f1d72c8d256a78acf3e4b65d151438989552022-12-05 20:06:3214 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x4b6f6dd02073c81b62375506a00ee7a000096f1d72c8d256a78acf3e4b65d151438989552022-12-05 20:06:3214 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0x4b6f6dd02073c81b62375506a00ee7a000096f1d72c8d256a78acf3e4b65d151438989552022-12-05 20:06:3214 mins ago Dopex: veDPX Yield Distributor Dopex: veDPX0 ETH
0xd2a8d2993d0c3d39f3d8544ab8f37ca74bac2f9fdcb61db74679f1a4526b1b6e438986992022-12-05 20:05:0615 mins ago Dopex: veDPXDopex: DPX Token0 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DPXVotingEscrow

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        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 8 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/IERC20.sol";

File 3 of 8 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

File 4 of 8 : 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 8 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.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));
        }
    }

    /**
     * @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 8 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.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 functionCall(target, data, "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");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason 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 {
            // 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 7 of 8 : 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 8 : DPXVotingEscrow.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

/**
@title Voting Escrow
@author Curve Finance
@license MIT
@notice Votes have a weight depending on time, so that users are
        committed to the future of (whatever they are voting for)
@dev Vote weight decays linearly over time. Lock time cannot be
     more than `MAXTIME` (4 years).

# Voting escrow to have time-weighted votes
# Votes have a weight depending on time, so that users are committed
# to the future of (whatever they are voting for).
# The weight in this implementation is linear, and lock cannot be more than maxtime:
# w ^
# 1 +        /
#   |      /
#   |    /
#   |  /
#   |/
# 0 +--------+------> time
#       maxtime (4 years?)
*/

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { ReentrancyGuard } from "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

struct Point {
  int128 bias;
  int128 slope; // # -dweight / dt
  uint256 ts;
  uint256 blk; // block
}
/* We cannot really do block numbers per se b/c slope is per time, not per block
 * and per block could be fairly bad b/c Ethereum changes blocktimes.
 * What we can do is to extrapolate ***At functions */

struct LockedBalance {
  int128 amount;
  uint256 end;
}

contract DPXVotingEscrow is Ownable, ReentrancyGuard {
  using SafeERC20 for IERC20;

  enum DepositType {
    DEPOSIT_FOR_TYPE,
    CREATE_LOCK_TYPE,
    INCREASE_LOCK_AMOUNT,
    INCREASE_UNLOCK_TIME
  }

  event Deposit(
    address indexed provider,
    uint256 value,
    uint256 indexed locktime,
    DepositType deposit_type,
    uint256 ts
  );
  event Withdraw(address indexed provider, uint256 value, uint256 ts);
  event Supply(uint256 prevSupply, uint256 supply);

  uint256 internal constant WEEK = 1 weeks;
  uint256 public constant MAXTIME = 4 * 365 * 86400;
  int128 internal constant iMAXTIME = 4 * 365 * 86400;
  uint256 internal constant MULTIPLIER = 1 ether;

  uint256 public immutable MINTIME;
  address public immutable token;
  uint256 public supply;
  bool public unlocked;

  mapping(address => LockedBalance) public locked;

  uint256 public epoch;
  mapping(uint256 => Point) public point_history; // epoch -> unsigned point
  mapping(address => Point[1000000000]) public user_point_history; // user -> Point[user_epoch]
  mapping(address => uint256) public user_point_epoch;
  mapping(uint256 => int128) public slope_changes; // time -> signed slope change

  string public constant name = "veDPX";
  string public constant symbol = "veDPX";
  string public constant version = "1.0.0";
  uint8 public constant decimals = 18;

  // Whitelisted (smart contract) wallets which are allowed to deposit
  // The goal is to prevent tokenizing the escrow
  mapping(address => bool) public contracts_whitelist;

  /// @notice Contract constructor
  /// @param token_addr `ERC20 DPX` token address
  constructor(address token_addr, uint256 min_time) {
    token = token_addr;
    point_history[0].blk = block.number;
    point_history[0].ts = block.timestamp;
    MINTIME = min_time;
  }

  modifier onlyUserOrWhitelist() {
    if (msg.sender != tx.origin) {
      require(contracts_whitelist[msg.sender], "Smart contract not allowed");
    }
    _;
  }

  modifier notUnlocked() {
    require(!unlocked, "unlocked globally");
    _;
  }

  /// @notice Add address to whitelist smart contract depositors `addr`
  /// @param addr Address to be whitelisted
  function add_to_whitelist(address addr) external onlyOwner {
    contracts_whitelist[addr] = true;
  }

  /// @notice Remove a smart contract address from whitelist
  /// @param addr Address to be removed from whitelist
  function remove_from_whitelist(address addr) external onlyOwner {
    contracts_whitelist[addr] = false;
  }

  /// @notice Unlock all locked balances
  function unlock() external onlyOwner {
    unlocked = true;
  }

  /// @notice Get the most recently recorded rate of voting power decrease for `_addr`
  /// @param addr Address of the user wallet
  /// @return Value of the slope
  function get_last_user_slope(address addr) external view returns (int128) {
    uint256 uepoch = user_point_epoch[addr];
    return user_point_history[addr][uepoch].slope;
  }

  /// @notice Get the timestamp for checkpoint `_idx` for `_addr`
  /// @param _addr User wallet address
  /// @param _idx User epoch number
  /// @return Epoch time of the checkpoint
  function user_point_history__ts(address _addr, uint256 _idx)
    external
    view
    returns (uint256)
  {
    return user_point_history[_addr][_idx].ts;
  }

  /// @notice Get timestamp when `_addr`'s lock finishes
  /// @param _addr User wallet address
  /// @return Epoch time of the lock end
  function locked__end(address _addr) external view returns (uint256) {
    return locked[_addr].end;
  }

  /// @notice Record global and per-user data to checkpoint
  /// @param _addr User's wallet address. No user checkpoint if 0x0
  /// @param old_locked Pevious locked amount / end lock time for the user
  /// @param new_locked New locked amount / end lock time for the user
  function _checkpoint(
    address _addr,
    LockedBalance memory old_locked,
    LockedBalance memory new_locked
  ) internal {
    Point memory u_old;
    Point memory u_new;
    int128 old_dslope = 0;
    int128 new_dslope = 0;
    uint256 _epoch = epoch;

    if (_addr != address(0x0)) {
      // Calculate slopes and biases
      // Kept at zero when they have to
      if (old_locked.end > block.timestamp && old_locked.amount > 0) {
        u_old.slope = old_locked.amount / iMAXTIME;
        u_old.bias =
          u_old.slope *
          int128(int256(old_locked.end - block.timestamp));
      }
      if (new_locked.end > block.timestamp && new_locked.amount > 0) {
        u_new.slope = new_locked.amount / iMAXTIME;
        u_new.bias =
          u_new.slope *
          int128(int256(new_locked.end - block.timestamp));
      }

      // Read values of scheduled changes in the slope
      // old_locked.end can be in the past and in the future
      // new_locked.end can ONLY by in the FUTURE unless everything expired: than zeros
      old_dslope = slope_changes[old_locked.end];
      if (new_locked.end != 0) {
        if (new_locked.end == old_locked.end) {
          new_dslope = old_dslope;
        } else {
          new_dslope = slope_changes[new_locked.end];
        }
      }
    }

    Point memory last_point = Point({
      bias: 0,
      slope: 0,
      ts: block.timestamp,
      blk: block.number
    });
    if (_epoch > 0) {
      last_point = point_history[_epoch];
    }
    uint256 last_checkpoint = last_point.ts;
    // initial_last_point is used for extrapolation to calculate block number
    // (approximately, for *At methods) and save them
    // as we cannot figure that out exactly from inside the contract

    uint256 initial_last_point_ts = last_point.ts;
    uint256 initial_last_point_blk = last_point.blk;

    uint256 block_slope = 0; // dblock/dt
    if (block.timestamp > last_point.ts) {
      block_slope =
        (MULTIPLIER * (block.number - last_point.blk)) /
        (block.timestamp - last_point.ts);
    }
    // If last point is already recorded in this block, slope=0
    // But that's ok b/c we know the block in such case

    // Go over weeks to fill history and calculate what the current point is
    uint256 t_i = (last_checkpoint / WEEK) * WEEK;
    for (uint256 i = 0; i < 255; ++i) {
      // Hopefully it won't happen that this won't get used in 5 years!
      // If it does, users will be able to withdraw but vote weight will be broken
      t_i += WEEK;
      int128 d_slope = 0;
      if (t_i > block.timestamp) {
        t_i = block.timestamp;
      } else {
        d_slope = slope_changes[t_i];
      }
      last_point.bias -=
        last_point.slope *
        int128(int256(t_i - last_checkpoint));
      last_point.slope += d_slope;
      if (last_point.bias < 0) {
        // This can happen
        last_point.bias = 0;
      }
      if (last_point.slope < 0) {
        // This cannot happen - just in case
        last_point.slope = 0;
      }
      last_checkpoint = t_i;
      last_point.ts = t_i;
      last_point.blk =
        initial_last_point_blk +
        (block_slope * (t_i - initial_last_point_ts)) /
        MULTIPLIER;

      _epoch += 1;
      if (t_i == block.timestamp) {
        last_point.blk = block.number;
        break;
      } else {
        point_history[_epoch] = last_point;
      }
    }

    epoch = _epoch;
    // Now point_history is filled until t=now

    if (_addr != address(0x0)) {
      // If last point was in this block, the slope change has been applied already
      // But in such case we have 0 slope(s)
      last_point.slope += (u_new.slope - u_old.slope);
      last_point.bias += (u_new.bias - u_old.bias);
      if (last_point.slope < 0) {
        last_point.slope = 0;
      }
      if (last_point.bias < 0) {
        last_point.bias = 0;
      }
    }

    // Record the changed point into history
    point_history[_epoch] = last_point;

    if (_addr != address(0x0)) {
      // Schedule the slope changes (slope is going down)
      // We subtract new_user_slope from [new_locked.end]
      // and add old_user_slope to [old_locked.end]
      if (old_locked.end > block.timestamp) {
        // old_dslope was <something> - u_old.slope, so we cancel that
        old_dslope += u_old.slope;
        if (new_locked.end == old_locked.end) {
          old_dslope -= u_new.slope; // It was a new deposit, not extension
        }
        slope_changes[old_locked.end] = old_dslope;
      }

      if (new_locked.end > block.timestamp) {
        if (new_locked.end > old_locked.end) {
          new_dslope -= u_new.slope; // old slope disappeared at this point
          slope_changes[new_locked.end] = new_dslope;
        }
        // else: we recorded it already in old_dslope
      }
      // Now handle user history
      address addr = _addr;
      uint256 user_epoch = user_point_epoch[addr] + 1;

      user_point_epoch[addr] = user_epoch;
      u_new.ts = block.timestamp;
      u_new.blk = block.number;
      user_point_history[addr][user_epoch] = u_new;
    }
  }

  /// @notice Deposit and lock tokens for a user
  /// @param _addr User's wallet address
  /// @param _value Amount to deposit
  /// @param unlock_time New time when to unlock the tokens, or 0 if unchanged
  /// @param locked_balance Previous locked amount / timestamp
  /// @param deposit_type The type of deposit
  function _deposit_for(
    address _addr,
    uint256 _value,
    uint256 unlock_time,
    LockedBalance memory locked_balance,
    DepositType deposit_type
  ) internal {
    LockedBalance memory _locked = locked_balance;
    uint256 supply_before = supply;

    supply = supply_before + _value;
    LockedBalance memory old_locked;
    (old_locked.amount, old_locked.end) = (_locked.amount, _locked.end);
    // Adding to existing lock, or if a lock is expired - creating a new one
    _locked.amount += int128(int256(_value));
    if (unlock_time != 0) {
      _locked.end = unlock_time;
    }
    locked[_addr] = _locked;

    // Possibilities:
    // Both old_locked.end could be current or expired (>/< block.timestamp)
    // value == 0 (extend lock) or value > 0 (add to lock or extend lock)
    // _locked.end > block.timestamp (always)
    _checkpoint(_addr, old_locked, _locked);

    if (_value != 0) {
      IERC20(token).safeTransferFrom(_addr, address(this), _value);
    }

    emit Deposit(_addr, _value, _locked.end, deposit_type, block.timestamp);
    emit Supply(supply_before, supply_before + _value);
  }

  /// @notice Record global data to checkpoint
  function checkpoint() external notUnlocked {
    _checkpoint(address(0x0), LockedBalance(0, 0), LockedBalance(0, 0));
  }

  /// @notice Deposit `_value` tokens for `_addr` and add to the lock
  /// @dev Anyone (even a smart contract) can deposit for someone else, but
  ///      cannot extend their locktime and deposit for a brand new user
  /// @param _addr User's wallet address
  /// @param _value Amount to add to user's lock
  function deposit_for(address _addr, uint256 _value)
    external
    nonReentrant
    notUnlocked
  {
    LockedBalance memory _locked = locked[_addr];

    require(_value > 0); // dev: need non-zero value
    require(_locked.amount > 0, "No existing lock found");
    require(
      _locked.end > block.timestamp,
      "Cannot add to expired lock. Withdraw"
    );
    _deposit_for(_addr, _value, 0, _locked, DepositType.DEPOSIT_FOR_TYPE);
  }

  /// @notice Deposit `_value` tokens for `msg.sender` and lock until `_unlock_time`
  /// @param _value Amount to deposit
  /// @param _unlock_time Epoch time when tokens unlock, rounded down to whole weeks
  function _create_lock(uint256 _value, uint256 _unlock_time) internal {
    require(_value > 0); // dev: need non-zero value

    LockedBalance memory _locked = locked[msg.sender];
    require(_locked.amount == 0, "Withdraw old tokens first");

    uint256 unlock_time = (_unlock_time / WEEK) * WEEK; // Locktime is rounded down to weeks
    require(
      unlock_time >= block.timestamp + MINTIME,
      "Voting lock must be at least MINTIME"
    );
    require(
      unlock_time <= block.timestamp + MAXTIME,
      "Voting lock can be 4 years max"
    );

    _deposit_for(
      msg.sender,
      _value,
      unlock_time,
      _locked,
      DepositType.CREATE_LOCK_TYPE
    );
  }

  /// @notice External function for _create_lock
  /// @param _value Amount to deposit
  /// @param _unlock_time Epoch time when tokens unlock, rounded down to whole weeks
  function create_lock(uint256 _value, uint256 _unlock_time)
    external
    nonReentrant
    onlyUserOrWhitelist
    notUnlocked
  {
    _create_lock(_value, _unlock_time);
  }

  /// @notice Deposit `_value` additional tokens for `msg.sender` without modifying the unlock time
  /// @param _value Amount of tokens to deposit and add to the lock
  function increase_amount(uint256 _value)
    external
    nonReentrant
    onlyUserOrWhitelist
    notUnlocked
  {
    _increase_amount(_value);
  }

  function _increase_amount(uint256 _value) internal {
    LockedBalance memory _locked = locked[msg.sender];

    require(_value > 0); // dev: need non-zero value
    require(_locked.amount > 0, "No existing lock found");
    require(
      _locked.end > block.timestamp,
      "Cannot add to expired lock. Withdraw"
    );

    _deposit_for(
      msg.sender,
      _value,
      0,
      _locked,
      DepositType.INCREASE_LOCK_AMOUNT
    );
  }

  /// @notice Extend the unlock time for `msg.sender` to `_unlock_time`
  /// @param _unlock_time New epoch time for unlocking
  function increase_unlock_time(uint256 _unlock_time)
    external
    nonReentrant
    onlyUserOrWhitelist
    notUnlocked
  {
    _increase_unlock_time(_unlock_time);
  }

  function _increase_unlock_time(uint256 _unlock_time) internal {
    LockedBalance memory _locked = locked[msg.sender];
    uint256 unlock_time = (_unlock_time / WEEK) * WEEK; // Locktime is rounded down to weeks

    require(_locked.end > block.timestamp, "Lock expired");
    require(_locked.amount > 0, "Nothing is locked");
    require(unlock_time > _locked.end, "Can only increase lock duration");
    require(
      unlock_time <= block.timestamp + MAXTIME,
      "Voting lock can be 4 years max"
    );

    _deposit_for(
      msg.sender,
      0,
      unlock_time,
      _locked,
      DepositType.INCREASE_UNLOCK_TIME
    );
  }

  /// @notice Extend the unlock time and/or for `msg.sender` to `_unlock_time`
  /// @param _unlock_time New epoch time for unlocking
  function increase_amount_and_time(uint256 _value, uint256 _unlock_time)
    external
    nonReentrant
    onlyUserOrWhitelist
    notUnlocked
  {
    require(
      _value > 0 || _unlock_time > 0,
      "Value and Unlock cannot both be 0"
    );
    if (_value > 0 && _unlock_time > 0) {
      _increase_amount(_value);
      _increase_unlock_time(_unlock_time);
    } else if (_value > 0 && _unlock_time == 0) {
      _increase_amount(_value);
    } else {
      _increase_unlock_time(_unlock_time);
    }
  }

  /// @notice Withdraw all tokens for `msg.sender`
  /// @dev Only possible if the lock has expired
  function _withdraw() internal {
    LockedBalance memory _locked = locked[msg.sender];
    uint256 value = uint256(int256(_locked.amount));

    if (!unlocked) {
      require(block.timestamp >= _locked.end, "The lock didn't expire");
    }

    locked[msg.sender] = LockedBalance(0, 0);
    uint256 supply_before = supply;
    supply = supply_before - value;

    // old_locked can have either expired <= timestamp or zero end
    // _locked has only 0 end
    // Both can have >= 0 amount
    _checkpoint(msg.sender, _locked, LockedBalance(0, 0));

    IERC20(token).safeTransfer(msg.sender, value);

    emit Withdraw(msg.sender, value, block.timestamp);
    emit Supply(supply_before, supply_before - value);
  }

  function withdraw() external nonReentrant {
    _withdraw();
  }

  /// @notice Deposit `_value` tokens for `msg.sender` and lock until `_unlock_time`
  /// @param _value Amount to deposit
  /// @param _unlock_time Epoch time when tokens unlock, rounded down to whole weeks
  function withdraw_and_create_lock(uint256 _value, uint256 _unlock_time)
    external
    nonReentrant
    onlyUserOrWhitelist
    notUnlocked
  {
    _withdraw();
    _create_lock(_value, _unlock_time);
  }

  // The following ERC20/minime-compatible methods are not real balanceOf and supply!
  // They measure the weights for the purpose of voting, so they don't represent
  // real coins.

  /// @notice Binary search to estimate timestamp for block number
  /// @param _block Block to find
  /// @param max_epoch Don't go beyond this epoch
  /// @return Approximate timestamp for block
  function _find_block_epoch(uint256 _block, uint256 max_epoch)
    internal
    view
    returns (uint256)
  {
    // Binary search
    uint256 _min = 0;
    uint256 _max = max_epoch;
    for (uint256 i = 0; i < 128; ++i) {
      // Will be always enough for 128-bit numbers
      if (_min >= _max) {
        break;
      }
      uint256 _mid = (_min + _max + 1) / 2;
      if (point_history[_mid].blk <= _block) {
        _min = _mid;
      } else {
        _max = _mid - 1;
      }
    }
    return _min;
  }

  /// @notice Get the current voting power for `msg.sender`
  /// @dev Adheres to the ERC20 `balanceOf` interface
  /// @param addr User wallet address
  /// @param _t Epoch time to return voting power at
  /// @return User voting power
  function _balanceOf(address addr, uint256 _t)
    internal
    view
    returns (uint256)
  {
    uint256 _epoch = user_point_epoch[addr];
    if (_epoch == 0) {
      return 0;
    } else {
      Point memory last_point = user_point_history[addr][_epoch];
      last_point.bias -=
        last_point.slope *
        int128(int256(_t) - int256(last_point.ts));
      if (last_point.bias < 0) {
        last_point.bias = 0;
      }
      return uint256(int256(last_point.bias));
    }
  }

  function balanceOfAtT(address addr, uint256 _t)
    external
    view
    returns (uint256)
  {
    return _balanceOf(addr, _t);
  }

  function balanceOf(address addr) external view returns (uint256) {
    return _balanceOf(addr, block.timestamp);
  }

  /// @notice Measure voting power of `addr` at block height `_block`
  /// @dev Adheres to MiniMe `balanceOfAt` interface: https://github.com/Giveth/minime
  /// @param addr User's wallet address
  /// @param _block Block to calculate the voting power at
  /// @return Voting power
  function balanceOfAt(address addr, uint256 _block)
    external
    view
    returns (uint256)
  {
    // Copying and pasting totalSupply code because Vyper cannot pass by
    // reference yet
    require(_block <= block.number);

    // Binary search
    uint256 _min = 0;
    uint256 _max = user_point_epoch[addr];
    for (uint256 i = 0; i < 128; ++i) {
      // Will be always enough for 128-bit numbers
      if (_min >= _max) {
        break;
      }
      uint256 _mid = (_min + _max + 1) / 2;
      if (user_point_history[addr][_mid].blk <= _block) {
        _min = _mid;
      } else {
        _max = _mid - 1;
      }
    }

    Point memory upoint = user_point_history[addr][_min];

    uint256 max_epoch = epoch;
    uint256 _epoch = _find_block_epoch(_block, max_epoch);
    Point memory point_0 = point_history[_epoch];
    uint256 d_block = 0;
    uint256 d_t = 0;
    if (_epoch < max_epoch) {
      Point memory point_1 = point_history[_epoch + 1];
      d_block = point_1.blk - point_0.blk;
      d_t = point_1.ts - point_0.ts;
    } else {
      d_block = block.number - point_0.blk;
      d_t = block.timestamp - point_0.ts;
    }
    uint256 block_time = point_0.ts;
    if (d_block != 0) {
      block_time += (d_t * (_block - point_0.blk)) / d_block;
    }

    upoint.bias -= upoint.slope * int128(int256(block_time - upoint.ts));
    if (upoint.bias >= 0) {
      return uint256(uint128(upoint.bias));
    } else {
      return 0;
    }
  }

  /// @notice Calculate total voting power at some point in the past
  /// @param point The point (bias/slope) to start search from
  /// @param t Time to calculate the total voting power at
  /// @return Total voting power at that time
  function _supply_at(Point memory point, uint256 t)
    internal
    view
    returns (uint256)
  {
    Point memory last_point = point;
    uint256 t_i = (last_point.ts / WEEK) * WEEK;
    for (uint256 i = 0; i < 255; ++i) {
      t_i += WEEK;
      int128 d_slope = 0;
      if (t_i > t) {
        t_i = t;
      } else {
        d_slope = slope_changes[t_i];
      }
      last_point.bias -= last_point.slope * int128(int256(t_i - last_point.ts));
      if (t_i == t) {
        break;
      }
      last_point.slope += d_slope;
      last_point.ts = t_i;
    }

    if (last_point.bias < 0) {
      last_point.bias = 0;
    }
    return uint256(uint128(last_point.bias));
  }

  /// @notice Calculate total voting power
  /// @dev Adheres to the ERC20 `totalSupply` interface
  /// @return Total voting power
  function _totalSupply(uint256 t) internal view returns (uint256) {
    uint256 _epoch = epoch;
    Point memory last_point = point_history[_epoch];
    return _supply_at(last_point, t);
  }

  function totalSupplyAtT(uint256 t) external view returns (uint256) {
    return _totalSupply(t);
  }

  function totalSupply() external view returns (uint256) {
    return _totalSupply(block.timestamp);
  }

  /// @notice Calculate total voting power at some point in the past
  /// @param _block Block to calculate the total voting power at
  /// @return Total voting power at `_block`
  function totalSupplyAt(uint256 _block) external view returns (uint256) {
    require(_block <= block.number);
    uint256 _epoch = epoch;
    uint256 target_epoch = _find_block_epoch(_block, _epoch);

    Point memory point = point_history[target_epoch];
    uint256 dt = 0;
    if (target_epoch < _epoch) {
      Point memory point_next = point_history[target_epoch + 1];
      if (point.blk != point_next.blk) {
        dt =
          ((_block - point.blk) * (point_next.ts - point.ts)) /
          (point_next.blk - point.blk);
      }
    } else {
      if (point.blk != block.number) {
        dt =
          ((_block - point.blk) * (block.timestamp - point.ts)) /
          (block.number - point.blk);
      }
    }
    // Now dt contains info on how far are we beyond point
    return _supply_at(point, point.ts + dt);
  }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"token_addr","type":"address"},{"internalType":"uint256","name":"min_time","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"locktime","type":"uint256"},{"indexed":false,"internalType":"enum DPXVotingEscrow.DepositType","name":"deposit_type","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"}],"name":"Deposit","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":"uint256","name":"prevSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"}],"name":"Supply","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"MAXTIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"add_to_whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"balanceOfAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint256","name":"_t","type":"uint256"}],"name":"balanceOfAtT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"contracts_whitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_unlock_time","type":"uint256"}],"name":"create_lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"deposit_for","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"get_last_user_slope","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"increase_amount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_unlock_time","type":"uint256"}],"name":"increase_amount_and_time","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_unlock_time","type":"uint256"}],"name":"increase_unlock_time","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"locked","outputs":[{"internalType":"int128","name":"amount","type":"int128"},{"internalType":"uint256","name":"end","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"}],"name":"locked__end","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"point_history","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"},{"internalType":"uint256","name":"blk","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"remove_from_whitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"slope_changes","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_block","type":"uint256"}],"name":"totalSupplyAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"t","type":"uint256"}],"name":"totalSupplyAtT","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":"unlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"user_point_epoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"user_point_history","outputs":[{"internalType":"int128","name":"bias","type":"int128"},{"internalType":"int128","name":"slope","type":"int128"},{"internalType":"uint256","name":"ts","type":"uint256"},{"internalType":"uint256","name":"blk","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_addr","type":"address"},{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"user_point_history__ts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_unlock_time","type":"uint256"}],"name":"withdraw_and_create_lock","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040523480156200001157600080fd5b5060405162002c5838038062002c588339810160408190526200003491620000f9565b6200003f33620000a9565b600180556001600160a01b0390911660a052600080526006602052437f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4fa55427f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f95560805262000135565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080604083850312156200010d57600080fd5b82516001600160a01b03811681146200012557600080fd5b6020939093015192949293505050565b60805160a051612ae8620001706000396000818161060f0152818161140201526117030152600081816103be01526115570152612ae86000f3fe608060405234801561001057600080fd5b506004361061023d5760003560e01c80637142a6a61161013b578063adc63589116100b8578063da020a181161007c578063da020a18146105c6578063ee00ef3a146105d9578063eff7a612146105e4578063f2fde38b146105f7578063fc0c546a1461060a57600080fd5b8063adc63589146104f9578063c2c4c5c114610525578063cbf9fe5f1461052d578063d07b705f14610575578063d1febfb91461058857600080fd5b806390fad1e6116100ff57806390fad1e6146104b857806395d89b411461027e578063981b24d0146104cb578063a69df4b5146104de578063ac25f266146104e657600080fd5b80637142a6a61461045c578063715018a61461046f5780637c74a174146104775780638da5cb5b1461048a578063900cf0cf146104af57600080fd5b80633ccfd60b116101c957806365fc38731161018d57806365fc3873146103e05780636a5e2650146103f357806370a08231146104005780637116c60c14610413578063711974841461042657600080fd5b80633ccfd60b146103675780634957677c1461036f5780634ee2cd7e1461038257806354fd4d50146103955780635b51c308146103b957600080fd5b80632371eb23116102105780632371eb23146102b757806328d09d47146102cc578063313ce567146103075780633617a204146103215780633a46273e1461035457600080fd5b8063010ae75714610242578063047fc9aa1461027557806306fdde031461027e57806318160ddd146102af575b600080fd5b6102626102503660046125dd565b60086020526000908152604090205481565b6040519081526020015b60405180910390f35b61026260025481565b6102a2604051806040016040528060058152602001640ecca88a0b60db1b81525081565b60405161026c9190612624565b610262610631565b6102ca6102c5366004612657565b610641565b005b6102df6102da366004612679565b6106e5565b60408051600f95860b81529390940b602084015292820152606081019190915260800161026c565b61030f601281565b60405160ff909116815260200161026c565b61034461032f3660046125dd565b600a6020526000908152604090205460ff1681565b604051901515815260200161026c565b6102ca610362366004612679565b61072c565b6102ca61083f565b6102ca61037d3660046126a3565b610875565b610262610390366004612679565b610906565b6102a2604051806040016040528060058152602001640312e302e360dc1b81525081565b6102627f000000000000000000000000000000000000000000000000000000000000000081565b6102ca6103ee366004612657565b610c00565b6003546103449060ff1681565b61026261040e3660046125dd565b610c81565b6102626104213660046126a3565b610c8d565b6104496104343660046126a3565b600960205260009081526040902054600f0b81565b604051600f9190910b815260200161026c565b6102ca61046a366004612657565b610c98565b6102ca610dcf565b6104496104853660046125dd565b610e05565b6000546001600160a01b03165b6040516001600160a01b03909116815260200161026c565b61026260055481565b6102ca6104c63660046125dd565b610e52565b6102626104d93660046126a3565b610e9d565b6102ca61103c565b6102ca6104f43660046125dd565b611075565b6102626105073660046125dd565b6001600160a01b031660009081526004602052604090206001015490565b6102ca6110c3565b61055b61053b3660046125dd565b60046020526000908152604090208054600190910154600f9190910b9082565b60408051600f9390930b835260208301919091520161026c565b610262610583366004612679565b611124565b6102df6105963660046126a3565b600660205260009081526040902080546001820154600290920154600f82810b93600160801b909304900b919084565b6102626105d4366004612679565b611137565b610262630784ce0081565b6102ca6105f23660046126a3565b611173565b6102ca6106053660046125dd565b6111fd565b6104977f000000000000000000000000000000000000000000000000000000000000000081565b600061063c42611298565b905090565b6002600154141561066d5760405162461bcd60e51b8152600401610664906126bc565b60405180910390fd5b60026001553332146106a857336000908152600a602052604090205460ff166106a85760405162461bcd60e51b8152600401610664906126f3565b60035460ff16156106cb5760405162461bcd60e51b81526004016106649061272a565b6106d36112f8565b6106dd82826114ac565b505060018055565b600760205281600052604060002081633b9aca00811061070457600080fd5b6003020180546001820154600290920154600f82810b9550600160801b90920490910b925084565b6002600154141561074f5760405162461bcd60e51b8152600401610664906126bc565b600260015560035460ff16156107775760405162461bcd60e51b81526004016106649061272a565b6001600160a01b03821660009081526004602090815260409182902082518084019093528054600f0b83526001015490820152816107b457600080fd5b60008160000151600f0b136108045760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b6044820152606401610664565b428160200151116108275760405162461bcd60e51b815260040161066490612755565b61083683836000846000611648565b50506001805550565b600260015414156108625760405162461bcd60e51b8152600401610664906126bc565b600260015561086f6112f8565b60018055565b600260015414156108985760405162461bcd60e51b8152600401610664906126bc565b60026001553332146108d357336000908152600a602052604090205460ff166108d35760405162461bcd60e51b8152600401610664906126f3565b60035460ff16156108f65760405162461bcd60e51b81526004016106649061272a565b6108ff816117c3565b5060018055565b60004382111561091557600080fd5b6001600160a01b038316600090815260086020526040812054815b60808110156109cd57818310610945576109cd565b6000600261095384866127af565b61095e9060016127af565b61096891906127dd565b6001600160a01b0388166000908152600760205260409020909150869082633b9aca008110610999576109996127f1565b6003020160020154116109ae578093506109bc565b6109b9600182612807565b92505b506109c68161281e565b9050610930565b506001600160a01b038516600090815260076020526040812083633b9aca0081106109fa576109fa6127f1565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b602083015260018101549282019290925260029091015460608201526005549091506000610a4f878361187d565b600081815260066020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529192508084841015610b2e576000600681610ab38760016127af565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b93810193909352600181015491830191909152600201546060808301829052860151919250610b109190612807565b925083604001518160400151610b269190612807565b915050610b52565b6060830151610b3d9043612807565b9150826040015142610b4f9190612807565b90505b60408301518215610b8f578284606001518c610b6e9190612807565b610b789084612839565b610b8291906127dd565b610b8c90826127af565b90505b6040870151610b9e9082612807565b8760200151610bad9190612858565b87518890610bbc9083906128ed565b600f90810b90915288516000910b129050610bec57505093516001600160801b03169650610bfa95505050505050565b600099505050505050505050505b92915050565b60026001541415610c235760405162461bcd60e51b8152600401610664906126bc565b6002600155333214610c5e57336000908152600a602052604090205460ff16610c5e5760405162461bcd60e51b8152600401610664906126f3565b60035460ff16156106d35760405162461bcd60e51b81526004016106649061272a565b6000610bfa8242611907565b6000610bfa82611298565b60026001541415610cbb5760405162461bcd60e51b8152600401610664906126bc565b6002600155333214610cf657336000908152600a602052604090205460ff16610cf65760405162461bcd60e51b8152600401610664906126f3565b60035460ff1615610d195760405162461bcd60e51b81526004016106649061272a565b6000821180610d285750600081115b610d7e5760405162461bcd60e51b815260206004820152602160248201527f56616c756520616e6420556e6c6f636b2063616e6e6f7420626f7468206265206044820152600360fc1b6064820152608401610664565b600082118015610d8e5750600081115b15610daa57610d9c826117c3565b610da5816119ed565b6106dd565b600082118015610db8575080155b15610dc657610da5826117c3565b6106dd816119ed565b6000546001600160a01b03163314610df95760405162461bcd60e51b81526004016106649061293d565b610e036000611b85565b565b6001600160a01b0381166000908152600860209081526040808320546007909252822081633b9aca008110610e3c57610e3c6127f1565b6003020154600160801b9004600f0b9392505050565b6000546001600160a01b03163314610e7c5760405162461bcd60e51b81526004016106649061293d565b6001600160a01b03166000908152600a60205260409020805460ff19169055565b600043821115610eac57600080fd5b6005546000610ebb848361187d565b600081815260066020908152604080832081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606082015291925083831015610fca576000600681610f1e8660016127af565b8152602080820192909252604090810160002081516080810183528154600f81810b8352600160801b909104900b9381019390935260018101549183019190915260020154606080830182905285015191925014610fc45782606001518160600151610f8a9190612807565b83604001518260400151610f9e9190612807565b6060850151610fad908a612807565b610fb79190612839565b610fc191906127dd565b91505b50611019565b43826060015114611019576060820151610fe49043612807565b6040830151610ff39042612807565b60608401516110029089612807565b61100c9190612839565b61101691906127dd565b90505b6110328282846040015161102d91906127af565b611bd5565b9695505050505050565b6000546001600160a01b031633146110665760405162461bcd60e51b81526004016106649061293d565b6003805460ff19166001179055565b6000546001600160a01b0316331461109f5760405162461bcd60e51b81526004016106649061293d565b6001600160a01b03166000908152600a60205260409020805460ff19166001179055565b60035460ff16156110e65760405162461bcd60e51b81526004016106649061272a565b610e03600060405180604001604052806000600f0b8152602001600081525060405180604001604052806000600f0b81526020016000815250611cd7565b60006111308383611907565b9392505050565b6001600160a01b038216600090815260076020526040812082633b9aca008110611163576111636127f1565b6003020160010154905092915050565b600260015414156111965760405162461bcd60e51b8152600401610664906126bc565b60026001553332146111d157336000908152600a602052604090205460ff166111d15760405162461bcd60e51b8152600401610664906126f3565b60035460ff16156111f45760405162461bcd60e51b81526004016106649061272a565b6108ff816119ed565b6000546001600160a01b031633146112275760405162461bcd60e51b81526004016106649061293d565b6001600160a01b03811661128c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610664565b61129581611b85565b50565b600554600081815260066020908152604080832081516080810183528154600f81810b8352600160801b909104900b938101939093526001810154918301919091526002015460608201529091906112f08185611bd5565b949350505050565b3360009081526004602090815260409182902082518084019093528054600f0b8084526001909101549183019190915260035460ff1661137f57816020015142101561137f5760405162461bcd60e51b8152602060048201526016602482015275546865206c6f636b206469646e27742065787069726560501b6044820152606401610664565b604080518082018252600080825260208083018281523383526004909152929020905181546001600160801b0319166001600160801b0390911617815590516001909101556002546113d18282612807565b60025560408051808201909152600080825260208201526113f59033908590611cd7565b6114296001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163384612340565b6040805183815242602082015233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568910160405180910390a27f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c8161148f8482612807565b6040805192835260208301919091520160405180910390a1505050565b600082116114b957600080fd5b3360009081526004602090815260409182902082518084019093528054600f0b80845260019091015491830191909152156115365760405162461bcd60e51b815260206004820152601960248201527f5769746864726177206f6c6420746f6b656e73206669727374000000000000006044820152606401610664565b600062093a8061154681856127dd565b6115509190612839565b905061157c7f0000000000000000000000000000000000000000000000000000000000000000426127af565b8110156115d75760405162461bcd60e51b8152602060048201526024808201527f566f74696e67206c6f636b206d757374206265206174206c65617374204d494e60448201526354494d4560e01b6064820152608401610664565b6115e5630784ce00426127af565b8111156116345760405162461bcd60e51b815260206004820152601e60248201527f566f74696e67206c6f636b2063616e2062652034207965617273206d617800006044820152606401610664565b611642338583856001611648565b50505050565b600254829061165786826127af565b6002556040805180820190915260008082526020820152825160208085015190830152600f0b8152825187908490611690908390612972565b600f0b90525085156116a457602083018690525b6001600160a01b0388166000908152600460209081526040909120845181546001600160801b0319166001600160801b03909116178155908401516001909101556116f0888285611cd7565b861561172b5761172b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001689308a6123a3565b8260200151886001600160a01b03167fbe9cf0e939c614fad640a623a53ba0a807c8cb503c4c4c8dacabe27b86ff2dd589874260405161176d939291906129c1565b60405180910390a37f5e2aa66efd74cce82b21852e317e5490d9ecc9e6bb953ae24d90851258cc2f5c826117a189826127af565b6040805192835260208301919091520160405180910390a15050505050505050565b3360009081526004602090815260409182902082518084019093528054600f0b83526001015490820152816117f757600080fd5b60008160000151600f0b136118475760405162461bcd60e51b8152602060048201526016602482015275139bc8195e1a5cdd1a5b99c81b1bd8dac8199bdd5b9960521b6044820152606401610664565b4281602001511161186a5760405162461bcd60e51b815260040161066490612755565b61187933836000846002611648565b5050565b60008082815b60808110156118fd57818310611898576118fd565b600060026118a684866127af565b6118b19060016127af565b6118bb91906127dd565b60008181526006602052604090206002015490915087106118de578093506118ec565b6118e9600182612807565b92505b506118f68161281e565b9050611883565b5090949350505050565b6001600160a01b0382166000908152600860205260408120548061192f576000915050610bfa565b6001600160a01b038416600090815260076020526040812082633b9aca00811061195b5761195b6127f1565b60408051608081018252600392909202929092018054600f81810b8452600160801b909104900b6020830152600181015492820183905260020154606082015291506119a790856129f7565b81602001516119b69190612858565b815182906119c59083906128ed565b600f90810b90915282516000910b121590506119e057600081525b51600f0b9150610bfa9050565b33600090815260046020908152604080832081518083019092528054600f0b825260010154918101919091529062093a80611a2881856127dd565b611a329190612839565b905042826020015111611a765760405162461bcd60e51b815260206004820152600c60248201526b131bd8dac8195e1c1a5c995960a21b6044820152606401610664565b60008260000151600f0b13611ac15760405162461bcd60e51b8152602060048201526011602482015270139bdd1a1a5b99c81a5cc81b1bd8dad959607a1b6044820152606401610664565b81602001518111611b145760405162461bcd60e51b815260206004820152601f60248201527f43616e206f6e6c7920696e637265617365206c6f636b206475726174696f6e006044820152606401610664565b611b22630784ce00426127af565b811115611b715760405162461bcd60e51b815260206004820152601e60248201527f566f74696e67206c6f636b2063616e2062652034207965617273206d617800006044820152606401610664565b611b8033600083856003611648565b505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080839050600062093a80808360400151611bf191906127dd565b611bfb9190612839565b905060005b60ff811015611caf57611c1662093a80836127af565b9150600085831115611c2a57859250611c3e565b50600082815260096020526040902054600f0b5b6040840151611c4d9084612807565b8460200151611c5c9190612858565b84518590611c6b9083906128ed565b600f0b90525082861415611c7f5750611caf565b8084602001818151611c919190612972565b600f0b9052505060408301829052611ca88161281e565b9050611c00565b5060008260000151600f0b1215611cc557600082525b50516001600160801b03169392505050565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260055460009081906001600160a01b03881615611e4c57428760200151118015611d50575060008760000151600f0b135b15611d95578651611d6690630784ce0090612a36565b600f0b602080870191909152870151611d80904290612807565b8560200151611d8f9190612858565b600f0b85525b428660200151118015611daf575060008660000151600f0b135b15611df4578551611dc590630784ce0090612a36565b600f0b602080860191909152860151611ddf904290612807565b8460200151611dee9190612858565b600f0b84525b602080880151600090815260098252604090205490870151600f9190910b935015611e4c57866020015186602001511415611e3157829150611e4c565b602080870151600090815260099091526040902054600f0b91505b604080516080810182526000808252602082015242918101919091524360608201528115611ec1575060008181526006602090815260409182902082516080810184528154600f81810b8352600160801b909104900b9281019290925260018101549282019290925260029091015460608201525b604081015160608201518190600042831015611f14576040850151611ee69042612807565b6060860151611ef59043612807565b611f0790670de0b6b3a7640000612839565b611f1191906127dd565b90505b600062093a80611f2481876127dd565b611f2e9190612839565b905060005b60ff81101561209f57611f4962093a80836127af565b9150600042831115611f5d57429250611f71565b50600082815260096020526040902054600f0b5b611f7b8784612807565b8860200151611f8a9190612858565b88518990611f999083906128ed565b600f0b905250602088018051829190611fb3908390612972565b600f90810b90915289516000910b12159050611fce57600088525b60008860200151600f0b1215611fe657600060208901525b604088018390529195508591670de0b6b3a76400006120058785612807565b61200f9086612839565b61201991906127dd565b61202390866127af565b606089015261203360018a6127af565b985042831415612049575043606088015261209f565b6000898152600660209081526040918290208a51918b01516001600160801b03908116600160801b0292169190911781559089015160018201556060890151600290910155506120988161281e565b9050611f33565b5060058790556001600160a01b038e1615612132578a602001518a602001516120c891906128ed565b866020018181516120d99190612972565b600f0b9052508a518a516120ed91906128ed565b865187906120fc908390612972565b600f90810b90915260208801516000910b1215905061211d57600060208701525b60008660000151600f0b121561213257600086525b6000878152600660209081526040918290208851918901516001600160801b03908116600160801b02921691909117815590870151600182015560608701516002909101556001600160a01b038e161561233057428d6020015111156121f35760208b01516121a1908a612972565b98508c602001518c6020015114156121c55760208a01516121c2908a6128ed565b98505b60208d810151600090815260099091526040902080546001600160801b0319166001600160801b038b161790555b428c60200151111561224e578c602001518c60200151111561224e5760208a015161221e90896128ed565b60208d810151600090815260099091526040902080546001600160801b0319166001600160801b03831617905597505b6001600160a01b038e166000908152600860205260408120548f91906122759060016127af565b90508060086000846001600160a01b03166001600160a01b0316815260200190815260200160002081905550428c6040018181525050438c60600181815250508b60076000846001600160a01b03166001600160a01b0316815260200190815260200160002082633b9aca0081106122ef576122ef6127f1565b825160208401516001600160801b03908116600160801b02911617600391909102919091019081556040820151600182015560609091015160029091015550505b5050505050505050505050505050565b6040516001600160a01b038316602482015260448101829052611b8090849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526123db565b6040516001600160a01b03808516602483015283166044820152606481018290526116429085906323b872dd60e01b9060840161236c565b6000612430826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124ad9092919063ffffffff16565b805190915015611b80578080602001905181019061244e9190612a74565b611b805760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610664565b60606112f08484600085856001600160a01b0385163b61250f5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610664565b600080866001600160a01b0316858760405161252b9190612a96565b60006040518083038185875af1925050503d8060008114612568576040519150601f19603f3d011682016040523d82523d6000602084013e61256d565b606091505b509150915061257d828286612588565b979650505050505050565b60608315612597575081611130565b8251156125a75782518084602001fd5b8160405162461bcd60e51b81526004016106649190612624565b80356001600160a01b03811681146125d857600080fd5b919050565b6000602082840312156125ef57600080fd5b611130826125c1565b60005b838110156126135781810151838201526020016125fb565b838111156116425750506000910152565b60208152600082518060208401526126438160408501602087016125f8565b601f01601f19169190910160400192915050565b6000806040838503121561266a57600080fd5b50508035926020909101359150565b6000806040838503121561268c57600080fd5b612695836125c1565b946020939093013593505050565b6000602082840312156126b557600080fd5b5035919050565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252601a908201527f536d61727420636f6e7472616374206e6f7420616c6c6f776564000000000000604082015260600190565b602080825260119082015270756e6c6f636b656420676c6f62616c6c7960781b604082015260600190565b60208082526024908201527f43616e6e6f742061646420746f2065787069726564206c6f636b2e20576974686040820152636472617760e01b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b600082198211156127c2576127c2612799565b500190565b634e487b7160e01b600052601260045260246000fd5b6000826127ec576127ec6127c7565b500490565b634e487b7160e01b600052603260045260246000fd5b60008282101561281957612819612799565b500390565b600060001982141561283257612832612799565b5060010190565b600081600019048311821515161561285357612853612799565b500290565b600081600f0b83600f0b60016001607f1b0360008213600084138383048511828216161561288857612888612799565b60016001607f1b031960008512828116878305871216156128ab576128ab612799565b600087129250858205871284841616156128c7576128c7612799565b858505871281841616156128dd576128dd612799565b5050509290910295945050505050565b600081600f0b83600f0b600081128160016001607f1b03190183128115161561291857612918612799565b8160016001607f1b0301831381161561293357612933612799565b5090039392505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600081600f0b83600f0b600082128260016001607f1b030382138115161561299c5761299c612799565b8260016001607f1b03190382128116156129b8576129b8612799565b50019392505050565b83815260608101600484106129e657634e487b7160e01b600052602160045260246000fd5b602082019390935260400152919050565b60008083128015600160ff1b850184121615612a1557612a15612799565b6001600160ff1b0384018313811615612a3057612a30612799565b50500390565b600081600f0b83600f0b80612a4d57612a4d6127c7565b60016001607f1b0319821460001982141615612a6b57612a6b612799565b90059392505050565b600060208284031215612a8657600080fd5b8151801515811461113057600080fd5b60008251612aa88184602087016125f8565b919091019291505056fea26469706673582212208a12bc1ac85148331c4c4ead2f093bcf8e1a915fefb95bb320c3861a752236d164736f6c634300080900330000000000000000000000006c2c06790b3e3e3c38e12ee22f8183b37a13ee550000000000000000000000000000000000000000000000000000000000093a80

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

0000000000000000000000006c2c06790b3e3e3c38e12ee22f8183b37a13ee550000000000000000000000000000000000000000000000000000000000093a80

-----Decoded View---------------
Arg [0] : token_addr (address): 0x6c2c06790b3e3e3c38e12ee22f8183b37a13ee55
Arg [1] : min_time (uint256): 604800

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000006c2c06790b3e3e3c38e12ee22f8183b37a13ee55
Arg [1] : 0000000000000000000000000000000000000000000000000000000000093a80


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.