ETH Price: $3,991.39 (+2.11%)

Token

CoW Protocol Virtual Token (vCOW)
 

Overview

Max Total Supply

231,829,878.387156133710652152 vCOW

Holders

696 (0.00%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
5,463.977273829120770039 vCOW

Value
$0.00
0xd50938c168cfa25d0C65e7E5B065439aDB0524D6
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

CoW Protocol matches trades via batch auctions for a variety of on-chain liquidity sources. Trades can be settled via underlying on-chain AMMs directly or via DEX Aggregators, depending on which pool/path offers the best price. It is thus essentially acting as a DexAggregator of the DexAggregators.

# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
CowProtocolVirtualToken

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
default evmVersion
File 1 of 12 : CowProtocolVirtualToken.sol
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity ^0.8.10;

import "./mixins/NonTransferrableErc20.sol";
import "./mixins/Vesting.sol";
import "./mixins/Claiming.sol";
import "./mixins/MerkleDistributor.sol";
import "./vendored/mixins/StorageAccessible.sol";

/// @dev The token that manages how the CoW Protocol governance token is
/// distributed to all different types of investors.
/// @title CoW Protocol Virtual Token
/// @author CoW Protocol Developers
contract CowProtocolVirtualToken is
    NonTransferrableErc20,
    Vesting,
    Claiming,
    MerkleDistributor,
    StorageAccessible
{
    string private constant ERC20_SYMBOL = "vCOW";
    string private constant ERC20_NAME = "CoW Protocol Virtual Token";

    constructor(
        bytes32 merkleRoot,
        address cowToken,
        address payable communityFundsTarget,
        address investorFundsTarget,
        address usdcToken,
        uint256 usdcPrice,
        address gnoToken,
        uint256 gnoPrice,
        address wrappedNativeToken,
        uint256 nativeTokenPrice,
        address teamController
    )
        NonTransferrableErc20(ERC20_NAME, ERC20_SYMBOL)
        Claiming(
            cowToken,
            communityFundsTarget,
            investorFundsTarget,
            usdcToken,
            usdcPrice,
            gnoToken,
            gnoPrice,
            wrappedNativeToken,
            nativeTokenPrice,
            teamController
        )
        MerkleDistributor(merkleRoot)
    // solhint-disable-next-line no-empty-blocks
    {

    }

    /// @dev Returns the sum of tokens that are either held as
    /// instantlySwappableBalance or will be vested in the future
    /// @param user The user for whom the balance is calculated
    /// @return Balance of the user
    function balanceOf(address user) public view returns (uint256) {
        return
            instantlySwappableBalance[user] +
            fullAllocation[user] -
            vestedAllocation[user];
    }

    /// @dev Returns the balance of a user assuming all vested tokens would
    /// have been converted into virtual tokens
    /// @param user The user for whom the balance is calculated
    /// @return Balance the user would have after calling `swapAll`
    function swappableBalanceOf(address user) public view returns (uint256) {
        return instantlySwappableBalance[user] + newlyVestedBalance(user);
    }
}

File 2 of 12 : NonTransferrableErc20.sol
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity ^0.8.10;

import "../vendored/interfaces/IERC20.sol";

/// @dev A contract of an ERC20 token that cannot be transferred.
/// @title Non-Transferrable ERC20
/// @author CoW Protocol Developers
abstract contract NonTransferrableErc20 is IERC20 {
    /// @dev The ERC20 name of the token
    string public name;
    /// @dev The ERC20 symbol of the token
    string public symbol;
    /// @dev The ERC20 number of decimals of the token
    uint8 public constant decimals = 18; // solhint-disable const-name-snakecase

    // solhint-disable-next-line no-empty-blocks
    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /// @dev This error is fired when trying to perform an action that is not
    /// supported by the contract, like transfers and approvals. These actions
    /// will never be supported.
    error NotSupported();

    /// @dev All types of transfers are permanently disabled.
    function transferFrom(
        address,
        address,
        uint256
    ) public pure returns (bool) {
        revert NotSupported();
    }

    /// @dev All types of transfers are permanently disabled.
    function transfer(address, uint256) public pure returns (bool) {
        revert NotSupported();
    }

    /// @dev All types of approvals are permanently disabled to reduce code
    /// size.
    function approve(address, uint256) public pure returns (bool) {
        revert NotSupported();
    }

    /// @dev Approvals cannot be set, so allowances are always zero.
    function allowance(address, address) public pure returns (uint256) {
        return 0;
    }
}

File 3 of 12 : Vesting.sol
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity ^0.8.10;

import "../vendored/libraries/Math.sol";

import "../interfaces/VestingInterface.sol";

/// @dev The vesting logic for distributing the COW token
/// @title Vesting Logic
/// @author CoW Protocol Developers
contract Vesting is VestingInterface {
    /// @dev The timestamp of the official vesting start. This value is shared
    /// between all participants.
    uint256 public immutable vestingStart;
    /// @dev How long it will take for all vesting to be completed. It is set to
    /// four years.
    uint256 public constant VESTING_PERIOD_IN_SECONDS = 4 * 365 days + 1 days;

    /// @dev Stores the amount of vesting that the user has already vested.
    mapping(address => uint256) public vestedAllocation;
    /// @dev Stores the maximum amount of vesting available to each user. This
    /// is exactly the total amount of vesting that can be converted after the
    /// vesting period is completed.
    mapping(address => uint256) public fullAllocation;

    /// @dev Stores a bit indicating whether a vesting is cancelable
    /// Important: This implementaiton implies that there can not be a
    /// cancelable and non-cancelable vesting in parallel
    mapping(address => bool) public isCancelable;

    /// @dev Event emitted when a new vesting position is added. The amount is
    /// the additional amount that can be vested at the end of the
    /// claiming period.
    event VestingAdded(address indexed user, uint256 amount, bool isCancelable);
    /// @dev Event emitted when a vesting position is canceled. The amount is
    /// the number of remaining vesting that will be given to the beneficiary.
    event VestingStopped(
        address indexed user,
        address freedVestingBeneficiary,
        uint256 amount
    );
    /// @dev Event emitted when the users claims (also partially) a vesting
    /// position.
    event Vested(address indexed user, uint256 amount);

    /// @dev Error returned when trying to stop a claim that is not cancelable.
    error VestingNotCancelable();

    constructor() {
        vestingStart = block.timestamp; // solhint-disable-line not-rely-on-time
    }

    /// @inheritdoc VestingInterface
    function addVesting(
        address user,
        uint256 vestingAmount,
        bool isCancelableFlag
    ) internal override {
        if (isCancelableFlag) {
            // if one cancelable vesting is made, it converts all vestings into cancelable ones
            isCancelable[user] = isCancelableFlag;
        }
        fullAllocation[user] += vestingAmount;
        emit VestingAdded(user, vestingAmount, isCancelableFlag);
    }

    /// @inheritdoc VestingInterface
    function shiftVesting(address user, address freedVestingBeneficiary)
        internal
        override
        returns (uint256 accruedVesting)
    {
        if (!isCancelable[user]) {
            revert VestingNotCancelable();
        }
        accruedVesting = vest(user);
        uint256 userFullAllocation = fullAllocation[user];
        uint256 userVestedAllocation = vestedAllocation[user];
        fullAllocation[user] = 0;
        vestedAllocation[user] = 0;
        fullAllocation[freedVestingBeneficiary] += userFullAllocation;
        vestedAllocation[freedVestingBeneficiary] += userVestedAllocation;
        emit VestingStopped(
            user,
            freedVestingBeneficiary,
            userFullAllocation - userVestedAllocation
        );
    }

    /// @inheritdoc VestingInterface
    function vest(address user)
        internal
        override
        returns (uint256 newlyVested)
    {
        newlyVested = newlyVestedBalance(user);
        vestedAllocation[user] += newlyVested;
        emit Vested(user, newlyVested);
    }

    /// @dev Assuming no conversions has been done by the user, calculates how
    /// much vesting can be converted at this point in time.
    /// @param user The user for whom the result is being calculated.
    /// @return How much vesting can be converted if no conversions had been
    /// done before.
    function cumulativeVestedBalance(address user)
        public
        view
        returns (uint256)
    {
        return
            (Math.min(
                block.timestamp - vestingStart, // solhint-disable-line not-rely-on-time
                VESTING_PERIOD_IN_SECONDS
            ) * fullAllocation[user]) / (VESTING_PERIOD_IN_SECONDS);
    }

    /// @dev Calculates how much vesting can be converted at this point in time.
    /// Unlike `cumulativeVestedBalance`, this function keeps track of previous
    /// conversions.
    /// @param user The user for whom the result is being calculated.
    /// @return How much vesting can be converted.
    function newlyVestedBalance(address user) public view returns (uint256) {
        return cumulativeVestedBalance(user) - vestedAllocation[user];
    }
}

File 4 of 12 : Claiming.sol
// SPDX-License-Identifier: LGPL-3.0-or-later

pragma solidity ^0.8.10;

import "../vendored/interfaces/IERC20.sol";
import "../vendored/libraries/SafeERC20.sol";

import "../interfaces/ClaimingInterface.sol";
import "../interfaces/VestingInterface.sol";

/// @dev The logic behind the claiming of virtual tokens and the swapping to
/// real tokens.
/// @title COW Virtual Token Claiming Logic
/// @author CoW Protocol Developers
abstract contract Claiming is ClaimingInterface, VestingInterface, IERC20 {
    using SafeERC20 for IERC20;

    /// @dev Prices are represented as fractions. For readability, the
    /// denominator is one unit of the virtual token (assuming it has 18
    /// decimals), in this way the numerator of a price is the number of atoms
    /// that have the same value as a unit of virtual token.
    uint256 internal constant PRICE_DENOMINATOR = 10**18;
    /// @dev Price numerator for the COW/USDC price. This is the number of USDC
    /// atoms required to obtain a full unit of virtual token from an option.
    uint256 public immutable usdcPrice;
    /// @dev Price numerator for the COW/GNO price. This is the number of GNO
    /// atoms required to obtain a full unit of virtual token from an option.
    uint256 public immutable gnoPrice;
    /// @dev Price numerator for the COW/native-token price. This is the number
    /// of native token wei required to obtain a full unit of virtual token from
    /// an option.
    uint256 public immutable nativeTokenPrice;

    /// @dev The proceeds from selling options to the community will be sent to,
    /// this address.
    address payable public immutable communityFundsTarget;
    /// @dev All proceeds from known investors will be sent to this address.
    address public immutable investorFundsTarget;

    /// @dev Address of the real COW token. Tokens claimed by this contract can
    /// be converted to this token if this contract stores some balance of it.
    IERC20 public immutable cowToken;
    /// @dev Address of the USDC token. It is a form of payment for investors.
    IERC20 public immutable usdcToken;
    /// @dev Address of the GNO token. It is a form of payment for users who
    /// claim the options derived from holding GNO.
    IERC20 public immutable gnoToken;
    /// @dev Address of the wrapped native token. It is a form of payment for
    /// users who claim the options derived from being users of the CoW
    /// Protocol.
    IERC20 public immutable wrappedNativeToken;

    /// @dev Address representing the CoW Protocol/CowSwap team. It is the only
    /// address that is allowed to stop the vesting of a claim, and exclusively
    /// for team claims.
    address public immutable teamController;

    /// @dev Time at which this contract was deployed.
    uint256 public immutable deploymentTimestamp;

    /// @dev Returns the amount of virtual tokens in existence, including those
    /// that have yet to be vested.
    uint256 public totalSupply;

    /// @dev How many tokens can be immediately swapped in exchange for real
    /// tokens for each user.
    mapping(address => uint256) public instantlySwappableBalance;

    /// @dev Error presented to a user trying to claim virtual tokens after the
    /// claiming period has ended.
    error ClaimingExpired();
    /// @dev Error presented to anyone but the team controller to stop a
    /// cancelable vesting position (i.e., only team vesting).
    error OnlyTeamController();
    /// @dev Error resulting from sending an incorrect amount of native to the
    /// contract.
    error InvalidNativeTokenAmount();
    /// @dev Error caused by an unsuccessful attempt to transfer native tokens.
    error FailedNativeTokenTransfer();
    /// @dev Error resulting from sending native tokens for a claim that cannot
    /// be redeemed with native tokens.
    error CannotSendNativeToken();

    constructor(
        address _cowToken,
        address payable _communityFundsTarget,
        address _investorFundsTarget,
        address _usdcToken,
        uint256 _usdcPrice,
        address _gnoToken,
        uint256 _gnoPrice,
        address _wrappedNativeToken,
        uint256 _nativeTokenPrice,
        address _teamController
    ) {
        cowToken = IERC20(_cowToken);
        communityFundsTarget = _communityFundsTarget;
        investorFundsTarget = _investorFundsTarget;
        usdcToken = IERC20(_usdcToken);
        usdcPrice = _usdcPrice;
        gnoToken = IERC20(_gnoToken);
        gnoPrice = _gnoPrice;
        wrappedNativeToken = IERC20(_wrappedNativeToken);
        nativeTokenPrice = _nativeTokenPrice;
        teamController = _teamController;

        // solhint-disable-next-line not-rely-on-time
        deploymentTimestamp = block.timestamp;
    }

    /// @dev Allows the decorated function only to be executed before the
    /// contract deployment date plus the input amount of seconds.
    /// @param durationSinceDeployment Number of seconds after contract
    /// deployment before which the function can be executed anymore. The
    /// function reverts afterwards.
    modifier before(uint256 durationSinceDeployment) {
        // solhint-disable-next-line not-rely-on-time
        if (block.timestamp > deploymentTimestamp + durationSinceDeployment) {
            revert ClaimingExpired();
        }
        _;
    }

    /// @dev The decorated function can only be executed by the team controller.
    modifier onlyTeamController() {
        if (msg.sender != teamController) {
            revert OnlyTeamController();
        }
        _;
    }

    /// @inheritdoc ClaimingInterface
    function performClaim(
        ClaimType claimType,
        address payer,
        address claimant,
        uint256 amount,
        uint256 sentNativeTokens
    ) internal override {
        if (claimType == ClaimType.Airdrop) {
            claimAirdrop(claimant, amount, sentNativeTokens);
        } else if (claimType == ClaimType.GnoOption) {
            claimGnoOption(claimant, amount, payer, sentNativeTokens);
        } else if (claimType == ClaimType.UserOption) {
            claimUserOption(claimant, amount, payer, sentNativeTokens);
        } else if (claimType == ClaimType.Investor) {
            claimInvestor(claimant, amount, payer, sentNativeTokens);
        } else if (claimType == ClaimType.Team) {
            claimTeam(claimant, amount, sentNativeTokens);
        } else {
            // claimType == ClaimType.Advisor
            claimAdvisor(claimant, amount, sentNativeTokens);
        }

        // Each claiming operation results in the creation of `amount` virtual
        // tokens.
        totalSupply += amount;
        emit Transfer(address(0), claimant, amount);
    }

    /// @dev Stops all vesting claims of a user. This is only applicable for
    /// claims that are cancellable, i.e., team claims.
    /// @param user The user whose vesting claims should be canceled.
    function stopClaim(address user) external onlyTeamController {
        uint256 accruedVesting = shiftVesting(user, teamController);
        instantlySwappableBalance[user] += accruedVesting;
    }

    /// @dev Transfers all ETH stored in the contract to the community funds
    // target.
    function withdrawEth() external {
        // We transfer ETH using .call instead of .transfer as not to restrict
        // the amount of gas sent to the target address during the transfer.
        // This is particularly relevant for sending ETH to smart contracts:
        // since EIP 2929, if a contract sends eth using `.transfer` then the
        // transaction proposed to the node needs to specify an _access list_,
        // which is currently not well supported by some wallet implementations.
        // There is no reentrancy risk as this call does not touch any storage
        // slot and the contract balance is not used in other logic.
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, ) = communityFundsTarget.call{
            value: address(this).balance
        }("");
        if (!success) {
            revert FailedNativeTokenTransfer();
        }
    }

    /// @dev Performs an airdrop-type claim for the user.
    /// @param account The user for which the claim is performed.
    /// @param amount The full amount claimed by the user.
    /// @param sentNativeTokens Amount of ETH sent along to the transaction.
    function claimAirdrop(
        address account,
        uint256 amount,
        uint256 sentNativeTokens
    ) private before(6 weeks) {
        if (sentNativeTokens != 0) {
            revert CannotSendNativeToken();
        }
        instantlySwappableBalance[account] += amount;
    }

    /// @dev Claims a Gno option for the user.
    /// @param account The user for which the claim is performed.
    /// @param amount The full amount claimed by the user after vesting.
    /// @param payer The address that pays the amount required by the claim.
    /// @param sentNativeTokens Amount of ETH sent along to the transaction.
    function claimGnoOption(
        address account,
        uint256 amount,
        address payer,
        uint256 sentNativeTokens
    ) private before(2 weeks) {
        if (sentNativeTokens != 0) {
            revert CannotSendNativeToken();
        }
        collectPayment(gnoToken, gnoPrice, payer, communityFundsTarget, amount);
        addVesting(account, amount, false);
    }

    /// @dev Claims a native-token-based option for the user.
    /// @param account The user for which the claim is performed.
    /// @param amount The full amount claimed by the user after vesting.
    /// @param payer The address that pays the amount required by the claim.
    /// @param sentNativeTokens Amount of ETH sent along to the transaction.
    function claimUserOption(
        address account,
        uint256 amount,
        address payer,
        uint256 sentNativeTokens
    ) private before(2 weeks) {
        if (sentNativeTokens != 0) {
            collectNativeTokenPayment(amount, sentNativeTokens);
        } else {
            collectPayment(
                wrappedNativeToken,
                nativeTokenPrice,
                payer,
                communityFundsTarget,
                amount
            );
        }
        addVesting(account, amount, false);
    }

    /// @dev Claims an investor option.
    /// @param account The user for which the claim is performed.
    /// @param amount The full amount claimed by the user after vesting.
    /// @param payer The address that pays the amount required by the claim.
    /// @param sentNativeTokens Amount of ETH sent along to the transaction.
    function claimInvestor(
        address account,
        uint256 amount,
        address payer,
        uint256 sentNativeTokens
    ) private before(2 weeks) {
        if (sentNativeTokens != 0) {
            revert CannotSendNativeToken();
        }
        collectPayment(
            usdcToken,
            usdcPrice,
            payer,
            investorFundsTarget,
            amount
        );
        addVesting(account, amount, false);
    }

    /// @dev Claims a team option. Team options are granted without any payment
    /// but can be canceled.
    /// @param account The user for which the claim is performed.
    /// @param amount The full amount claimed by the user after vesting.
    /// @param sentNativeTokens Amount of ETH sent along to the transaction.
    function claimTeam(
        address account,
        uint256 amount,
        uint256 sentNativeTokens
    ) private before(6 weeks) {
        if (sentNativeTokens != 0) {
            revert CannotSendNativeToken();
        }
        addVesting(account, amount, true);
    }

    /// @dev Claims an adviser option. Team options are granted without any
    /// payment and cannot be canceled.
    /// @param account The user for which the claim is performed.
    /// @param amount The full amount claimed by the user after vesting.
    /// @param sentNativeTokens Amount of ETH sent along to the transaction.
    function claimAdvisor(
        address account,
        uint256 amount,
        uint256 sentNativeTokens
    ) private before(6 weeks) {
        if (sentNativeTokens != 0) {
            revert CannotSendNativeToken();
        }
        addVesting(account, amount, false);
    }

    /// @dev Executes a transfer from the user to the target. The transfered
    /// amount is based on the input COW price and amount of COW bought.
    /// @param token The token used for the payment.
    /// @param price The number of atoms of the input token that are equivalent
    /// to one atom of COW multiplied by PRICE_DENOMINATOR.
    /// @param from The address from which to take the funds.
    /// @param to The address to which to send the funds.
    /// @param amount The amount of COW atoms that will be paid for.
    function collectPayment(
        IERC20 token,
        uint256 price,
        address from,
        address to,
        uint256 amount
    ) private {
        uint256 tokenEquivalent = convertCowAmountAtPrice(amount, price);
        token.safeTransferFrom(from, to, tokenEquivalent);
    }

    /// @dev Transfers native tokens from this contract to the target, assuming
    /// that the amount of native tokens sent coincides with the expected amount
    /// of native tokens. This amount is based on the price of the native token
    /// and amount of COW bought.
    /// @param amount The amount of COW atoms that will be paid for.
    /// @param sentNativeTokens Amount of ETH sent along to the transaction.
    function collectNativeTokenPayment(uint256 amount, uint256 sentNativeTokens)
        private
        view
    {
        uint256 nativeTokenEquivalent = convertCowAmountAtPrice(
            amount,
            nativeTokenPrice
        );
        if (sentNativeTokens != nativeTokenEquivalent) {
            revert InvalidNativeTokenAmount();
        }
    }

    /// @dev Converts input amount in COW token atoms to an amount in token
    /// atoms at the specified price.
    /// @param amount Amount of tokens to convert.
    /// @param price The number of atoms of the input token that are equivalent
    /// to one atom of COW *multiplied by PRICE_DENOMINATOR*.
    function convertCowAmountAtPrice(uint256 amount, uint256 price)
        private
        pure
        returns (uint256)
    {
        return (amount * price) / PRICE_DENOMINATOR;
    }

    /// @dev Converts an amount of (virtual) tokens from this contract to real
    /// tokens based on the claims previously performed by the caller.
    /// @param amount How many virtual tokens to convert into real tokens.
    function swap(uint256 amount) external {
        makeVestingSwappable();
        _swap(amount);
    }

    /// @dev Converts all available (virtual) tokens from this contract to real
    /// tokens based on the claims previously performed by the caller.
    /// @return swappedBalance The full amount that was swapped (i.e., virtual
    /// tokens burnt as well as real tokens received).
    function swapAll() external returns (uint256 swappedBalance) {
        swappedBalance = makeVestingSwappable();
        _swap(swappedBalance);
    }

    /// @dev Transfers real tokens to the message sender and reduces the balance
    /// of virtual tokens available. Note that this function assumes that the
    /// current contract stores enough real tokens to fulfill this swap request.
    /// @param amount How many virtual tokens to convert into real tokens.
    function _swap(uint256 amount) private {
        instantlySwappableBalance[msg.sender] -= amount;
        totalSupply -= amount;
        cowToken.safeTransfer(msg.sender, amount);
        emit Transfer(msg.sender, address(0), amount);
    }

    /// @dev Adds the currently vested amount to the immediately swappable
    /// balance.
    /// @return swappableBalance The maximum balance that can be swapped at
    /// this point in time by the caller.
    function makeVestingSwappable() private returns (uint256 swappableBalance) {
        swappableBalance =
            instantlySwappableBalance[msg.sender] +
            vest(msg.sender);
        instantlySwappableBalance[msg.sender] = swappableBalance;
    }
}

