ETH Price: $2,483.89 (+2.75%)

Contract

0x5cd63BED68c69e719917b95F5d7b999b3f29ed16
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer Unused ...143516502022-03-09 8:57:45942 days ago1646816265IN
0x5cd63BED...b3f29ed16
0 ETH0.0015083534.80612951
Revoke Vesting G...143515712022-03-09 8:38:01942 days ago1646815081IN
0x5cd63BED...b3f29ed16
0 ETH0.001699441.1408245
Revoke Vesting G...143515702022-03-09 8:37:29942 days ago1646815049IN
0x5cd63BED...b3f29ed16
0 ETH0.001585738.38835407
Revoke Vesting G...143515692022-03-09 8:37:19942 days ago1646815039IN
0x5cd63BED...b3f29ed16
0 ETH0.001610838.99600279
Revoke Vesting G...143515682022-03-09 8:37:07942 days ago1646815027IN
0x5cd63BED...b3f29ed16
0 ETH0.0017288641.85410771
Revoke Vesting G...143515672022-03-09 8:37:00942 days ago1646815020IN
0x5cd63BED...b3f29ed16
0 ETH0.0018126343.8948099
Revoke Vesting G...143515652022-03-09 8:36:31942 days ago1646814991IN
0x5cd63BED...b3f29ed16
0 ETH0.0019734147.77437978
Revoke Vesting G...143515642022-03-09 8:36:08942 days ago1646814968IN
0x5cd63BED...b3f29ed16
0 ETH0.0018104143.82838546
Revoke Vesting G...143515632022-03-09 8:35:49942 days ago1646814949IN
0x5cd63BED...b3f29ed16
0 ETH0.0016207439.23654935
Revoke Vesting G...143515612022-03-09 8:35:30942 days ago1646814930IN
0x5cd63BED...b3f29ed16
0 ETH0.0018757845.41091749
Revoke Vesting G...143515602022-03-09 8:35:04942 days ago1646814904IN
0x5cd63BED...b3f29ed16
0 ETH0.0017857643.23151602
Revoke Vesting G...143515592022-03-09 8:34:50942 days ago1646814890IN
0x5cd63BED...b3f29ed16
0 ETH0.0018145543.928506
Revoke Vesting G...143515582022-03-09 8:34:33942 days ago1646814873IN
0x5cd63BED...b3f29ed16
0 ETH0.0018439644.64039115
Revoke Vesting G...143515572022-03-09 8:34:21942 days ago1646814861IN
0x5cd63BED...b3f29ed16
0 ETH0.0016784840.63448437
Revoke Vesting G...143515562022-03-09 8:33:48942 days ago1646814828IN
0x5cd63BED...b3f29ed16
0 ETH0.0015034736.39746345
Revoke Vesting G...143515552022-03-09 8:33:32942 days ago1646814812IN
0x5cd63BED...b3f29ed16
0 ETH0.0013479832.63331307
Revoke Vesting G...143515452022-03-09 8:32:05942 days ago1646814725IN
0x5cd63BED...b3f29ed16
0 ETH0.0020808650.3755861
Revoke Vesting G...143515442022-03-09 8:31:53942 days ago1646814713IN
0x5cd63BED...b3f29ed16
0 ETH0.0021615552.32896654
Revoke Vesting G...143515412022-03-09 8:30:55942 days ago1646814655IN
0x5cd63BED...b3f29ed16
0 ETH0.0020481949.58461866
Revoke Vesting G...143515342022-03-09 8:28:12942 days ago1646814492IN
0x5cd63BED...b3f29ed16
0 ETH0.0022033453.34074932
Revoke Vesting G...143515332022-03-09 8:27:58942 days ago1646814478IN
0x5cd63BED...b3f29ed16
0 ETH0.0020766350.27319743
Revoke Vesting G...143515312022-03-09 8:27:49942 days ago1646814469IN
0x5cd63BED...b3f29ed16
0 ETH0.0023612257.16277708
Revoke Vesting G...143515282022-03-09 8:27:27942 days ago1646814447IN
0x5cd63BED...b3f29ed16
0 ETH0.0025253961.1372116
Revoke Vesting G...143515262022-03-09 8:26:32942 days ago1646814392IN
0x5cd63BED...b3f29ed16
0 ETH0.0020407749.40496719
Revoke Vesting G...143515232022-03-09 8:26:03942 days ago1646814363IN
0x5cd63BED...b3f29ed16
0 ETH0.0021755452.66778615
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Vesting

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 6 : Vesting.sol
// SPDX-License-Identifier: Apache-2.0
// Copyright 2021 Enjinstarter
pragma solidity ^0.7.6;

import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "./interfaces/IVesting.sol";

/**
 * @title Vesting
 * @author Enjinstarter
 */