File 5 of 12 : MerkleDistributor.sol
// SPDX-License-Identifier: LGPL-3.0-or-later

// This contract is based on Uniswap's MekleDistributor, which can be found at:
// https://github.com/Uniswap/merkle-distributor/blob/0d478d722da2e5d95b7292fd8cbdb363d98e9a93/contracts/MerkleDistributor.sol
//
// The changes between the original contract and this are:
//  - the claim function doesn't trigger a transfer on a successful proof, but
//    it executes a dedicated (virtual) function.
//  - added a claimMany function for bundling multiple claims in a transaction
//  - supported sending an amount of native tokens along with the claim
//  - added the option of claiming less than the maximum amount
//  - gas optimizations in the packing and unpacking of the claimed bit
//  - bumped Solidity version
//  - code formatting

pragma solidity ^0.8.10;

import "../vendored/interfaces/IERC20.sol";
import "../vendored/libraries/MerkleProof.sol";

import "../interfaces/ClaimingInterface.sol";

abstract contract MerkleDistributor is ClaimingInterface {
    bytes32 public immutable merkleRoot;

    /// @dev Event fired if a claim was successfully performed.
    event Claimed(
        uint256 index,
        ClaimType claimType,
        address claimant,
        uint256 claimableAmount,
        uint256 claimedAmount
    );

    /// @dev Error caused by a user trying to call the claim function for a
    /// claim that has already been used before.
    error AlreadyClaimed();
    /// @dev Error caused by a user trying to claim a larger amount than the
    /// maximum allowed in the claim.
    error ClaimingMoreThanMaximum();
    /// @dev Error caused by the caller trying to perform a partial claim while
    /// not being the owner of the claim.
    error OnlyOwnerCanClaimPartially();
    /// @dev Error caused by calling the claim function with an invalid proof.
    error InvalidProof();
    /// @dev Error caused by calling claimMany with a transaction value that is
    /// different from the required one.
    error InvalidNativeTokenValue();

    /// @dev Packed array of booleans that stores if a claim is available.
    mapping(uint256 => uint256) private claimedBitMap;

    constructor(bytes32 merkleRoot_) {
        merkleRoot = merkleRoot_;
    }

    /// @dev Checks if the claim at the provided index has already been claimed.
    /// @param index The index to check.
    /// @return Whether the claim at the given index has already been claimed.
    function isClaimed(uint256 index) public view returns (bool) {
        uint256 claimedWordIndex = index >> 8;
        uint256 claimedBitIndex = index & 0xff;
        uint256 claimedWord = claimedBitMap[claimedWordIndex];
        uint256 mask = (1 << claimedBitIndex);
        return claimedWord & mask != 0;
    }

    /// @dev Mark the provided index as having been claimed.
    /// @param index The index that was claimed.
    function _setClaimed(uint256 index) private {
        uint256 claimedWordIndex = index >> 8;
        uint256 claimedBitIndex = index & 0xff;
        claimedBitMap[claimedWordIndex] =
            claimedBitMap[claimedWordIndex] |
            (1 << claimedBitIndex);
    }

    /// @dev This function verifies the provided input proof based on the
    /// provided input. If the proof is valid, the function [`performClaim`] is
    /// called for the claimed amount.
    /// @param index The index that identifies the input claim.
    /// @param claimType See [`performClaim`].
    /// @param claimant See [`performClaim`].
    /// @param claimableAmount The maximum amount that the claimant can claim
    /// for this claim. Should not be smaller than claimedAmount.
    /// @param claimedAmount See [`performClaim`].
    /// @param merkleProof A proof that the input claim belongs to the unique
    /// Merkle root associated to this contract.
    function claim(
        uint256 index,
        ClaimType claimType,
        address claimant,
        uint256 claimableAmount,
        uint256 claimedAmount,
        bytes32[] calldata merkleProof
    ) external payable {
        _claim(
            index,
            claimType,
            claimant,
            claimableAmount,
            claimedAmount,
            merkleProof,
            msg.value
        );
    }

    /// @dev This function verifies and executes multiple claims in the same
    /// transaction.
    /// @param indices A vector of indices. See [`claim`] for details.
    /// @param claimTypes A vector of claim types. See [`performClaim`] for
    /// details.
    /// @param claimants A vector of claimants. See [`performClaim`] for
    /// details.
    /// @param claimableAmounts A vector of claimable amounts. See [`claim`] for
    /// details.
    /// @param claimedAmounts A vector of claimed amounts. See [`performClaim`]
    /// for details.
    /// @param merkleProofs A vector of merkle proofs. See [`claim`] for
    /// details.
    /// @param sentNativeTokens A vector of native token amounts. See
    /// [`performClaim`] for details.
    function claimMany(
        uint256[] memory indices,
        ClaimType[] memory claimTypes,
        address[] calldata claimants,
        uint256[] calldata claimableAmounts,
        uint256[] calldata claimedAmounts,
        bytes32[][] calldata merkleProofs,
        uint256[] calldata sentNativeTokens
    ) external payable {
        uint256 sumSentNativeTokens;
        for (uint256 i = 0; i < indices.length; i++) {
            sumSentNativeTokens += sentNativeTokens[i];
            _claim(
                indices[i],
                claimTypes[i],
                claimants[i],
                claimableAmounts[i],
                claimedAmounts[i],
                merkleProofs[i],
                sentNativeTokens[i]
            );
        }
        if (sumSentNativeTokens != msg.value) {
            revert InvalidNativeTokenValue();
        }
    }

    /// @dev This function verifies the provided input proof based on the
    /// provided input. If the proof is valid, the function [`performClaim`] is
    /// called for the claimed amount.
    /// @param index See [`claim`].
    /// @param claimType See [`performClaim`].
    /// @param claimant See [`performClaim`].
    /// @param claimableAmount See [`claim`].
    /// @param claimedAmount See [`performClaim`].
    /// @param merkleProof See [`claim`].
    /// @param sentNativeTokens See [`performClaim`].
    function _claim(
        uint256 index,
        ClaimType claimType,
        address claimant,
        uint256 claimableAmount,
        uint256 claimedAmount,
        bytes32[] calldata merkleProof,
        uint256 sentNativeTokens
    ) private {
        if (isClaimed(index)) {
            revert AlreadyClaimed();
        }
        if (claimedAmount > claimableAmount) {
            revert ClaimingMoreThanMaximum();
        }
        if ((claimedAmount < claimableAmount) && (msg.sender != claimant)) {
            revert OnlyOwnerCanClaimPartially();
        }

        // Note: all types used inside `encodePacked` should have fixed length,
        // otherwise the same proof could be used in different claims.
        bytes32 node = keccak256(
            abi.encodePacked(index, claimType, claimant, claimableAmount)
        );
        if (!MerkleProof.verify(merkleProof, merkleRoot, node)) {
            revert InvalidProof();
        }

        _setClaimed(index);

        performClaim(
            claimType,
            msg.sender,
            claimant,
            claimedAmount,
            sentNativeTokens
        );

        emit Claimed(
            index,
            claimType,
            claimant,
            claimableAmount,
            claimedAmount
        );
    }
}

File 6 of 12 : StorageAccessible.sol
// SPDX-License-Identifier: LGPL-3.0-only

// Vendored from Gnosis utility contracts, see:
// <https://raw.githubusercontent.com/gnosis/gp-v2-contracts/40c349d52d14f8f3c9f787fe2fca5a496bb10ea9/src/contracts/mixins/StorageAccessible.sol>
// The following changes were made:
// - Modified Solidity version
// - Formatted code

pragma solidity ^0.8.10;

/// @title ViewStorageAccessible - Interface on top of StorageAccessible base class to allow simulations from view functions
interface ViewStorageAccessible {
    /**
     * @dev Same as `simulateDelegatecall` on StorageAccessible. Marked as view so that it can be called from external contracts
     * that want to run simulations from within view functions. Will revert if the invoked simulation attempts to change state.
     */
    function simulateDelegatecall(
        address targetContract,
        bytes memory calldataPayload
    ) external view returns (bytes memory);

    /**
     * @dev Same as `getStorageAt` on StorageAccessible. This method allows reading aribtrary ranges of storage.
     */
    function getStorageAt(uint256 offset, uint256 length)
        external
        view
        returns (bytes memory);
}

/// @title StorageAccessible - generic base contract that allows callers to access all internal storage.
contract StorageAccessible {
    /**
     * @dev Reads `length` bytes of storage in the currents contract
     * @param offset - the offset in the current contract's storage in words to start reading from
     * @param length - the number of words (32 bytes) of data to read
     * @return the bytes that were read.
     */
    function getStorageAt(uint256 offset, uint256 length)
        external
        view
        returns (bytes memory)
    {
        bytes memory result = new bytes(length * 32);
        for (uint256 index = 0; index < length; index++) {
            // solhint-disable-next-line no-inline-assembly
            assembly {
                let word := sload(add(offset, index))
                mstore(add(add(result, 0x20), mul(index, 0x20)), word)
            }
        }
        return result;
    }

    /**
     * @dev Performs a delegetecall on a targetContract in the context of self.
     * Internally reverts execution to avoid side effects (making it static). Catches revert and returns encoded result as bytes.
     * @param targetContract Address of the contract containing the code to execute.
     * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).
     */
    function simulateDelegatecall(
        address targetContract,
        bytes memory calldataPayload
    ) public returns (bytes memory response) {
        bytes memory innerCall = abi.encodeWithSelector(
            this.simulateDelegatecallInternal.selector,
            targetContract,
            calldataPayload
        );
        // solhint-disable-next-line avoid-low-level-calls
        (, response) = address(this).call(innerCall);
        bool innerSuccess = response[response.length - 1] == 0x01;
        setLength(response, response.length - 1);
        if (innerSuccess) {
            return response;
        } else {
            revertWith(response);
        }
    }

    /**
     * @dev Performs a delegetecall on a targetContract in the context of self.
     * Internally reverts execution to avoid side effects (making it static). Returns encoded result as revert message
     * concatenated with the success flag of the inner call as a last byte.
     * @param targetContract Address of the contract containing the code to execute.
     * @param calldataPayload Calldata that should be sent to the target contract (encoded method name and arguments).
     */
    function simulateDelegatecallInternal(
        address targetContract,
        bytes memory calldataPayload
    ) external returns (bytes memory response) {
        bool success;
        // solhint-disable-next-line avoid-low-level-calls
        (success, response) = targetContract.delegatecall(calldataPayload);
        revertWith(abi.encodePacked(response, success));
    }

    function revertWith(bytes memory response) internal pure {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            revert(add(response, 0x20), mload(response))
        }
    }

    function setLength(bytes memory buffer, uint256 length) internal pure {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            mstore(buffer, length)
        }
    }
}