contract Vesting is IVesting {
    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    struct VestingSchedule {
        uint256 cliffDurationDays; // Cliff duration in days with respect to the start of vesting schedule
        uint256 percentReleaseAtScheduleStart; // Percentage of grant amount to be released in wei at start of vesting schedule
        uint256 percentReleaseForEachInterval; // Percentage of grant amount to be released in wei for each interval after cliff duration
        uint256 intervalDays; // Vesting interval in days
        uint256 gapDays; // Gap between intervals in days
        uint256 numberOfIntervals; // Number of intervals
        ReleaseMethod releaseMethod;
    }

    struct VestingGrant {
        uint256 grantAmount; // Total number of tokens granted
        bool isRevocable; // true if vesting grant is revocable (a gift), false if irrevocable (purchased)
        bool isRevoked; // true if vesting grant has been revoked
        bool isActive; // true if vesting grant is active
    }

    uint256 public constant BATCH_MAX_NUM = 200;
    uint256 public constant PERCENT_100_WEI = 100 ether;
    uint256 public constant SECONDS_IN_DAY = 86400;

    address public governanceAccount;
    address public vestingAdmin;
    address public tokenAddress;
    uint256 public totalGrantAmount;
    uint256 public totalReleasedAmount;
    uint256 public scheduleStartTimestamp;
    bool public allowAccumulate;

    VestingSchedule private _vestingSchedule;
    mapping(address => VestingGrant) private _vestingGrants;
    mapping(address => uint256) private _released;

    constructor(
        address tokenAddress_,
        uint256 cliffDurationDays,
        uint256 percentReleaseAtScheduleStart,
        uint256 percentReleaseForEachInterval,
        uint256 intervalDays,
        uint256 gapDays,
        uint256 numberOfIntervals,
        ReleaseMethod releaseMethod,
        bool allowAccumulate_
    ) {
        require(tokenAddress_ != address(0), "Vesting: zero token address");
        require(
            percentReleaseAtScheduleStart <= PERCENT_100_WEI,
            "Vesting: percent release at grant start > 100%"
        );
        require(
            percentReleaseForEachInterval <= PERCENT_100_WEI,
            "Vesting: percent release for each interval > 100%"
        );
        require(intervalDays > 0, "Vesting: zero interval");
        require(
            percentReleaseAtScheduleStart.add(
                percentReleaseForEachInterval.mul(numberOfIntervals)
            ) <= PERCENT_100_WEI,
            "Vesting: total percent release > 100%"
        );

        governanceAccount = msg.sender;
        vestingAdmin = msg.sender;
        tokenAddress = tokenAddress_;

        _vestingSchedule.cliffDurationDays = cliffDurationDays;
        _vestingSchedule
            .percentReleaseAtScheduleStart = percentReleaseAtScheduleStart;
        _vestingSchedule
            .percentReleaseForEachInterval = percentReleaseForEachInterval;
        _vestingSchedule.intervalDays = intervalDays;
        _vestingSchedule.gapDays = gapDays;
        _vestingSchedule.numberOfIntervals = numberOfIntervals;
        _vestingSchedule.releaseMethod = releaseMethod;

        allowAccumulate = allowAccumulate_;
    }

    modifier onlyBy(address account) {
        require(msg.sender == account, "Vesting: sender unauthorized");
        _;
    }

    /**
     * @dev isRevocable will be ignored if grant already added but amount allowed to accumulate.
     */
    function addVestingGrant(
        address account,
        uint256 grantAmount,
        bool isRevocable
    ) external override onlyBy(vestingAdmin) {
        _addVestingGrant(account, grantAmount, isRevocable);
    }

    function revokeVestingGrant(address account)
        external
        override
        onlyBy(vestingAdmin)
    {
        _revokeVestingGrant(account);
    }

    function release() external override {
        uint256 releasableAmount = releasableAmountFor(msg.sender);

        _release(msg.sender, releasableAmount);
    }

    function transferUnusedTokens()
        external
        override
        onlyBy(governanceAccount)
    {
        uint256 unusedAmount = IERC20(tokenAddress)
            .balanceOf(address(this))
            .add(totalReleasedAmount)
            .sub(totalGrantAmount);
        require(unusedAmount > 0, "Vesting: nothing to transfer");

        IERC20(tokenAddress).safeTransfer(governanceAccount, unusedAmount);
    }

    function addVestingGrantsBatch(
        address[] memory accounts,
        uint256[] memory grantAmounts,
        bool[] memory isRevocables
    ) external override onlyBy(vestingAdmin) {
        require(accounts.length > 0, "Vesting: empty");
        require(accounts.length <= BATCH_MAX_NUM, "Vesting: exceed max");
        require(
            grantAmounts.length == accounts.length,
            "Vesting: grant amounts length different"
        );
        require(
            isRevocables.length == accounts.length,
            "Vesting: is revocables length different"
        );

        for (uint256 i = 0; i < accounts.length; i++) {
            _addVestingGrant(accounts[i], grantAmounts[i], isRevocables[i]);
        }
    }

    function setScheduleStartTimestamp(uint256 scheduleStartTimestamp_)
        external
        override
        onlyBy(vestingAdmin)
    {
        require(
            scheduleStartTimestamp_ > block.timestamp,
            "Vesting: start before current timestamp"
        );

        uint256 oldScheduleStartTimestamp = scheduleStartTimestamp;
        require(
            oldScheduleStartTimestamp == 0 ||
                block.timestamp < oldScheduleStartTimestamp,
            "Vesting: already started"
        );

        scheduleStartTimestamp = scheduleStartTimestamp_;

        emit ScheduleStartTimestampSet(
            msg.sender,
            scheduleStartTimestamp_,
            oldScheduleStartTimestamp
        );
    }

    function setGovernanceAccount(address account)
        external
        override
        onlyBy(governanceAccount)
    {
        require(account != address(0), "Vesting: zero account");

        governanceAccount = account;
    }

    function setVestingAdmin(address account)
        external
        override
        onlyBy(governanceAccount)
    {
        require(account != address(0), "Vesting: zero account");

        vestingAdmin = account;
    }

    function getVestingSchedule()
        external
        view
        override
        returns (
            uint256 cliffDurationDays,
            uint256 percentReleaseAtScheduleStart,
            uint256 percentReleaseForEachInterval,
            uint256 intervalDays,
            uint256 gapDays,
            uint256 numberOfIntervals,
            ReleaseMethod releaseMethod
        )
    {
        VestingSchedule memory vestingSchedule = _vestingSchedule;
        cliffDurationDays = vestingSchedule.cliffDurationDays;
        percentReleaseAtScheduleStart = vestingSchedule
            .percentReleaseAtScheduleStart;
        percentReleaseForEachInterval = vestingSchedule
            .percentReleaseForEachInterval;
        intervalDays = vestingSchedule.intervalDays;
        gapDays = vestingSchedule.gapDays;
        numberOfIntervals = vestingSchedule.numberOfIntervals;
        releaseMethod = vestingSchedule.releaseMethod;
    }

    function vestingGrantFor(address account)
        external
        view
        override
        returns (
            uint256 grantAmount,
            bool isRevocable,
            bool isRevoked,
            bool isActive
        )
    {
        require(account != address(0), "Vesting: zero account");

        VestingGrant memory vestingGrant = _vestingGrants[account];
        grantAmount = vestingGrant.grantAmount;
        isRevocable = vestingGrant.isRevocable;
        isRevoked = vestingGrant.isRevoked;
        isActive = vestingGrant.isActive;
    }

    function revoked(address account)
        public
        view
        override
        returns (bool isRevoked)
    {
        require(account != address(0), "Vesting: zero account");

        isRevoked = _vestingGrants[account].isRevoked;
    }

    function releasedAmountFor(address account)
        public
        view
        override
        returns (uint256 releasedAmount)
    {
        require(account != address(0), "Vesting: zero account");

        releasedAmount = _released[account];
    }

    function releasableAmountFor(address account)
        public
        view
        override
        returns (uint256 releasableAmount)
    {
        require(account != address(0), "Vesting: zero account");

        uint256 startTimestamp = scheduleStartTimestamp;
        require(startTimestamp > 0, "Vesting: undefined start time");
        require(block.timestamp >= startTimestamp, "Vesting: not started");

        require(!revoked(account), "Vesting: revoked");

        uint256 vestedAmount = vestedAmountFor(account);
        releasableAmount = vestedAmount.sub(releasedAmountFor(account));
    }

    function vestedAmountFor(address account)
        public
        view
        override
        returns (uint256 vestedAmount)
    {
        require(account != address(0), "Vesting: zero account");

        VestingGrant memory vestingGrant = _vestingGrants[account];
        require(vestingGrant.isActive, "Vesting: inactive");

        uint256 startTimestamp = scheduleStartTimestamp;

        if (startTimestamp == 0) {
            return 0;
        }

        if (block.timestamp < startTimestamp) {
            return 0;
        }

        if (revoked(account)) {
            return releasedAmountFor(account);
        }

        VestingSchedule memory vestingSchedule = _vestingSchedule;

        vestedAmount = 0;

        if (vestingSchedule.percentReleaseAtScheduleStart > 0) {
            vestedAmount = vestingGrant
                .grantAmount
                .mul(vestingSchedule.percentReleaseAtScheduleStart)
                .div(PERCENT_100_WEI);
        }

        uint256 cliffEndTimestamp = startTimestamp.add(
            vestingSchedule.cliffDurationDays.mul(SECONDS_IN_DAY)
        );
        if (block.timestamp < cliffEndTimestamp) {
            return vestedAmount;
        }

        uint256 intervalSeconds = vestingSchedule.intervalDays.mul(
            SECONDS_IN_DAY
        );
        uint256 gapSeconds = vestingSchedule.gapDays.mul(SECONDS_IN_DAY);
        uint256 scheduleEndTimestamp = cliffEndTimestamp
            .add(intervalSeconds.mul(vestingSchedule.numberOfIntervals))
            .add(gapSeconds.mul(vestingSchedule.numberOfIntervals.sub(1)));
        if (block.timestamp >= scheduleEndTimestamp) {
            vestedAmount = vestingGrant.grantAmount;
            return vestedAmount;
        }

        // https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply
        // slither-disable-next-line divide-before-multiply
        uint256 intervalNumber = block.timestamp.sub(cliffEndTimestamp).div(
            intervalSeconds.add(gapSeconds)
        );
        require(
            intervalNumber < vestingSchedule.numberOfIntervals,
            "Vesting: unexpected interval number"
        );

        // https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply
        // slither-disable-next-line divide-before-multiply
        uint256 totalPercentage = vestingSchedule
            .percentReleaseForEachInterval
            .mul(intervalNumber);
        if (vestingSchedule.releaseMethod == ReleaseMethod.IntervalEnd) {
            // solhint-disable-previous-line no-empty-blocks
        } else if (
            vestingSchedule.releaseMethod == ReleaseMethod.LinearlyPerSecond
        ) {
            // https://github.com/crytic/slither/wiki/Detector-Documentation#divide-before-multiply
            // slither-disable-next-line divide-before-multiply
            uint256 secondsInInterval = block.timestamp.sub(
                cliffEndTimestamp.add(
                    intervalSeconds.add(gapSeconds).mul(intervalNumber)
                )
            );
            totalPercentage = secondsInInterval >= intervalSeconds
                ? totalPercentage.add(
                    vestingSchedule.percentReleaseForEachInterval
                )
                : totalPercentage.add(
                    vestingSchedule
                        .percentReleaseForEachInterval
                        .mul(secondsInInterval)
                        .div(intervalSeconds)
                );
        } else {
            require(false, "Vesting: unexpected release method");
        }

        uint256 maxPercentage = PERCENT_100_WEI.sub(
            vestingSchedule.percentReleaseAtScheduleStart
        );
        if (totalPercentage > maxPercentage) {
            totalPercentage = maxPercentage;
        }

        vestedAmount = vestedAmount.add(
            vestingGrant.grantAmount.mul(totalPercentage).div(PERCENT_100_WEI)
        );
    }

    function unvestedAmountFor(address account)
        external
        view
        override
        returns (uint256 unvestedAmount)
    {
        require(account != address(0), "Vesting: zero account");

        VestingGrant memory vestingGrant = _vestingGrants[account];
        require(vestingGrant.isActive, "Vesting: inactive");

        if (revoked(account)) {
            unvestedAmount = 0;
        } else {
            unvestedAmount = vestingGrant.grantAmount.sub(
                vestedAmountFor(account)
            );
        }
    }

    function _addVestingGrant(
        address account,
        uint256 grantAmount,
        bool isRevocable
    ) private {
        require(account != address(0), "Vesting: zero account");
        require(grantAmount > 0, "Vesting: zero grant amount");

        uint256 startTimestamp = scheduleStartTimestamp;
        require(
            startTimestamp == 0 || block.timestamp < startTimestamp,
            "Vesting: already started"
        );

        VestingGrant memory vestingGrant = _vestingGrants[account];
        require(
            allowAccumulate || !vestingGrant.isActive,
            "Vesting: already added"
        );
        require(!revoked(account), "Vesting: already revoked");

        totalGrantAmount = totalGrantAmount.add(grantAmount);
        require(
            totalGrantAmount <= IERC20(tokenAddress).balanceOf(address(this)),
            "Vesting: total grant amount exceed balance"
        );

        if (vestingGrant.isActive) {
            _vestingGrants[account].grantAmount = vestingGrant.grantAmount.add(
                grantAmount
            );
            // _vestingGrants[account].isRevocable = isRevocable;
        } else {
            _vestingGrants[account] = VestingGrant({
                grantAmount: grantAmount,
                isRevocable: isRevocable,
                isRevoked: false,
                isActive: true
            });
        }

        emit VestingGrantAdded(account, grantAmount, isRevocable);
    }

    function _revokeVestingGrant(address account) private {
        require(account != address(0), "Vesting: zero account");

        VestingGrant memory vestingGrant = _vestingGrants[account];
        require(vestingGrant.isActive, "Vesting: inactive");
        require(vestingGrant.isRevocable, "Vesting: not revocable");
        require(!revoked(account), "Vesting: already revoked");

        uint256 releasedAmount = releasedAmountFor(account);
        uint256 remainderAmount = vestingGrant.grantAmount.sub(releasedAmount);
        totalGrantAmount = totalGrantAmount.sub(remainderAmount);
        _vestingGrants[account].isRevoked = true;

        emit VestingGrantRevoked(
            account,
            remainderAmount,
            vestingGrant.grantAmount,
            releasedAmount
        );
    }

    function _release(address account, uint256 amount) private {
        require(account != address(0), "Vesting: zero account");
        require(amount > 0, "Vesting: zero amount");

        _released[account] = _released[account].add(amount);
        totalReleasedAmount = totalReleasedAmount.add(amount);

        emit TokensReleased(account, amount);

        IERC20(tokenAddress).safeTransfer(account, amount);
    }
}