File 7 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT

// Vendored from OpenZeppelin Contracts v4.4.0, see:
// <https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.4.0/contracts/token/ERC20/IERC20.sol>

// OpenZeppelin Contracts v4.4.0 (token/ERC20/IERC20.sol)

pragma solidity ^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 8 of 12 : Math.sol
// SPDX-License-Identifier: MIT

// Vendored from OpenZeppelin Contracts v4.4.0, see:
// <https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.4.0/contracts/utils/math/Math.sol>

// OpenZeppelin Contracts v4.4.0 (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a / b + (a % b == 0 ? 0 : 1);
    }
}

File 9 of 12 : VestingInterface.sol
// SPDX-License-Identifier: LGPL-3.0-or-later

pragma solidity ^0.8.10;

/// @dev The contract functions that are shared between the `Vesting` and
/// `Claiming` contracts. The two components are handled and tested
/// separately and are linked to each other by the functions in this contract.
/// This contracs is for all intents and purposes an interface, however actual
/// interfaces cannot declare internal functions.
/// @title COW token vesting interface.
/// @author CoW Protocol Developers
abstract contract VestingInterface {
    /// @dev Adds an amount that will be vested over time.
    /// Should be called from the parent contract on redeeming a vested claim.
    /// @param user The user for whom the vesting is performed.
    /// @param vestingAmount The (added) amount to be vested in time.
    /// @param isCancelableFlag Flag whether the vesting is cancelable
    function addVesting(
        address user,
        uint256 vestingAmount,
        bool isCancelableFlag
    ) internal virtual;

    /// @dev Computes the current vesting from the total vested amount and marks
    /// that amount as converted. This is called by the parent contract every
    /// time virtual tokens from a vested claim are swapped into real tokens.
    /// @param user The user for which the amount is vested.
    /// @return Amount converted.
    function vest(address user) internal virtual returns (uint256);

    /// @dev Transfers a cancelable vesting of a user to another address.
    /// Returns the amount of token that is not yet converted.
    /// @param user The user for whom the vesting is removed.
    /// @param freedVestingBeneficiary The address to which to assign the amount
    /// that remains to be vested.
    /// @return accruedVesting The total number of tokens that remain to be
    /// converted
    function shiftVesting(address user, address freedVestingBeneficiary)
        internal
        virtual
        returns (uint256 accruedVesting);
}

File 10 of 12 : SafeERC20.sol
// SPDX-License-Identifier: LGPL-3.0-or-later

// Vendored from GPv2 contracts v1.1.2, see:
// <https://raw.githubusercontent.com/gnosis/gp-v2-contracts/7fb88982021e9a274d631ffb598694e6d9b30089/src/contracts/libraries/GPv2SafeERC20.sol>
// The following changes were made:
// - Bumped up Solidity version and checked that the assembly is still valid.
// - Use own vendored IERC20 instead of custom implementation.
// - Removed "GPv2" from contract name.
// - Modified revert messages, including length.

pragma solidity ^0.8.10;

import "../interfaces/IERC20.sol";

/// @title Gnosis Protocol v2 Safe ERC20 Transfer Library
/// @author Gnosis Developers
/// @dev Gas-efficient version of Openzeppelin's SafeERC20 contract.
library SafeERC20 {
    /// @dev Wrapper around a call to the ERC20 function `transfer` that reverts
    /// also when the token returns `false`.
    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        bytes4 selector_ = token.transfer.selector;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            let freeMemoryPointer := mload(0x40)
            mstore(freeMemoryPointer, selector_)
            mstore(
                add(freeMemoryPointer, 4),
                and(to, 0xffffffffffffffffffffffffffffffffffffffff)
            )
            mstore(add(freeMemoryPointer, 36), value)

            if iszero(call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)) {
                returndatacopy(0, 0, returndatasize())
                revert(0, returndatasize())
            }
        }

        require(getLastTransferResult(token), "SafeERC20: failed transfer");
    }

    /// @dev Wrapper around a call to the ERC20 function `transferFrom` that
    /// reverts also when the token returns `false`.
    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        bytes4 selector_ = token.transferFrom.selector;

        // solhint-disable-next-line no-inline-assembly
        assembly {
            let freeMemoryPointer := mload(0x40)
            mstore(freeMemoryPointer, selector_)
            mstore(
                add(freeMemoryPointer, 4),
                and(from, 0xffffffffffffffffffffffffffffffffffffffff)
            )
            mstore(
                add(freeMemoryPointer, 36),
                and(to, 0xffffffffffffffffffffffffffffffffffffffff)
            )
            mstore(add(freeMemoryPointer, 68), value)

            if iszero(call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)) {
                returndatacopy(0, 0, returndatasize())
                revert(0, returndatasize())
            }
        }

        require(getLastTransferResult(token), "SafeERC20: failed transferFrom");
    }

    /// @dev Verifies that the last return was a successful `transfer*` call.
    /// This is done by checking that the return data is either empty, or
    /// is a valid ABI encoded boolean.
    function getLastTransferResult(IERC20 token)
        private
        view
        returns (bool success)
    {
        // NOTE: Inspecting previous return data requires assembly. Note that
        // we write the return data to memory 0 in the case where the return
        // data size is 32, this is OK since the first 64 bytes of memory are
        // reserved by Solidy as a scratch space that can be used within
        // assembly blocks.
        // <https://docs.soliditylang.org/en/v0.8.10/internals/layout_in_memory.html>
        // solhint-disable-next-line no-inline-assembly
        assembly {
            /// @dev Revert with an ABI encoded Solidity error with a message
            /// that fits into 32-bytes.
            ///
            /// An ABI encoded Solidity error has the following memory layout:
            ///
            /// ------------+----------------------------------
            ///  byte range | value
            /// ------------+----------------------------------
            ///  0x00..0x04 |        selector("Error(string)")
            ///  0x04..0x24 |      string offset (always 0x20)
            ///  0x24..0x44 |                    string length
            ///  0x44..0x64 | string value, padded to 32-bytes
            function revertWithMessage(length, message) {
                mstore(0x00, "\x08\xc3\x79\xa0")
                mstore(0x04, 0x20)
                mstore(0x24, length)
                mstore(0x44, message)
                revert(0x00, 0x64)
            }

            switch returndatasize()
            // Non-standard ERC20 transfer without return.
            case 0 {
                // NOTE: When the return data size is 0, verify that there
                // is code at the address. This is done in order to maintain
                // compatibility with Solidity calling conventions.
                // <https://docs.soliditylang.org/en/v0.8.10/control-structures.html#external-function-calls>
                if iszero(extcodesize(token)) {
                    revertWithMessage(25, "SafeERC20: not a contract")
                }

                success := 1
            }
            // Standard ERC20 transfer returning boolean success value.
            case 32 {
                returndatacopy(0, 0, returndatasize())

                // NOTE: For ABI encoding v1, any non-zero value is accepted
                // as `true` for a boolean. In order to stay compatible with
                // OpenZeppelin's `SafeERC20` library which is known to work
                // with the existing ERC20 implementation we care about,
                // make sure we return success for any non-zero return value
                // from the `transfer*` call.
                success := iszero(iszero(mload(0)))
            }
            default {
                revertWithMessage(30, "SafeERC20: bad transfer result")
            }
        }
    }
}

File 11 of 12 : ClaimingInterface.sol
// SPDX-License-Identifier: LGPL-3.0-or-later

pragma solidity ^0.8.10;

/// @dev The contract functions that are shared between the `Claiming` and
/// `MerkleDistributor` contracts. The two components are handled and tested
/// separately and are linked to each other by the functions in this contract.
/// This contracs is for all intents and purposes an interface, however actual
/// interfaces cannot declare internal functions.
/// @title COW token claiming interface.
/// @author CoW Protocol Developers
abstract contract ClaimingInterface {
    /// @dev Exhaustive list of the different branches of the claiming logic.
    enum ClaimType {
        Airdrop,
        GnoOption,
        UserOption,
        Investor,
        Team,
        Advisor
    }

    /// @dev This function is executed when a valid proof of the claim is
    /// provided and executes all steps required for each claim type.
    /// @param claimType Which claim will be performed. See [`ClaimType`] for
    /// an exausting list.
    /// @param payer The address that will pay if the claim to be performed
    /// requires a payment.
    /// @param claimant The account to which the claim is assigned and which
    /// will receive the corresponding virtual tokens.
    /// @param claimedAmount The amount that the user decided to claim (after
    /// vesting if it applies).
    /// @param sentNativeTokens The amount of native tokens that the user sent
    /// along with the transaction.
    function performClaim(
        ClaimType claimType,
        address payer,
        address claimant,
        uint256 claimedAmount,
        uint256 sentNativeTokens
    ) internal virtual;
}

File 12 of 12 : MerkleProof.sol
// SPDX-License-Identifier: MIT

// Vendored from OpenZeppelin Contracts v4.4.0, see:
// <https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/v4.4.0/contracts/utils/cryptography/MerkleProof.sol>