File 2 of 6 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import "./IERC20.sol";
import "../../math/SafeMath.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 SafeMath for uint256;
    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'
        // solhint-disable-next-line max-line-length
        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).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        _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
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

File 3 of 6 : IVesting.sol
// SPDX-License-Identifier: Apache-2.0
// Copyright 2021 Enjinstarter
pragma solidity ^0.7.6;

/**
 * @title IVesting
 * @author Enjinstarter
 */
interface IVesting {
    enum ReleaseMethod {
        IntervalEnd, // 0: at end of each interval
        LinearlyPerSecond //  1: linearly per second across interval
    }

    function addVestingGrant(
        address account,
        uint256 grantAmount,
        bool isRevocable
    ) external;

    function revokeVestingGrant(address account) external;

    function release() external;

    function transferUnusedTokens() external;

    function addVestingGrantsBatch(
        address[] memory accounts,
        uint256[] memory grantAmounts,
        bool[] memory isRevocables
    ) external;

    function setScheduleStartTimestamp(uint256 scheduleStartTimestamp_)
        external;

    function setGovernanceAccount(address account) external;

    function setVestingAdmin(address account) external;

    function getVestingSchedule()
        external
        view
        returns (
            uint256 cliffDurationDays,
            uint256 percentReleaseAtGrantStart,
            uint256 percentReleaseAtIntervalStart,
            uint256 intervalDays,
            uint256 gapDays,
            uint256 numberOfIntervals,
            ReleaseMethod releaseMethod
        );

    function vestingGrantFor(address account)
        external
        view
        returns (
            uint256 grantAmount,
            bool isRevocable,
            bool isRevoked,
            bool isActive
        );

    function revoked(address account) external view returns (bool isRevoked);

    function releasedAmountFor(address account)
        external
        view
        returns (uint256 releasedAmount);

    function releasableAmountFor(address account)
        external
        view
        returns (uint256 unreleasedAmount);

    function vestedAmountFor(address account)
        external
        view
        returns (uint256 vestedAmount);