// OpenZeppelin Contracts v4.4.0 (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf)
        internal
        pure
        returns (bytes32)
    {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(
                    abi.encodePacked(computedHash, proofElement)
                );
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(
                    abi.encodePacked(proofElement, computedHash)
                );
            }
        }
        return computedHash;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"address","name":"cowToken","type":"address"},{"internalType":"address payable","name":"communityFundsTarget","type":"address"},{"internalType":"address","name":"investorFundsTarget","type":"address"},{"internalType":"address","name":"usdcToken","type":"address"},{"internalType":"uint256","name":"usdcPrice","type":"uint256"},{"internalType":"address","name":"gnoToken","type":"address"},{"internalType":"uint256","name":"gnoPrice","type":"uint256"},{"internalType":"address","name":"wrappedNativeToken","type":"address"},{"internalType":"uint256","name":"nativeTokenPrice","type":"uint256"},{"internalType":"address","name":"teamController","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"CannotSendNativeToken","type":"error"},{"inputs":[],"name":"ClaimingExpired","type":"error"},{"inputs":[],"name":"ClaimingMoreThanMaximum","type":"error"},{"inputs":[],"name":"FailedNativeTokenTransfer","type":"error"},{"inputs":[],"name":"InvalidNativeTokenAmount","type":"error"},{"inputs":[],"name":"InvalidNativeTokenValue","type":"error"},{"inputs":[],"name":"InvalidProof","type":"error"},{"inputs":[],"name":"NotSupported","type":"error"},{"inputs":[],"name":"OnlyOwnerCanClaimPartially","type":"error"},{"inputs":[],"name":"OnlyTeamController","type":"error"},{"inputs":[],"name":"VestingNotCancelable","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"enum ClaimingInterface.ClaimType","name":"claimType","type":"uint8"},{"indexed":false,"internalType":"address","name":"claimant","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimableAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"claimedAmount","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Vested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isCancelable","type":"bool"}],"name":"VestingAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"freedVestingBeneficiary","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"VestingStopped","type":"event"},{"inputs":[],"name":"VESTING_PERIOD_IN_SECONDS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"enum ClaimingInterface.ClaimType","name":"claimType","type":"uint8"},{"internalType":"address","name":"claimant","type":"address"},{"internalType":"uint256","name":"claimableAmount","type":"uint256"},{"internalType":"uint256","name":"claimedAmount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"indices","type":"uint256[]"},{"internalType":"enum ClaimingInterface.ClaimType[]","name":"claimTypes","type":"uint8[]"},{"internalType":"address[]","name":"claimants","type":"address[]"},{"internalType":"uint256[]","name":"claimableAmounts","type":"uint256[]"},{"internalType":"uint256[]","name":"claimedAmounts","type":"uint256[]"},{"internalType":"bytes32[][]","name":"merkleProofs","type":"bytes32[][]"},{"internalType":"uint256[]","name":"sentNativeTokens","type":"uint256[]"}],"name":"claimMany","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"communityFundsTarget","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cowToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"cumulativeVestedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"fullAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"getStorageAt","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gnoPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gnoToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"instantlySwappableBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"investorFundsTarget","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isCancelable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeTokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"newlyVestedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"calldataPayload","type":"bytes"}],"name":"simulateDelegatecall","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"calldataPayload","type":"bytes"}],"name":"simulateDelegatecallInternal","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"stopClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapAll","outputs":[{"internalType":"uint256","name":"swappedBalance","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"swappableBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"usdcPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"usdcToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vestedAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vestingStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrappedNativeToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6102206040523480156200001257600080fd5b5060405162002fc538038062002fc58339810160408190526200003591620001e7565b8a8a8a8a8a8a8a8a8a8a8a6040518060400160405280601a81526020017f436f572050726f746f636f6c205669727475616c20546f6b656e0000000000008152506040518060400160405280600481526020016376434f5760e01b8152508160009080519060200190620000ab92919062000128565b508051620000c190600190602084019062000128565b50504260808190526001600160a01b039b8c1661014052998b166101005250968916610120529488166101605260a0939093529086166101805260c05284166101a05260e0529091166101c0526101e0526102005250620002f99950505050505050505050565b8280546200013690620002bc565b90600052602060002090601f0160209004810192826200015a5760008555620001a5565b82601f106200017557805160ff1916838001178555620001a5565b82800160010185558215620001a5579182015b82811115620001a557825182559160200191906001019062000188565b50620001b3929150620001b7565b5090565b5b80821115620001b35760008155600101620001b8565b6001600160a01b0381168114620001e457600080fd5b50565b60008060008060008060008060008060006101608c8e0312156200020a57600080fd5b8b519a5060208c01516200021e81620001ce565b60408d0151909a506200023181620001ce565b60608d01519099506200024481620001ce565b60808d01519098506200025781620001ce565b60a08d015160c08e015191985096506200027181620001ce565b60e08d01516101008e015191965094506200028c81620001ce565b6101208d01516101408e01519194509250620002a881620001ce565b809150509295989b509295989b9093969950565b600181811c90821680620002d157607f821691505b60208210811415620002f357634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051612b9562000430600039600081816104ae015261133c0152600081816107bf015281816119e901528181611ac801528181611be701528181611cd001528181611ddc0152611e8701526000818161047a01528181610d480152610da70152600081816103e10152611c5e0152600081816107f30152611b620152600081816103880152611d6a0152600081816105d201526111830152600081816106f20152611dad01526000818161087e01528181610c0301528181611ba50152611ca101526000818161050901528181611c7f015261204f0152600081816107730152611b830152600081816108270152611d8b0152600081816104460152610ced0152612b956000f3fe6080604052600436106102bb5760003560e01c80639519f8281161016e578063bcfffb68116100cb578063dd62ed3e1161007f578063f3507dab11610064578063f3507dab146108a0578063f84436bd146108b3578063ffd93cd5146108d357600080fd5b8063dd62ed3e14610849578063e4a0ddf71461086c57600080fd5b8063bfc12c05116100b0578063bfc12c05146107ad578063c61f2184146107e1578063dacee3471461081557600080fd5b8063bcfffb6814610761578063be1ae6f91461079557600080fd5b8063a9059cbb11610122578063b1d882eb11610107578063b1d882eb146106e0578063b79b371314610714578063b7d1d98e1461074157600080fd5b8063a9059cbb146102eb578063acaf21f7146106c057600080fd5b80639e34070f116101535780639e34070f1461063e578063a0ef91df1461067e578063a2a626f81461069357600080fd5b80639519f8281461061657806395d89b411461062957600080fd5b80632eb4a7ab1161021c5780635624b25b116101d057806370a08231116101b557806370a08231146105a05780638cd8e8d2146105c057806394b918de146105f457600080fd5b80635624b25b14610560578063687000281461058057600080fd5b8063332572c411610201578063332572c4146104f75780633e9ffbea1461052b57806343218e191461054057600080fd5b80632eb4a7ab1461049c578063313ce567146104d057600080fd5b806317fcb39b1161027357806323b872dd1161025857806323b872dd14610419578063254800d41461043457806326f3acae1461046857600080fd5b806317fcb39b146103cf57806318160ddd1461040357600080fd5b80630ca9279c116102a45780630ca9279c1461031b5780631051e84f1461034957806311eac8551461037657600080fd5b806306fdde03146102c0578063095ea7b3146102eb575b600080fd5b3480156102cc57600080fd5b506102d5610903565b6040516102e29190612223565b60405180910390f35b3480156102f757600080fd5b5061030b61030636600461225f565b610991565b60405190151581526020016102e2565b34801561032757600080fd5b5061033b610336366004612289565b6109c5565b6040519081526020016102e2565b34801561035557600080fd5b5061033b610364366004612289565b60036020526000908152604090205481565b34801561038257600080fd5b506103aa7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102e2565b3480156103db57600080fd5b506103aa7f000000000000000000000000000000000000000000000000000000000000000081565b34801561040f57600080fd5b5061033b60055481565b34801561042557600080fd5b5061030b6103063660046122a4565b34801561044057600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561047457600080fd5b506103aa7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104a857600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104dc57600080fd5b506104e5601281565b60405160ff90911681526020016102e2565b34801561050357600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561053757600080fd5b5061033b610a06565b34801561054c57600080fd5b506102d561055b36600461235e565b610a1e565b34801561056c57600080fd5b506102d561057b366004612422565b610ac0565b34801561058c57600080fd5b5061033b61059b366004612289565b610b46565b3480156105ac57600080fd5b5061033b6105bb366004612289565b610b7f565b3480156105cc57600080fd5b506103aa7f000000000000000000000000000000000000000000000000000000000000000081565b34801561060057600080fd5b5061061461060f366004612444565b610bc4565b005b6106146106243660046124b8565b610bd9565b34801561063557600080fd5b506102d5610bf2565b34801561064a57600080fd5b5061030b610659366004612444565b600881901c600090815260076020526040902054600160ff9092169190911b16151590565b34801561068a57600080fd5b50610614610bff565b34801561069f57600080fd5b5061033b6106ae366004612289565b60026020526000908152604090205481565b3480156106cc57600080fd5b5061033b6106db366004612289565b610cb9565b3480156106ec57600080fd5b506103aa7f000000000000000000000000000000000000000000000000000000000000000081565b34801561072057600080fd5b5061033b61072f366004612289565b60066020526000908152604090205481565b34801561074d57600080fd5b5061061461075c366004612289565b610d30565b34801561076d57600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156107a157600080fd5b5061033b6307861f8081565b3480156107b957600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156107ed57600080fd5b506103aa7f000000000000000000000000000000000000000000000000000000000000000081565b34801561082157600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000000000000081565b34801561085557600080fd5b5061033b61086436600461253a565b600092915050565b34801561087857600080fd5b506103aa7f000000000000000000000000000000000000000000000000000000000000000081565b6106146108ae36600461265e565b610e0e565b3480156108bf57600080fd5b506102d56108ce36600461235e565b610f6e565b3480156108df57600080fd5b5061030b6108ee366004612289565b60046020526000908152604090205460ff1681565b60008054610910906127c9565b80601f016020809104026020016040519081016040528092919081815260200182805461093c906127c9565b80156109895780601f1061095e57610100808354040283529160200191610989565b820191906000526020600020905b81548152906001019060200180831161096c57829003601f168201915b505050505081565b60006040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109d082610b46565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260066020526040902054610a009190612846565b92915050565b6000610a106110ef565b9050610a1b8161112b565b90565b606060008373ffffffffffffffffffffffffffffffffffffffff1683604051610a47919061285e565b600060405180830381855af49150503d8060008114610a82576040519150601f19603f3d011682016040523d82523d6000602084013e610a87565b606091505b50604051909350909150610ab990610aa5908490849060200161287a565b6040516020818303038152906040526111e5565b5092915050565b60606000610acf8360206128a2565b67ffffffffffffffff811115610ae757610ae76122e0565b6040519080825280601f01601f191660200182016040528015610b11576020820181803683370190505b50905060005b83811015610b3e578481015460208083028401015280610b36816128df565b915050610b17565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812054610b7583610cb9565b610a009190612918565b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602090815260408083205460038352818420546006909352908320549091610b7591612846565b610bcc6110ef565b50610bd68161112b565b50565b610be987878787878787346111ed565b50505050505050565b60018054610910906127c9565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff164760405160006040518083038185875af1925050503d8060008114610c79576040519150601f19603f3d011682016040523d82523d6000602084013e610c7e565b606091505b5050905080610bd6576040517f68a36fef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260408120546307861f8090610d1c610d127f000000000000000000000000000000000000000000000000000000000000000042612918565b6307861f80611413565b610d2691906128a2565b610a00919061292f565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610d9f576040517f1f78defd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610dcb827f000000000000000000000000000000000000000000000000000000000000000061142b565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260066020526040812080549293508392909190610e05908490612846565b90915550505050565b6000805b8d51811015610f2557838382818110610e2d57610e2d61296a565b9050602002013582610e3f9190612846565b9150610f138e8281518110610e5657610e5661296a565b60200260200101518e8381518110610e7057610e7061296a565b60200260200101518e8e85818110610e8a57610e8a61296a565b9050602002016020810190610e9f9190612289565b8d8d86818110610eb157610eb161296a565b905060200201358c8c87818110610eca57610eca61296a565b905060200201358b8b88818110610ee357610ee361296a565b9050602002810190610ef59190612999565b8b8b8a818110610f0757610f0761296a565b905060200201356111ed565b80610f1d816128df565b915050610e12565b50348114610f5f576040517f46459bbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050505050565b606060006343218e1960e01b8484604051602401610f8d929190612a01565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051909150309061101c90839061285e565b6000604051808303816000865af19150503d8060008114611059576040519150601f19603f3d011682016040523d82523d6000602084013e61105e565b606091505b50905080925050600082600184516110769190612918565b815181106110865761108661296a565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916600160f81b1490506110d183600185516110cd9190612918565b9052565b80156110de575050610a00565b6110e7836111e5565b505092915050565b60006110fa336115aa565b336000908152600660205260409020546111149190612846565b336000908152600660205260409020819055919050565b336000908152600660205260408120805483929061114a908490612918565b9250508190555080600560008282546111639190612918565b909155506111aa905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611643565b60405181815260009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350565b805160208201fd5b600888901c600090815260076020526040902054600160ff8a161b1615611240576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8484111561127a576040517f28de1fc900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b848410801561129f57503373ffffffffffffffffffffffffffffffffffffffff871614155b156112d6576040517fb052d0e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000888888886040516020016112ef9493929190612a67565b6040516020818303038152906040528051906020012090506113678484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152507f000000000000000000000000000000000000000000000000000000000000000092508591506117219050565b61139d576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600889901c60009081526007602052604090208054600160ff8c161b1790556113c98833898886611737565b7fd436e9973d1e44d40db4d4119e3c773cadb1323b263981968c14d3d191c0e1488989898989604051611400959493929190612ae9565b60405180910390a1505050505050505050565b60008183106114225781611424565b825b9392505050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526004602052604081205460ff1661148a576040517fd5cd510000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611493836115aa565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526003602081815260408084208054600284528286208054928790558690559589168552929091528220805494955092939092849290916114f1908490612846565b909155505073ffffffffffffffffffffffffffffffffffffffff84166000908152600260205260408120805483929061152b908490612846565b909155505073ffffffffffffffffffffffffffffffffffffffff85167fcc22011f6028a0d1d9fcbfa015dec953b2bc08df296d28d2a6407b8fcf9c6c82856115738486612918565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091520160405180910390a2505092915050565b60006115b582610b46565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600260205260408120805492935083929091906115ef908490612846565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316907ed5958799b183a7b738d3ad5e711305293dd5076a37a4e3b7e6611dea6114f39060200160405180910390a2919050565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff84166004830152602482018390529060008060448382895af16116a6573d6000803e3d6000fd5b506116b08461186f565b61171b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a206661696c6564207472616e7366657200000000000060448201526064015b60405180910390fd5b50505050565b60008261172e858461193b565b14949350505050565b600085600581111561174b5761174b612a38565b14156117615761175c8383836119df565b611803565b600185600581111561177557611775612a38565b14156117875761175c83838684611abe565b600285600581111561179b5761179b612a38565b14156117ad5761175c83838684611bdd565b60038560058111156117c1576117c1612a38565b14156117d35761175c83838684611cc6565b60048560058111156117e7576117e7612a38565b14156117f85761175c838383611dd2565b611803838383611e7d565b81600560008282546118159190612846565b909155505060405182815273ffffffffffffffffffffffffffffffffffffffff8416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050505050565b60006118af565b7f08c379a00000000000000000000000000000000000000000000000000000000060005260206004528060245250806044525060646000fd5b3d80156118ee5760208114611928576118e97f5361666545524332303a20626164207472616e7366657220726573756c740000601e611876565b611935565b823b61191f5761191f7f5361666545524332303a206e6f74206120636f6e7472616374000000000000006019611876565b60019150611935565b3d6000803e600051151591505b50919050565b600081815b8451811015610b3e57600085828151811061195d5761195d61296a565b6020026020010151905080831161199f5760408051602081018590529081018290526060016040516020818303038152906040528051906020012092506119cc565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b50806119d7816128df565b915050611940565b62375f00611a0d817f0000000000000000000000000000000000000000000000000000000000000000612846565b421115611a46576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611a7e576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526006602052604081208054859290611ab3908490612846565b909155505050505050565b62127500611aec817f0000000000000000000000000000000000000000000000000000000000000000612846565b421115611b25576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611b5d576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bca7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000857f000000000000000000000000000000000000000000000000000000000000000088611f28565b611bd685856000611f60565b5050505050565b62127500611c0b817f0000000000000000000000000000000000000000000000000000000000000000612846565b421115611c44576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611c5957611c548483612047565b611bca565b611bca7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000857f000000000000000000000000000000000000000000000000000000000000000088611f28565b62127500611cf4817f0000000000000000000000000000000000000000000000000000000000000000612846565b421115611d2d576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611d65576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bca7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000857f000000000000000000000000000000000000000000000000000000000000000088611f28565b62375f00611e00817f0000000000000000000000000000000000000000000000000000000000000000612846565b421115611e39576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611e71576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61171b84846001611f60565b62375f00611eab817f0000000000000000000000000000000000000000000000000000000000000000612846565b421115611ee4576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611f1c576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61171b84846000611f60565b6000611f3482866120b3565b9050611f5873ffffffffffffffffffffffffffffffffffffffff87168585846120d2565b505050505050565b8015611fb65773ffffffffffffffffffffffffffffffffffffffff8316600090815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215151790555b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054849290611feb908490612846565b909155505060408051838152821515602082015273ffffffffffffffffffffffffffffffffffffffff8516917f9534c146324716c0538375208553c94318368250a36a4832f663bea2f3351fd3910160405180910390a2505050565b6000612073837f00000000000000000000000000000000000000000000000000000000000000006120b3565b90508082146120ae576040517f27eb4d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6000670de0b6b3a76400006120c883856128a2565b611424919061292f565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff8581166004840152841660248301526044820183905290600080606483828a5af161213d573d6000803e3d6000fd5b506121478561186f565b611bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5361666545524332303a206661696c6564207472616e7366657246726f6d00006044820152606401611712565b60005b838110156121c85781810151838201526020016121b0565b8381111561171b5750506000910152565b600081518084526121f18160208601602086016121ad565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061142460208301846121d9565b803573ffffffffffffffffffffffffffffffffffffffff8116811461225a57600080fd5b919050565b6000806040838503121561227257600080fd5b61227b83612236565b946020939093013593505050565b60006020828403121561229b57600080fd5b61142482612236565b6000806000606084860312156122b957600080fd5b6122c284612236565b92506122d060208501612236565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612356576123566122e0565b604052919050565b6000806040838503121561237157600080fd5b61237a83612236565b915060208084013567ffffffffffffffff8082111561239857600080fd5b818601915086601f8301126123ac57600080fd5b8135818111156123be576123be6122e0565b6123ee847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161230f565b9150808252878482850101111561240457600080fd5b80848401858401376000848284010152508093505050509250929050565b6000806040838503121561243557600080fd5b50508035926020909101359150565b60006020828403121561245657600080fd5b5035919050565b80356006811061225a57600080fd5b60008083601f84011261247e57600080fd5b50813567ffffffffffffffff81111561249657600080fd5b6020830191508360208260051b85010111156124b157600080fd5b9250929050565b600080600080600080600060c0888a0312156124d357600080fd5b873596506124e36020890161245d565b95506124f160408901612236565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561251b57600080fd5b6125278a828b0161246c565b989b979a50959850939692959293505050565b6000806040838503121561254d57600080fd5b61255683612236565b915061256460208401612236565b90509250929050565b600067ffffffffffffffff821115612587576125876122e0565b5060051b60200190565b600082601f8301126125a257600080fd5b813560206125b76125b28361256d565b61230f565b82815260059290921b840181019181810190868411156125d657600080fd5b8286015b848110156125f157803583529183019183016125da565b509695505050505050565b600082601f83011261260d57600080fd5b8135602061261d6125b28361256d565b82815260059290921b8401810191818101908684111561263c57600080fd5b8286015b848110156125f1576126518161245d565b8352918301918301612640565b60008060008060008060008060008060008060e08d8f03121561268057600080fd5b67ffffffffffffffff8d35111561269657600080fd5b6126a38e8e358f01612591565b9b5067ffffffffffffffff60208e013511156126be57600080fd5b6126ce8e60208f01358f016125fc565b9a5067ffffffffffffffff60408e013511156126e957600080fd5b6126f98e60408f01358f0161246c565b909a50985067ffffffffffffffff60608e0135111561271757600080fd5b6127278e60608f01358f0161246c565b909850965067ffffffffffffffff60808e0135111561274557600080fd5b6127558e60808f01358f0161246c565b909650945067ffffffffffffffff60a08e0135111561277357600080fd5b6127838e60a08f01358f0161246c565b909450925067ffffffffffffffff60c08e013511156127a157600080fd5b6127b18e60c08f01358f0161246c565b81935080925050509295989b509295989b509295989b565b600181811c908216806127dd57607f821691505b60208210811415611935577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561285957612859612817565b500190565b600082516128708184602087016121ad565b9190910192915050565b6000835161288c8184602088016121ad565b92151560f81b9190920190815260010192915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156128da576128da612817565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561291157612911612817565b5060010190565b60008282101561292a5761292a612817565b500390565b600082612965577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129ce57600080fd5b83018035915067ffffffffffffffff8211156129e957600080fd5b6020019150600581901b36038213156124b157600080fd5b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000612a3060408301846121d9565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b848152600060068510612aa3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b5060f89390931b602084015260609190911b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218301526035820152605501919050565b85815260a0810160068610612b27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b85602083015273ffffffffffffffffffffffffffffffffffffffff85166040830152836060830152826080830152969550505050505056fea264697066735822122063f0fb84a0188ec301f7006f559e6097e0ded7535272ed77da8795db73dda70f64736f6c634300080a0033246660bd35bfe8e312c39a601894f9874534ff967263b79f0a3196f50b431583000000000000000000000000def1ca1fb7fbcdc777520aa7f396b4e015f497ab000000000000000000000000ca771eda0c70aa7d053ab1b25004559b918fe662000000000000000000000000a1cb7762f40318ee0260f53e15de835ff001cb7e000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000249f00000000000000000000000006810e776880c02933d47db1b9fc05908e5386b96000000000000000000000000000000000000000000000000000214e8348c4f00000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000039257389bb3e000000000000000000000000ca07eaa4253638d286cad71cbceec11803f2709a