    function unvestedAmountFor(address account)
        external
        view
        returns (uint256 unvestedAmount);

    event VestingGrantAdded(
        address indexed account,
        uint256 indexed grantAmount,
        bool isRevocable
    );
    event VestingGrantRevoked(
        address indexed account,
        uint256 remainderAmount,
        uint256 grantAmount,
        uint256 releasedAmount
    );
    event TokensReleased(address indexed account, uint256 amount);
    event ScheduleStartTimestampSet(
        address indexed account,
        uint256 newScheduleStartTimestamp,
        uint256 oldScheduleStartTimestamp
    );
}

File 4 of 6 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

File 5 of 6 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library 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) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        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) {
        // 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) {
        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) {
        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) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        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) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        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) {
        require(b > 0, "SafeMath: modulo by zero");
        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) {
        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.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        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) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

File 6 of 6 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <0.8.0;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 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");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"tokenAddress_","type":"address"},{"internalType":"uint256","name":"cliffDurationDays","type":"uint256"},{"internalType":"uint256","name":"percentReleaseAtScheduleStart","type":"uint256"},{"internalType":"uint256","name":"percentReleaseForEachInterval","type":"uint256"},{"internalType":"uint256","name":"intervalDays","type":"uint256"},{"internalType":"uint256","name":"gapDays","type":"uint256"},{"internalType":"uint256","name":"numberOfIntervals","type":"uint256"},{"internalType":"enum IVesting.ReleaseMethod","name":"releaseMethod","type":"uint8"},{"internalType":"bool","name":"allowAccumulate_","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"newScheduleStartTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldScheduleStartTimestamp","type":"uint256"}],"name":"ScheduleStartTimestampSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"grantAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isRevocable","type":"bool"}],"name":"VestingGrantAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"remainderAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"grantAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"releasedAmount","type":"uint256"}],"name":"VestingGrantRevoked","type":"event"},{"inputs":[],"name":"BATCH_MAX_NUM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERCENT_100_WEI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SECONDS_IN_DAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"grantAmount","type":"uint256"},{"internalType":"bool","name":"isRevocable","type":"bool"}],"name":"addVestingGrant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"grantAmounts","type":"uint256[]"},{"internalType":"bool[]","name":"isRevocables","type":"bool[]"}],"name":"addVestingGrantsBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"allowAccumulate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVestingSchedule","outputs":[{"internalType":"uint256","name":"cliffDurationDays","type":"uint256"},{"internalType":"uint256","name":"percentReleaseAtScheduleStart","type":"uint256"},{"internalType":"uint256","name":"percentReleaseForEachInterval","type":"uint256"},{"internalType":"uint256","name":"intervalDays","type":"uint256"},{"internalType":"uint256","name":"gapDays","type":"uint256"},{"internalType":"uint256","name":"numberOfIntervals","type":"uint256"},{"internalType":"enum IVesting.ReleaseMethod","name":"releaseMethod","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governanceAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"releasableAmountFor","outputs":[{"internalType":"uint256","name":"releasableAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"releasedAmountFor","outputs":[{"internalType":"uint256","name":"releasedAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeVestingGrant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revoked","outputs":[{"internalType":"bool","name":"isRevoked","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"scheduleStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setGovernanceAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"scheduleStartTimestamp_","type":"uint256"}],"name":"setScheduleStartTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"setVestingAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalGrantAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleasedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transferUnusedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"unvestedAmountFor","outputs":[{"internalType":"uint256","name":"unvestedAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"vestedAmountFor","outputs":[{"internalType":"uint256","name":"vestedAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"vestingGrantFor","outputs":[{"internalType":"uint256","name":"grantAmount","type":"uint256"},{"internalType":"bool","name":"isRevocable","type":"bool"},{"internalType":"bool","name":"isRevoked","type":"bool"},{"internalType":"bool","name":"isActive","type":"bool"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b50604051620027d6380380620027d683398181016040526101208110156200003857600080fd5b508051602082015160408301516060840151608085015160a086015160c087015160e0880151610100909801519697959694959394929391929091906001600160a01b038916620000d0576040805162461bcd60e51b815260206004820152601b60248201527f56657374696e673a207a65726f20746f6b656e20616464726573730000000000604482015290519081900360640190fd5b68056bc75e2d631000008711156200011a5760405162461bcd60e51b815260040180806020018281038252602e815260200180620027a8602e913960400191505060405180910390fd5b68056bc75e2d63100000861115620001645760405162461bcd60e51b8152600401808060200182810382526031815260200180620027776031913960400191505060405180910390fd5b60008511620001ba576040805162461bcd60e51b815260206004820152601660248201527f56657374696e673a207a65726f20696e74657276616c00000000000000000000604482015290519081900360640190fd5b68056bc75e2d63100000620001f7620001e28589620002c760201b620015f51790919060201c565b896200032e60201b620016571790919060201c565b1115620002365760405162461bcd60e51b8152600401808060200182810382526025815260200180620027526025913960400191505060405180910390fd5b60008054336001600160a01b031991821681179092556001805482169092178255600280549091166001600160a01b038c16179055600789905560088890556009879055600a869055600b859055600c849055600d8054849260ff19909116908381811115620002a257fe5b02179055506006805460ff191691151591909117905550620003899650505050505050565b600082620002d85750600062000328565b82820282848281620002e657fe5b0414620003255760405162461bcd60e51b8152600401808060200182810382526021815260200180620027316021913960400191505060405180910390fd5b90505b92915050565b60008282018381101562000325576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b61239880620003996000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c806386d1a69f116100de578063cbe274d111610097578063f313372d11610071578063f313372d1461056f578063f5b65fea14610577578063f803b2cd1461059d578063fa01dc06146105c357610173565b8063cbe274d114610517578063de3e75201461051f578063f1c2111c1461055357610173565b806386d1a69f146104c95780638ac33be9146104d15780638e9463f6146104f75780639d76ea58146104ff578063ac6ddd5d14610507578063aff01b611461050f57610173565b80634229613d116101305780634229613d146102ba57806355c17ed1146102e057806359303ed81461030657806361a52a361461030e57806368f113eb1461031657806383273cd1146104c157610173565b8063045ea76e146101785780631032df4b146101b057806327144c05146101cf5780632cf2dab2146101f35780633a05f0d8146102415780633bea3c8d14610294575b600080fd5b61019e6004803603602081101561018e57600080fd5b50356001600160a01b03166105e9565b60408051918252519081900360200190f35b6101cd600480360360208110156101c657600080fd5b503561074b565b005b6101d7610876565b604080516001600160a01b039092168252519081900360200190f35b6102196004803603602081101561020957600080fd5b50356001600160a01b0316610885565b6040805194855292151560208501529015158383015215156060830152519081900360800190f35b61024961093a565b6040518088815260200187815260200186815260200185815260200184815260200183815260200182600181111561027d57fe5b815260200197505050505050505060405180910390f35b6101cd600480360360208110156102aa57600080fd5b50356001600160a01b03166109e1565b61019e600480360360208110156102d057600080fd5b50356001600160a01b0316610a9b565b61019e600480360360208110156102f657600080fd5b50356001600160a01b0316610b02565b6101cd610c23565b61019e610d91565b6101cd6004803603606081101561032c57600080fd5b81019060208101813564010000000081111561034757600080fd5b82018360208201111561035957600080fd5b8035906020019184602083028401116401000000008311171561037b57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156103cb57600080fd5b8201836020820111156103dd57600080fd5b803590602001918460208302840111640100000000831117156103ff57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561044f57600080fd5b82018360208201111561046157600080fd5b8035906020019184602083028401116401000000008311171561048357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610d98945050505050565b61019e610f59565b6101cd610f5f565b61019e600480360360208110156104e757600080fd5b50356001600160a01b0316610f79565b6101d76113ce565b6101d76113dd565b61019e6113ec565b61019e6113f1565b61019e6113fe565b6101cd6004803603606081101561053557600080fd5b506001600160a01b0381351690602081013590604001351515611404565b61055b611463565b604080519115158252519081900360200190f35b61019e61146c565b6101cd6004803603602081101561058d57600080fd5b50356001600160a01b0316611472565b6101cd600480360360208110156105b357600080fd5b50356001600160a01b031661152c565b61055b600480360360208110156105d957600080fd5b50356001600160a01b0316611583565b60006001600160a01b038216610634576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b60055480610689576040805162461bcd60e51b815260206004820152601d60248201527f56657374696e673a20756e646566696e65642073746172742074696d65000000604482015290519081900360640190fd5b804210156106d5576040805162461bcd60e51b815260206004820152601460248201527315995cdd1a5b99ce881b9bdd081cdd185c9d195960621b604482015290519081900360640190fd5b6106de83611583565b15610723576040805162461bcd60e51b815260206004820152601060248201526f15995cdd1a5b99ce881c995d9bdad95960821b604482015290519081900360640190fd5b600061072e84610f79565b905061074361073c85610a9b565b82906116b1565b949350505050565b6001546001600160a01b0316338114610799576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b4282116107d75760405162461bcd60e51b81526004018080602001828103825260278152602001806122856027913960400191505060405180910390fd5b6005548015806107e657508042105b610832576040805162461bcd60e51b815260206004820152601860248201527715995cdd1a5b99ce88185b1c9958591e481cdd185c9d195960421b604482015290519081900360640190fd5b60058390556040805184815260208101839052815133927f7cc9782852035bcec8a39e2f316483fbe8456229c22aac560a2c628c571e8819928290030190a2505050565b6000546001600160a01b031681565b60008080806001600160a01b0385166108d3576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b505050506001600160a01b03166000908152600e60209081526040918290208251608081018452815480825260019092015460ff80821615159483018590526101008204811615159583018690526201000090910416151560609091018190529093919291565b6040805160e081018252600780548252600854602083015260095492820192909252600a546060820152600b546080820152600c5460a0820152600d5460009283928392839283928392839283929160c083019060ff16600181111561099c57fe5b60018111156109a757fe5b9052508051602082015160408301516060840151608085015160a086015160c090960151949e939d50919b50995097509195509350915050565b6000546001600160a01b0316338114610a2f576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b6001600160a01b038216610a78576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b50600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038216610ae6576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b506001600160a01b03166000908152600f602052604090205490565b60006001600160a01b038216610b4d576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602090815260409182902082516080810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000090920416151560608201819052610bef576040805162461bcd60e51b815260206004820152601160248201527056657374696e673a20696e61637469766560781b604482015290519081900360640190fd5b610bf883611583565b15610c065760009150610c1d565b610c1a610c1284610f79565b8251906116b1565b91505b50919050565b6000546001600160a01b0316338114610c71576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b6000610d19600354610d13600454600260009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610ce157600080fd5b505afa158015610cf5573d6000803e3d6000fd5b505050506040513d6020811015610d0b57600080fd5b505190611657565b906116b1565b905060008111610d70576040805162461bcd60e51b815260206004820152601c60248201527f56657374696e673a206e6f7468696e6720746f207472616e7366657200000000604482015290519081900360640190fd5b600054600254610d8d916001600160a01b0391821691168361170e565b5050565b6201518081565b6001546001600160a01b0316338114610de6576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b6000845111610e2d576040805162461bcd60e51b815260206004820152600e60248201526d56657374696e673a20656d70747960901b604482015290519081900360640190fd5b60c884511115610e7a576040805162461bcd60e51b81526020600482015260136024820152720accae6e8d2dcce7440caf0c6cacac840dac2f606b1b604482015290519081900360640190fd5b8351835114610eba5760405162461bcd60e51b81526004018080602001828103825260278152602001806122186027913960400191505060405180910390fd5b8351825114610efa5760405162461bcd60e51b81526004018080602001828103825260278152602001806121ce6027913960400191505060405180910390fd5b60005b8451811015610f5257610f4a858281518110610f1557fe5b6020026020010151858381518110610f2957fe5b6020026020010151858481518110610f3d57fe5b6020026020010151611765565b600101610efd565b5050505050565b60045481565b6000610f6a336105e9565b9050610f763382611b31565b50565b60006001600160a01b038216610fc4576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602090815260409182902082516080810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000090920416151560608201819052611066576040805162461bcd60e51b815260206004820152601160248201527056657374696e673a20696e61637469766560781b604482015290519081900360640190fd5b60055480611079576000925050506113c9565b8042101561108c576000925050506113c9565b61109584611583565b156110ac576110a384610a9b565b925050506113c9565b6040805160e081018252600780548252600854602083015260095492820192909252600a546060820152600b546080820152600c5460a0820152600d546000929060c083019060ff16600181111561110057fe5b600181111561110b57fe5b9052506020810151600095509091501561114757602081015183516111449168056bc75e2d631000009161113e916115f5565b90611c68565b93505b80516000906111649061115d90620151806115f5565b8490611657565b90508042101561117757505050506113c9565b606082015160009061118c90620151806115f5565b905060006111aa6201518085608001516115f590919063ffffffff16565b905060006111fa6111d36111cc60018860a001516116b190919063ffffffff16565b84906115f5565b6111f46111ed8860a00151876115f590919063ffffffff16565b8790611657565b90611657565b9050804210611213575050935194506113c99350505050565b600061122c6112228585611657565b61113e42886116b1565b90508560a0015181106112705760405162461bcd60e51b81526004018080602001828103825260238152602001806121f56023913960400191505060405180910390fd5b604086015160009061128290836115f5565b905060008760c00151600181111561129657fe5b14156112a157611366565b60018760c0015160018111156112b357fe5b141561132f5760006112e36112dc6112d5856112cf8a8a611657565b906115f5565b8990611657565b42906116b1565b9050858110156113175761131261130b8761113e848c604001516115f590919063ffffffff16565b8390611657565b611327565b6040880151611327908390611657565b915050611366565b60405162461bcd60e51b81526004018080602001828103825260228152602001806123176022913960400191505060405180910390fd5b6000611388886020015168056bc75e2d631000006116b190919063ffffffff16565b905080821115611396578091505b89516113bc906113b59068056bc75e2d631000009061113e90866115f5565b8c90611657565b9a50505050505050505050505b919050565b6001546001600160a01b031681565b6002546001600160a01b031681565b60c881565b68056bc75e2d6310000081565b60035481565b6001546001600160a01b0316338114611452576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b61145d848484611765565b50505050565b60065460ff1681565b60055481565b6000546001600160a01b03163381146114c0576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b6001600160a01b038216611509576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b50600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633811461157a576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b610d8d82611ccf565b60006001600160a01b0382166115ce576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b506001600160a01b03166000908152600e6020526040902060010154610100900460ff1690565b60008261160457506000611651565b8282028284828161161157fe5b041461164e5760405162461bcd60e51b81526004018080602001828103825260218152602001806122d66021913960400191505060405180910390fd5b90505b92915050565b60008282018381101561164e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082821115611708576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611760908490611efe565b505050565b6001600160a01b0383166117ae576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b60008211611803576040805162461bcd60e51b815260206004820152601a60248201527f56657374696e673a207a65726f206772616e7420616d6f756e74000000000000604482015290519081900360640190fd5b60055480158061181257508042105b61185e576040805162461bcd60e51b815260206004820152601860248201527715995cdd1a5b99ce88185b1c9958591e481cdd185c9d195960421b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e602090815260409182902082516080810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000090920481161515606083015260065416806118cb57508060600151155b611915576040805162461bcd60e51b815260206004820152601660248201527515995cdd1a5b99ce88185b1c9958591e48185919195960521b604482015290519081900360640190fd5b61191e85611583565b1561196b576040805162461bcd60e51b815260206004820152601860248201527715995cdd1a5b99ce88185b1c9958591e481c995d9bdad95960421b604482015290519081900360640190fd5b6003546119789085611657565b600355600254604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156119c657600080fd5b505afa1580156119da573d6000803e3d6000fd5b505050506040513d60208110156119f057600080fd5b50516003541115611a325760405162461bcd60e51b815260040180806020018281038252602a8152602001806122ac602a913960400191505060405180910390fd5b806060015115611a66578051611a489085611657565b6001600160a01b0386166000908152600e6020526040902055611ae8565b60408051608081018252858152841515602080830191825260008385018181526001606086018181526001600160a01b038d168452600e90945295909120935184559151929093018054915193511515620100000262ff0000199415156101000261ff001994151560ff19909416939093179390931691909117929092161790555b604080518415158152905185916001600160a01b038816917f4e623b5b8a8f6ed80fac7bdb7744dcf9e24e56e76819aebd9c0321ba115d24669181900360200190a35050505050565b6001600160a01b038216611b7a576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b60008111611bc6576040805162461bcd60e51b815260206004820152601460248201527315995cdd1a5b99ce881e995c9bc8185b5bdd5b9d60621b604482015290519081900360640190fd5b6001600160a01b0382166000908152600f6020526040902054611be99082611657565b6001600160a01b0383166000908152600f6020526040902055600454611c0f9082611657565b6004556040805182815290516001600160a01b038416917fc7798891864187665ac6dd119286e44ec13f014527aeeb2b8eb3fd413df93179919081900360200190a2600254610d8d906001600160a01b0316838361170e565b6000808211611cbe576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611cc757fe5b049392505050565b6001600160a01b038116611d18576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b6001600160a01b0381166000908152600e602090815260409182902082516080810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000090920416151560608201819052611dba576040805162461bcd60e51b815260206004820152601160248201527056657374696e673a20696e61637469766560781b604482015290519081900360640190fd5b8060200151611e09576040805162461bcd60e51b815260206004820152601660248201527556657374696e673a206e6f74207265766f6361626c6560501b604482015290519081900360640190fd5b611e1282611583565b15611e5f576040805162461bcd60e51b815260206004820152601860248201527715995cdd1a5b99ce88185b1c9958591e481c995d9bdad95960421b604482015290519081900360640190fd5b6000611e6a83610a9b565b8251909150600090611e7c90836116b1565b600354909150611e8c90826116b1565b6003556001600160a01b0384166000818152600e6020908152604091829020600101805461ff001916610100179055855182518581529182015280820185905290517f2cbcf429217a291c55cc57abc1ff239f99b18cd7a753f01614bc352db23178c99181900360600190a250505050565b6000611f53826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611faf9092919063ffffffff16565b80519091501561176057808060200190516020811015611f7257600080fd5b50516117605760405162461bcd60e51b815260040180806020018281038252602a815260200180612339602a913960400191505060405180910390fd5b6060611fbe8484600085611fc8565b90505b9392505050565b6060824710156120095760405162461bcd60e51b815260040180806020018281038252602681526020018061223f6026913960400191505060405180910390fd5b61201285612123565b612063576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106120a15780518252601f199092019160209182019101612082565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612103576040519150601f19603f3d011682016040523d82523d6000602084013e612108565b606091505b5091509150612118828286612129565b979650505050505050565b3b151590565b60608315612138575081611fc1565b8251156121485782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561219257818101518382015260200161217a565b50505050905090810190601f1680156121bf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe56657374696e673a206973207265766f6361626c6573206c656e67746820646966666572656e7456657374696e673a20756e657870656374656420696e74657276616c206e756d62657256657374696e673a206772616e7420616d6f756e7473206c656e67746820646966666572656e74416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c56657374696e673a2073656e64657220756e617574686f72697a65640000000056657374696e673a207374617274206265666f72652063757272656e742074696d657374616d7056657374696e673a20746f74616c206772616e7420616d6f756e74206578636565642062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7756657374696e673a207a65726f206163636f756e74000000000000000000000056657374696e673a20756e65787065637465642072656c65617365206d6574686f645361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220f17945974f5dc2ff1e2889e2694222d04088e6a0054ebd47ad2c608135ced79e64736f6c63430007060033536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7756657374696e673a20746f74616c2070657263656e742072656c65617365203e203130302556657374696e673a2070657263656e742072656c6561736520666f72206561636820696e74657276616c203e203130302556657374696e673a2070657263656e742072656c65617365206174206772616e74207374617274203e203130302500000000000000000000000096610186f3ab8d73ebee1cf950c750f3b1fb79c2000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101735760003560e01c806386d1a69f116100de578063cbe274d111610097578063f313372d11610071578063f313372d1461056f578063f5b65fea14610577578063f803b2cd1461059d578063fa01dc06146105c357610173565b8063cbe274d114610517578063de3e75201461051f578063f1c2111c1461055357610173565b806386d1a69f146104c95780638ac33be9146104d15780638e9463f6146104f75780639d76ea58146104ff578063ac6ddd5d14610507578063aff01b611461050f57610173565b80634229613d116101305780634229613d146102ba57806355c17ed1146102e057806359303ed81461030657806361a52a361461030e57806368f113eb1461031657806383273cd1146104c157610173565b8063045ea76e146101785780631032df4b146101b057806327144c05146101cf5780632cf2dab2146101f35780633a05f0d8146102415780633bea3c8d14610294575b600080fd5b61019e6004803603602081101561018e57600080fd5b50356001600160a01b03166105e9565b60408051918252519081900360200190f35b6101cd600480360360208110156101c657600080fd5b503561074b565b005b6101d7610876565b604080516001600160a01b039092168252519081900360200190f35b6102196004803603602081101561020957600080fd5b50356001600160a01b0316610885565b6040805194855292151560208501529015158383015215156060830152519081900360800190f35b61024961093a565b6040518088815260200187815260200186815260200185815260200184815260200183815260200182600181111561027d57fe5b815260200197505050505050505060405180910390f35b6101cd600480360360208110156102aa57600080fd5b50356001600160a01b03166109e1565b61019e600480360360208110156102d057600080fd5b50356001600160a01b0316610a9b565b61019e600480360360208110156102f657600080fd5b50356001600160a01b0316610b02565b6101cd610c23565b61019e610d91565b6101cd6004803603606081101561032c57600080fd5b81019060208101813564010000000081111561034757600080fd5b82018360208201111561035957600080fd5b8035906020019184602083028401116401000000008311171561037b57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092959493602081019350359150506401000000008111156103cb57600080fd5b8201836020820111156103dd57600080fd5b803590602001918460208302840111640100000000831117156103ff57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561044f57600080fd5b82018360208201111561046157600080fd5b8035906020019184602083028401116401000000008311171561048357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610d98945050505050565b61019e610f59565b6101cd610f5f565b61019e600480360360208110156104e757600080fd5b50356001600160a01b0316610f79565b6101d76113ce565b6101d76113dd565b61019e6113ec565b61019e6113f1565b61019e6113fe565b6101cd6004803603606081101561053557600080fd5b506001600160a01b0381351690602081013590604001351515611404565b61055b611463565b604080519115158252519081900360200190f35b61019e61146c565b6101cd6004803603602081101561058d57600080fd5b50356001600160a01b0316611472565b6101cd600480360360208110156105b357600080fd5b50356001600160a01b031661152c565b61055b600480360360208110156105d957600080fd5b50356001600160a01b0316611583565b60006001600160a01b038216610634576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b60055480610689576040805162461bcd60e51b815260206004820152601d60248201527f56657374696e673a20756e646566696e65642073746172742074696d65000000604482015290519081900360640190fd5b804210156106d5576040805162461bcd60e51b815260206004820152601460248201527315995cdd1a5b99ce881b9bdd081cdd185c9d195960621b604482015290519081900360640190fd5b6106de83611583565b15610723576040805162461bcd60e51b815260206004820152601060248201526f15995cdd1a5b99ce881c995d9bdad95960821b604482015290519081900360640190fd5b600061072e84610f79565b905061074361073c85610a9b565b82906116b1565b949350505050565b6001546001600160a01b0316338114610799576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b4282116107d75760405162461bcd60e51b81526004018080602001828103825260278152602001806122856027913960400191505060405180910390fd5b6005548015806107e657508042105b610832576040805162461bcd60e51b815260206004820152601860248201527715995cdd1a5b99ce88185b1c9958591e481cdd185c9d195960421b604482015290519081900360640190fd5b60058390556040805184815260208101839052815133927f7cc9782852035bcec8a39e2f316483fbe8456229c22aac560a2c628c571e8819928290030190a2505050565b6000546001600160a01b031681565b60008080806001600160a01b0385166108d3576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b505050506001600160a01b03166000908152600e60209081526040918290208251608081018452815480825260019092015460ff80821615159483018590526101008204811615159583018690526201000090910416151560609091018190529093919291565b6040805160e081018252600780548252600854602083015260095492820192909252600a546060820152600b546080820152600c5460a0820152600d5460009283928392839283928392839283929160c083019060ff16600181111561099c57fe5b60018111156109a757fe5b9052508051602082015160408301516060840151608085015160a086015160c090960151949e939d50919b50995097509195509350915050565b6000546001600160a01b0316338114610a2f576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b6001600160a01b038216610a78576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b50600180546001600160a01b0319166001600160a01b0392909216919091179055565b60006001600160a01b038216610ae6576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b506001600160a01b03166000908152600f602052604090205490565b60006001600160a01b038216610b4d576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602090815260409182902082516080810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000090920416151560608201819052610bef576040805162461bcd60e51b815260206004820152601160248201527056657374696e673a20696e61637469766560781b604482015290519081900360640190fd5b610bf883611583565b15610c065760009150610c1d565b610c1a610c1284610f79565b8251906116b1565b91505b50919050565b6000546001600160a01b0316338114610c71576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b6000610d19600354610d13600454600260009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610ce157600080fd5b505afa158015610cf5573d6000803e3d6000fd5b505050506040513d6020811015610d0b57600080fd5b505190611657565b906116b1565b905060008111610d70576040805162461bcd60e51b815260206004820152601c60248201527f56657374696e673a206e6f7468696e6720746f207472616e7366657200000000604482015290519081900360640190fd5b600054600254610d8d916001600160a01b0391821691168361170e565b5050565b6201518081565b6001546001600160a01b0316338114610de6576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b6000845111610e2d576040805162461bcd60e51b815260206004820152600e60248201526d56657374696e673a20656d70747960901b604482015290519081900360640190fd5b60c884511115610e7a576040805162461bcd60e51b81526020600482015260136024820152720accae6e8d2dcce7440caf0c6cacac840dac2f606b1b604482015290519081900360640190fd5b8351835114610eba5760405162461bcd60e51b81526004018080602001828103825260278152602001806122186027913960400191505060405180910390fd5b8351825114610efa5760405162461bcd60e51b81526004018080602001828103825260278152602001806121ce6027913960400191505060405180910390fd5b60005b8451811015610f5257610f4a858281518110610f1557fe5b6020026020010151858381518110610f2957fe5b6020026020010151858481518110610f3d57fe5b6020026020010151611765565b600101610efd565b5050505050565b60045481565b6000610f6a336105e9565b9050610f763382611b31565b50565b60006001600160a01b038216610fc4576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b6001600160a01b0382166000908152600e602090815260409182902082516080810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000090920416151560608201819052611066576040805162461bcd60e51b815260206004820152601160248201527056657374696e673a20696e61637469766560781b604482015290519081900360640190fd5b60055480611079576000925050506113c9565b8042101561108c576000925050506113c9565b61109584611583565b156110ac576110a384610a9b565b925050506113c9565b6040805160e081018252600780548252600854602083015260095492820192909252600a546060820152600b546080820152600c5460a0820152600d546000929060c083019060ff16600181111561110057fe5b600181111561110b57fe5b9052506020810151600095509091501561114757602081015183516111449168056bc75e2d631000009161113e916115f5565b90611c68565b93505b80516000906111649061115d90620151806115f5565b8490611657565b90508042101561117757505050506113c9565b606082015160009061118c90620151806115f5565b905060006111aa6201518085608001516115f590919063ffffffff16565b905060006111fa6111d36111cc60018860a001516116b190919063ffffffff16565b84906115f5565b6111f46111ed8860a00151876115f590919063ffffffff16565b8790611657565b90611657565b9050804210611213575050935194506113c99350505050565b600061122c6112228585611657565b61113e42886116b1565b90508560a0015181106112705760405162461bcd60e51b81526004018080602001828103825260238152602001806121f56023913960400191505060405180910390fd5b604086015160009061128290836115f5565b905060008760c00151600181111561129657fe5b14156112a157611366565b60018760c0015160018111156112b357fe5b141561132f5760006112e36112dc6112d5856112cf8a8a611657565b906115f5565b8990611657565b42906116b1565b9050858110156113175761131261130b8761113e848c604001516115f590919063ffffffff16565b8390611657565b611327565b6040880151611327908390611657565b915050611366565b60405162461bcd60e51b81526004018080602001828103825260228152602001806123176022913960400191505060405180910390fd5b6000611388886020015168056bc75e2d631000006116b190919063ffffffff16565b905080821115611396578091505b89516113bc906113b59068056bc75e2d631000009061113e90866115f5565b8c90611657565b9a50505050505050505050505b919050565b6001546001600160a01b031681565b6002546001600160a01b031681565b60c881565b68056bc75e2d6310000081565b60035481565b6001546001600160a01b0316338114611452576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b61145d848484611765565b50505050565b60065460ff1681565b60055481565b6000546001600160a01b03163381146114c0576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b6001600160a01b038216611509576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b50600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031633811461157a576040805162461bcd60e51b815260206004820152601c6024820152600080516020612265833981519152604482015290519081900360640190fd5b610d8d82611ccf565b60006001600160a01b0382166115ce576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b506001600160a01b03166000908152600e6020526040902060010154610100900460ff1690565b60008261160457506000611651565b8282028284828161161157fe5b041461164e5760405162461bcd60e51b81526004018080602001828103825260218152602001806122d66021913960400191505060405180910390fd5b90505b92915050565b60008282018381101561164e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082821115611708576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611760908490611efe565b505050565b6001600160a01b0383166117ae576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b60008211611803576040805162461bcd60e51b815260206004820152601a60248201527f56657374696e673a207a65726f206772616e7420616d6f756e74000000000000604482015290519081900360640190fd5b60055480158061181257508042105b61185e576040805162461bcd60e51b815260206004820152601860248201527715995cdd1a5b99ce88185b1c9958591e481cdd185c9d195960421b604482015290519081900360640190fd5b6001600160a01b0384166000908152600e602090815260409182902082516080810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000090920481161515606083015260065416806118cb57508060600151155b611915576040805162461bcd60e51b815260206004820152601660248201527515995cdd1a5b99ce88185b1c9958591e48185919195960521b604482015290519081900360640190fd5b61191e85611583565b1561196b576040805162461bcd60e51b815260206004820152601860248201527715995cdd1a5b99ce88185b1c9958591e481c995d9bdad95960421b604482015290519081900360640190fd5b6003546119789085611657565b600355600254604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b1580156119c657600080fd5b505afa1580156119da573d6000803e3d6000fd5b505050506040513d60208110156119f057600080fd5b50516003541115611a325760405162461bcd60e51b815260040180806020018281038252602a8152602001806122ac602a913960400191505060405180910390fd5b806060015115611a66578051611a489085611657565b6001600160a01b0386166000908152600e6020526040902055611ae8565b60408051608081018252858152841515602080830191825260008385018181526001606086018181526001600160a01b038d168452600e90945295909120935184559151929093018054915193511515620100000262ff0000199415156101000261ff001994151560ff19909416939093179390931691909117929092161790555b604080518415158152905185916001600160a01b038816917f4e623b5b8a8f6ed80fac7bdb7744dcf9e24e56e76819aebd9c0321ba115d24669181900360200190a35050505050565b6001600160a01b038216611b7a576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b60008111611bc6576040805162461bcd60e51b815260206004820152601460248201527315995cdd1a5b99ce881e995c9bc8185b5bdd5b9d60621b604482015290519081900360640190fd5b6001600160a01b0382166000908152600f6020526040902054611be99082611657565b6001600160a01b0383166000908152600f6020526040902055600454611c0f9082611657565b6004556040805182815290516001600160a01b038416917fc7798891864187665ac6dd119286e44ec13f014527aeeb2b8eb3fd413df93179919081900360200190a2600254610d8d906001600160a01b0316838361170e565b6000808211611cbe576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611cc757fe5b049392505050565b6001600160a01b038116611d18576040805162461bcd60e51b815260206004820152601560248201526000805160206122f7833981519152604482015290519081900360640190fd5b6001600160a01b0381166000908152600e602090815260409182902082516080810184528154815260019091015460ff808216151593830193909352610100810483161515938201939093526201000090920416151560608201819052611dba576040805162461bcd60e51b815260206004820152601160248201527056657374696e673a20696e61637469766560781b604482015290519081900360640190fd5b8060200151611e09576040805162461bcd60e51b815260206004820152601660248201527556657374696e673a206e6f74207265766f6361626c6560501b604482015290519081900360640190fd5b611e1282611583565b15611e5f576040805162461bcd60e51b815260206004820152601860248201527715995cdd1a5b99ce88185b1c9958591e481c995d9bdad95960421b604482015290519081900360640190fd5b6000611e6a83610a9b565b8251909150600090611e7c90836116b1565b600354909150611e8c90826116b1565b6003556001600160a01b0384166000818152600e6020908152604091829020600101805461ff001916610100179055855182518581529182015280820185905290517f2cbcf429217a291c55cc57abc1ff239f99b18cd7a753f01614bc352db23178c99181900360600190a250505050565b6000611f53826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611faf9092919063ffffffff16565b80519091501561176057808060200190516020811015611f7257600080fd5b50516117605760405162461bcd60e51b815260040180806020018281038252602a815260200180612339602a913960400191505060405180910390fd5b6060611fbe8484600085611fc8565b90505b9392505050565b6060824710156120095760405162461bcd60e51b815260040180806020018281038252602681526020018061223f6026913960400191505060405180910390fd5b61201285612123565b612063576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106120a15780518252601f199092019160209182019101612082565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114612103576040519150601f19603f3d011682016040523d82523d6000602084013e612108565b606091505b5091509150612118828286612129565b979650505050505050565b3b151590565b60608315612138575081611fc1565b8251156121485782518084602001fd5b8160405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561219257818101518382015260200161217a565b50505050905090810190601f1680156121bf5780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe56657374696e673a206973207265766f6361626c6573206c656e67746820646966666572656e7456657374696e673a20756e657870656374656420696e74657276616c206e756d62657256657374696e673a206772616e7420616d6f756e7473206c656e67746820646966666572656e74416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c56657374696e673a2073656e64657220756e617574686f72697a65640000000056657374696e673a207374617274206265666f72652063757272656e742074696d657374616d7056657374696e673a20746f74616c206772616e7420616d6f756e74206578636565642062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7756657374696e673a207a65726f206163636f756e74000000000000000000000056657374696e673a20756e65787065637465642072656c65617365206d6574686f645361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a2646970667358221220f17945974f5dc2ff1e2889e2694222d04088e6a0054ebd47ad2c608135ced79e64736f6c63430007060033

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

00000000000000000000000096610186f3ab8d73ebee1cf950c750f3b1fb79c2000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : tokenAddress_ (address): 0x96610186F3ab8d73EBEe1CF950C750f3B1Fb79C2
Arg [1] : cliffDurationDays (uint256): 30
Arg [2] : percentReleaseAtScheduleStart (uint256): 0
Arg [3] : percentReleaseForEachInterval (uint256): 10000000000000000000
Arg [4] : intervalDays (uint256): 30
Arg [5] : gapDays (uint256): 0
Arg [6] : numberOfIntervals (uint256): 10
Arg [7] : releaseMethod (uint8): 1
Arg [8] : allowAccumulate_ (bool): False

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000096610186f3ab8d73ebee1cf950c750f3b1fb79c2
Arg [1] : 000000000000000000000000000000000000000000000000000000000000001e
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000008ac7230489e80000
Arg [4] : 000000000000000000000000000000000000000000000000000000000000001e
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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