Deployed Bytecode

0x6080604052600436106102bb5760003560e01c80639519f8281161016e578063bcfffb68116100cb578063dd62ed3e1161007f578063f3507dab11610064578063f3507dab146108a0578063f84436bd146108b3578063ffd93cd5146108d357600080fd5b8063dd62ed3e14610849578063e4a0ddf71461086c57600080fd5b8063bfc12c05116100b0578063bfc12c05146107ad578063c61f2184146107e1578063dacee3471461081557600080fd5b8063bcfffb6814610761578063be1ae6f91461079557600080fd5b8063a9059cbb11610122578063b1d882eb11610107578063b1d882eb146106e0578063b79b371314610714578063b7d1d98e1461074157600080fd5b8063a9059cbb146102eb578063acaf21f7146106c057600080fd5b80639e34070f116101535780639e34070f1461063e578063a0ef91df1461067e578063a2a626f81461069357600080fd5b80639519f8281461061657806395d89b411461062957600080fd5b80632eb4a7ab1161021c5780635624b25b116101d057806370a08231116101b557806370a08231146105a05780638cd8e8d2146105c057806394b918de146105f457600080fd5b80635624b25b14610560578063687000281461058057600080fd5b8063332572c411610201578063332572c4146104f75780633e9ffbea1461052b57806343218e191461054057600080fd5b80632eb4a7ab1461049c578063313ce567146104d057600080fd5b806317fcb39b1161027357806323b872dd1161025857806323b872dd14610419578063254800d41461043457806326f3acae1461046857600080fd5b806317fcb39b146103cf57806318160ddd1461040357600080fd5b80630ca9279c116102a45780630ca9279c1461031b5780631051e84f1461034957806311eac8551461037657600080fd5b806306fdde03146102c0578063095ea7b3146102eb575b600080fd5b3480156102cc57600080fd5b506102d5610903565b6040516102e29190612223565b60405180910390f35b3480156102f757600080fd5b5061030b61030636600461225f565b610991565b60405190151581526020016102e2565b34801561032757600080fd5b5061033b610336366004612289565b6109c5565b6040519081526020016102e2565b34801561035557600080fd5b5061033b610364366004612289565b60036020526000908152604090205481565b34801561038257600080fd5b506103aa7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4881565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102e2565b3480156103db57600080fd5b506103aa7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b34801561040f57600080fd5b5061033b60055481565b34801561042557600080fd5b5061030b6103063660046122a4565b34801561044057600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000006206c17b81565b34801561047457600080fd5b506103aa7f000000000000000000000000ca07eaa4253638d286cad71cbceec11803f2709a81565b3480156104a857600080fd5b5061033b7f246660bd35bfe8e312c39a601894f9874534ff967263b79f0a3196f50b43158381565b3480156104dc57600080fd5b506104e5601281565b60405160ff90911681526020016102e2565b34801561050357600080fd5b5061033b7f000000000000000000000000000000000000000000000000000039257389bb3e81565b34801561053757600080fd5b5061033b610a06565b34801561054c57600080fd5b506102d561055b36600461235e565b610a1e565b34801561056c57600080fd5b506102d561057b366004612422565b610ac0565b34801561058c57600080fd5b5061033b61059b366004612289565b610b46565b3480156105ac57600080fd5b5061033b6105bb366004612289565b610b7f565b3480156105cc57600080fd5b506103aa7f000000000000000000000000def1ca1fb7fbcdc777520aa7f396b4e015f497ab81565b34801561060057600080fd5b5061061461060f366004612444565b610bc4565b005b6106146106243660046124b8565b610bd9565b34801561063557600080fd5b506102d5610bf2565b34801561064a57600080fd5b5061030b610659366004612444565b600881901c600090815260076020526040902054600160ff9092169190911b16151590565b34801561068a57600080fd5b50610614610bff565b34801561069f57600080fd5b5061033b6106ae366004612289565b60026020526000908152604090205481565b3480156106cc57600080fd5b5061033b6106db366004612289565b610cb9565b3480156106ec57600080fd5b506103aa7f000000000000000000000000a1cb7762f40318ee0260f53e15de835ff001cb7e81565b34801561072057600080fd5b5061033b61072f366004612289565b60066020526000908152604090205481565b34801561074d57600080fd5b5061061461075c366004612289565b610d30565b34801561076d57600080fd5b5061033b7f000000000000000000000000000000000000000000000000000214e8348c4f0081565b3480156107a157600080fd5b5061033b6307861f8081565b3480156107b957600080fd5b5061033b7f000000000000000000000000000000000000000000000000000000006206c17b81565b3480156107ed57600080fd5b506103aa7f0000000000000000000000006810e776880c02933d47db1b9fc05908e5386b9681565b34801561082157600080fd5b5061033b7f00000000000000000000000000000000000000000000000000000000000249f081565b34801561085557600080fd5b5061033b61086436600461253a565b600092915050565b34801561087857600080fd5b506103aa7f000000000000000000000000ca771eda0c70aa7d053ab1b25004559b918fe66281565b6106146108ae36600461265e565b610e0e565b3480156108bf57600080fd5b506102d56108ce36600461235e565b610f6e565b3480156108df57600080fd5b5061030b6108ee366004612289565b60046020526000908152604090205460ff1681565b60008054610910906127c9565b80601f016020809104026020016040519081016040528092919081815260200182805461093c906127c9565b80156109895780601f1061095e57610100808354040283529160200191610989565b820191906000526020600020905b81548152906001019060200180831161096c57829003601f168201915b505050505081565b60006040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109d082610b46565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260066020526040902054610a009190612846565b92915050565b6000610a106110ef565b9050610a1b8161112b565b90565b606060008373ffffffffffffffffffffffffffffffffffffffff1683604051610a47919061285e565b600060405180830381855af49150503d8060008114610a82576040519150601f19603f3d011682016040523d82523d6000602084013e610a87565b606091505b50604051909350909150610ab990610aa5908490849060200161287a565b6040516020818303038152906040526111e5565b5092915050565b60606000610acf8360206128a2565b67ffffffffffffffff811115610ae757610ae76122e0565b6040519080825280601f01601f191660200182016040528015610b11576020820181803683370190505b50905060005b83811015610b3e578481015460208083028401015280610b36816128df565b915050610b17565b509392505050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260026020526040812054610b7583610cb9565b610a009190612918565b73ffffffffffffffffffffffffffffffffffffffff811660009081526002602090815260408083205460038352818420546006909352908320549091610b7591612846565b610bcc6110ef565b50610bd68161112b565b50565b610be987878787878787346111ed565b50505050505050565b60018054610910906127c9565b60007f000000000000000000000000ca771eda0c70aa7d053ab1b25004559b918fe66273ffffffffffffffffffffffffffffffffffffffff164760405160006040518083038185875af1925050503d8060008114610c79576040519150601f19603f3d011682016040523d82523d6000602084013e610c7e565b606091505b5050905080610bd6576040517f68a36fef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260408120546307861f8090610d1c610d127f000000000000000000000000000000000000000000000000000000006206c17b42612918565b6307861f80611413565b610d2691906128a2565b610a00919061292f565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ca07eaa4253638d286cad71cbceec11803f2709a1614610d9f576040517f1f78defd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610dcb827f000000000000000000000000ca07eaa4253638d286cad71cbceec11803f2709a61142b565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260066020526040812080549293508392909190610e05908490612846565b90915550505050565b6000805b8d51811015610f2557838382818110610e2d57610e2d61296a565b9050602002013582610e3f9190612846565b9150610f138e8281518110610e5657610e5661296a565b60200260200101518e8381518110610e7057610e7061296a565b60200260200101518e8e85818110610e8a57610e8a61296a565b9050602002016020810190610e9f9190612289565b8d8d86818110610eb157610eb161296a565b905060200201358c8c87818110610eca57610eca61296a565b905060200201358b8b88818110610ee357610ee361296a565b9050602002810190610ef59190612999565b8b8b8a818110610f0757610f0761296a565b905060200201356111ed565b80610f1d816128df565b915050610e12565b50348114610f5f576040517f46459bbd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050505050565b606060006343218e1960e01b8484604051602401610f8d929190612a01565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051909150309061101c90839061285e565b6000604051808303816000865af19150503d8060008114611059576040519150601f19603f3d011682016040523d82523d6000602084013e61105e565b606091505b50905080925050600082600184516110769190612918565b815181106110865761108661296a565b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916600160f81b1490506110d183600185516110cd9190612918565b9052565b80156110de575050610a00565b6110e7836111e5565b505092915050565b60006110fa336115aa565b336000908152600660205260409020546111149190612846565b336000908152600660205260409020819055919050565b336000908152600660205260408120805483929061114a908490612918565b9250508190555080600560008282546111639190612918565b909155506111aa905073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000def1ca1fb7fbcdc777520aa7f396b4e015f497ab163383611643565b60405181815260009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350565b805160208201fd5b600888901c600090815260076020526040902054600160ff8a161b1615611240576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8484111561127a576040517f28de1fc900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b848410801561129f57503373ffffffffffffffffffffffffffffffffffffffff871614155b156112d6576040517fb052d0e900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000888888886040516020016112ef9493929190612a67565b6040516020818303038152906040528051906020012090506113678484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152507f246660bd35bfe8e312c39a601894f9874534ff967263b79f0a3196f50b43158392508591506117219050565b61139d576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600889901c60009081526007602052604090208054600160ff8c161b1790556113c98833898886611737565b7fd436e9973d1e44d40db4d4119e3c773cadb1323b263981968c14d3d191c0e1488989898989604051611400959493929190612ae9565b60405180910390a1505050505050505050565b60008183106114225781611424565b825b9392505050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526004602052604081205460ff1661148a576040517fd5cd510000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611493836115aa565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526003602081815260408084208054600284528286208054928790558690559589168552929091528220805494955092939092849290916114f1908490612846565b909155505073ffffffffffffffffffffffffffffffffffffffff84166000908152600260205260408120805483929061152b908490612846565b909155505073ffffffffffffffffffffffffffffffffffffffff85167fcc22011f6028a0d1d9fcbfa015dec953b2bc08df296d28d2a6407b8fcf9c6c82856115738486612918565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091520160405180910390a2505092915050565b60006115b582610b46565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600260205260408120805492935083929091906115ef908490612846565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316907ed5958799b183a7b738d3ad5e711305293dd5076a37a4e3b7e6611dea6114f39060200160405180910390a2919050565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff84166004830152602482018390529060008060448382895af16116a6573d6000803e3d6000fd5b506116b08461186f565b61171b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f5361666545524332303a206661696c6564207472616e7366657200000000000060448201526064015b60405180910390fd5b50505050565b60008261172e858461193b565b14949350505050565b600085600581111561174b5761174b612a38565b14156117615761175c8383836119df565b611803565b600185600581111561177557611775612a38565b14156117875761175c83838684611abe565b600285600581111561179b5761179b612a38565b14156117ad5761175c83838684611bdd565b60038560058111156117c1576117c1612a38565b14156117d35761175c83838684611cc6565b60048560058111156117e7576117e7612a38565b14156117f85761175c838383611dd2565b611803838383611e7d565b81600560008282546118159190612846565b909155505060405182815273ffffffffffffffffffffffffffffffffffffffff8416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050505050565b60006118af565b7f08c379a00000000000000000000000000000000000000000000000000000000060005260206004528060245250806044525060646000fd5b3d80156118ee5760208114611928576118e97f5361666545524332303a20626164207472616e7366657220726573756c740000601e611876565b611935565b823b61191f5761191f7f5361666545524332303a206e6f74206120636f6e7472616374000000000000006019611876565b60019150611935565b3d6000803e600051151591505b50919050565b600081815b8451811015610b3e57600085828151811061195d5761195d61296a565b6020026020010151905080831161199f5760408051602081018590529081018290526060016040516020818303038152906040528051906020012092506119cc565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b50806119d7816128df565b915050611940565b62375f00611a0d817f000000000000000000000000000000000000000000000000000000006206c17b612846565b421115611a46576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611a7e576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526006602052604081208054859290611ab3908490612846565b909155505050505050565b62127500611aec817f000000000000000000000000000000000000000000000000000000006206c17b612846565b421115611b25576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611b5d576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bca7f0000000000000000000000006810e776880c02933d47db1b9fc05908e5386b967f000000000000000000000000000000000000000000000000000214e8348c4f00857f000000000000000000000000ca771eda0c70aa7d053ab1b25004559b918fe66288611f28565b611bd685856000611f60565b5050505050565b62127500611c0b817f000000000000000000000000000000000000000000000000000000006206c17b612846565b421115611c44576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611c5957611c548483612047565b611bca565b611bca7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000000000000000000000000000000039257389bb3e857f000000000000000000000000ca771eda0c70aa7d053ab1b25004559b918fe66288611f28565b62127500611cf4817f000000000000000000000000000000000000000000000000000000006206c17b612846565b421115611d2d576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611d65576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611bca7f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb487f00000000000000000000000000000000000000000000000000000000000249f0857f000000000000000000000000a1cb7762f40318ee0260f53e15de835ff001cb7e88611f28565b62375f00611e00817f000000000000000000000000000000000000000000000000000000006206c17b612846565b421115611e39576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611e71576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61171b84846001611f60565b62375f00611eab817f000000000000000000000000000000000000000000000000000000006206c17b612846565b421115611ee4576040517ff7704cc200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8115611f1c576040517f79ef7d0700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61171b84846000611f60565b6000611f3482866120b3565b9050611f5873ffffffffffffffffffffffffffffffffffffffff87168585846120d2565b505050505050565b8015611fb65773ffffffffffffffffffffffffffffffffffffffff8316600090815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215151790555b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054849290611feb908490612846565b909155505060408051838152821515602082015273ffffffffffffffffffffffffffffffffffffffff8516917f9534c146324716c0538375208553c94318368250a36a4832f663bea2f3351fd3910160405180910390a2505050565b6000612073837f000000000000000000000000000000000000000000000000000039257389bb3e6120b3565b90508082146120ae576040517f27eb4d5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6000670de0b6b3a76400006120c883856128a2565b611424919061292f565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000080825273ffffffffffffffffffffffffffffffffffffffff8581166004840152841660248301526044820183905290600080606483828a5af161213d573d6000803e3d6000fd5b506121478561186f565b611bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f5361666545524332303a206661696c6564207472616e7366657246726f6d00006044820152606401611712565b60005b838110156121c85781810151838201526020016121b0565b8381111561171b5750506000910152565b600081518084526121f18160208601602086016121ad565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061142460208301846121d9565b803573ffffffffffffffffffffffffffffffffffffffff8116811461225a57600080fd5b919050565b6000806040838503121561227257600080fd5b61227b83612236565b946020939093013593505050565b60006020828403121561229b57600080fd5b61142482612236565b6000806000606084860312156122b957600080fd5b6122c284612236565b92506122d060208501612236565b9150604084013590509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612356576123566122e0565b604052919050565b6000806040838503121561237157600080fd5b61237a83612236565b915060208084013567ffffffffffffffff8082111561239857600080fd5b818601915086601f8301126123ac57600080fd5b8135818111156123be576123be6122e0565b6123ee847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161230f565b9150808252878482850101111561240457600080fd5b80848401858401376000848284010152508093505050509250929050565b6000806040838503121561243557600080fd5b50508035926020909101359150565b60006020828403121561245657600080fd5b5035919050565b80356006811061225a57600080fd5b60008083601f84011261247e57600080fd5b50813567ffffffffffffffff81111561249657600080fd5b6020830191508360208260051b85010111156124b157600080fd5b9250929050565b600080600080600080600060c0888a0312156124d357600080fd5b873596506124e36020890161245d565b95506124f160408901612236565b9450606088013593506080880135925060a088013567ffffffffffffffff81111561251b57600080fd5b6125278a828b0161246c565b989b979a50959850939692959293505050565b6000806040838503121561254d57600080fd5b61255683612236565b915061256460208401612236565b90509250929050565b600067ffffffffffffffff821115612587576125876122e0565b5060051b60200190565b600082601f8301126125a257600080fd5b813560206125b76125b28361256d565b61230f565b82815260059290921b840181019181810190868411156125d657600080fd5b8286015b848110156125f157803583529183019183016125da565b509695505050505050565b600082601f83011261260d57600080fd5b8135602061261d6125b28361256d565b82815260059290921b8401810191818101908684111561263c57600080fd5b8286015b848110156125f1576126518161245d565b8352918301918301612640565b60008060008060008060008060008060008060e08d8f03121561268057600080fd5b67ffffffffffffffff8d35111561269657600080fd5b6126a38e8e358f01612591565b9b5067ffffffffffffffff60208e013511156126be57600080fd5b6126ce8e60208f01358f016125fc565b9a5067ffffffffffffffff60408e013511156126e957600080fd5b6126f98e60408f01358f0161246c565b909a50985067ffffffffffffffff60608e0135111561271757600080fd5b6127278e60608f01358f0161246c565b909850965067ffffffffffffffff60808e0135111561274557600080fd5b6127558e60808f01358f0161246c565b909650945067ffffffffffffffff60a08e0135111561277357600080fd5b6127838e60a08f01358f0161246c565b909450925067ffffffffffffffff60c08e013511156127a157600080fd5b6127b18e60c08f01358f0161246c565b81935080925050509295989b509295989b509295989b565b600181811c908216806127dd57607f821691505b60208210811415611935577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561285957612859612817565b500190565b600082516128708184602087016121ad565b9190910192915050565b6000835161288c8184602088016121ad565b92151560f81b9190920190815260010192915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156128da576128da612817565b500290565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561291157612911612817565b5060010190565b60008282101561292a5761292a612817565b500390565b600082612965577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129ce57600080fd5b83018035915067ffffffffffffffff8211156129e957600080fd5b6020019150600581901b36038213156124b157600080fd5b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000612a3060408301846121d9565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b848152600060068510612aa3577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b5060f89390931b602084015260609190911b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660218301526035820152605501919050565b85815260a0810160068610612b27577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b85602083015273ffffffffffffffffffffffffffffffffffffffff85166040830152836060830152826080830152969550505050505056fea264697066735822122063f0fb84a0188ec301f7006f559e6097e0ded7535272ed77da8795db73dda70f64736f6c634300080a0033

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

246660bd35bfe8e312c39a601894f9874534ff967263b79f0a3196f50b431583000000000000000000000000def1ca1fb7fbcdc777520aa7f396b4e015f497ab000000000000000000000000ca771eda0c70aa7d053ab1b25004559b918fe662000000000000000000000000a1cb7762f40318ee0260f53e15de835ff001cb7e000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000249f00000000000000000000000006810e776880c02933d47db1b9fc05908e5386b96000000000000000000000000000000000000000000000000000214e8348c4f00000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000039257389bb3e000000000000000000000000ca07eaa4253638d286cad71cbceec11803f2709a

-----Decoded View---------------
Arg [0] : merkleRoot (bytes32): 0x246660bd35bfe8e312c39a601894f9874534ff967263b79f0a3196f50b431583
Arg [1] : cowToken (address): 0xDEf1CA1fb7FBcDC777520aa7f396b4E015F497aB
Arg [2] : communityFundsTarget (address): 0xcA771eda0c70aA7d053aB1B25004559B918FE662
Arg [3] : investorFundsTarget (address): 0xA1cb7762F40318ee0260F53e15De835fF001cb7E
Arg [4] : usdcToken (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [5] : usdcPrice (uint256): 150000
Arg [6] : gnoToken (address): 0x6810e776880C02933D47DB1b9fc05908e5386b96
Arg [7] : gnoPrice (uint256): 585937500000000
Arg [8] : wrappedNativeToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [9] : nativeTokenPrice (uint256): 62833014979390
Arg [10] : teamController (address): 0xca07EaA4253638D286caD71CBcEec11803F2709A

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 246660bd35bfe8e312c39a601894f9874534ff967263b79f0a3196f50b431583
Arg [1] : 000000000000000000000000def1ca1fb7fbcdc777520aa7f396b4e015f497ab
Arg [2] : 000000000000000000000000ca771eda0c70aa7d053ab1b25004559b918fe662
Arg [3] : 000000000000000000000000a1cb7762f40318ee0260f53e15de835ff001cb7e
Arg [4] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [5] : 00000000000000000000000000000000000000000000000000000000000249f0
Arg [6] : 0000000000000000000000006810e776880c02933d47db1b9fc05908e5386b96
Arg [7] : 000000000000000000000000000000000000000000000000000214e8348c4f00
Arg [8] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [9] : 000000000000000000000000000000000000000000000000000039257389bb3e
Arg [10] : 000000000000000000000000ca07eaa4253638d286cad71cbceec11803f2709a


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.