ETH Price: $3,300.85 (-3.47%)
Gas: 13 Gwei

Contract

0xD057B63f5E69CF1B929b356b579Cba08D7688048
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Swap All202193442024-07-02 14:11:3527 hrs ago1719929495IN
CoW Protocol: vCOW Token
0 ETH0.00054747.33899258
Swap All202169322024-07-02 6:06:2335 hrs ago1719900383IN
CoW Protocol: vCOW Token
0 ETH0.000267993.59297825
Swap All202169232024-07-02 6:04:3535 hrs ago1719900275IN
CoW Protocol: vCOW Token
0 ETH0.000228773.06720008
Swap All202168882024-07-02 5:57:3535 hrs ago1719899855IN
CoW Protocol: vCOW Token
0 ETH0.000232393.81548414
Swap All202142712024-07-01 21:10:5944 hrs ago1719868259IN
CoW Protocol: vCOW Token
0 ETH0.000423515.67811388
Swap All202133822024-07-01 18:12:4747 hrs ago1719857567IN
CoW Protocol: vCOW Token
0 ETH0.0009337912.51941368
Swap All202122592024-07-01 14:27:112 days ago1719844031IN
CoW Protocol: vCOW Token
0 ETH0.00073839.89841079
Swap All202076142024-06-30 22:52:592 days ago1719787979IN
CoW Protocol: vCOW Token
0 ETH0.000441885.92432251
Swap All201985002024-06-29 16:21:354 days ago1719678095IN
CoW Protocol: vCOW Token
0 ETH0.000201882.70661779
Swap All201984852024-06-29 16:18:354 days ago1719677915IN
CoW Protocol: vCOW Token
0 ETH0.000193112.5890406
Swap All201984512024-06-29 16:11:474 days ago1719677507IN
CoW Protocol: vCOW Token
0 ETH0.000204722.74478057
Swap All201953962024-06-29 5:56:234 days ago1719640583IN
CoW Protocol: vCOW Token
0 ETH0.000158492.12494732
Swap All201945502024-06-29 3:06:354 days ago1719630395IN
CoW Protocol: vCOW Token
0 ETH0.00012061.61699533
Swap All201939482024-06-29 1:05:234 days ago1719623123IN
CoW Protocol: vCOW Token
0 ETH0.000146691.96677959
Swap All201924332024-06-28 19:59:594 days ago1719604799IN
CoW Protocol: vCOW Token
0 ETH0.000214522.87615399
Swap All201915952024-06-28 17:11:595 days ago1719594719IN
CoW Protocol: vCOW Token
0 ETH0.000444535.9598653
Swap All201906132024-06-28 13:54:115 days ago1719582851IN
CoW Protocol: vCOW Token
0 ETH0.00051096.84969718
Swap All201891202024-06-28 8:54:355 days ago1719564875IN
CoW Protocol: vCOW Token
0 ETH0.000225393.70057563
Swap All201883392024-06-28 6:17:355 days ago1719555455IN
CoW Protocol: vCOW Token
0 ETH0.000193233.17253948
Swap All201827682024-06-27 11:36:356 days ago1719488195IN
CoW Protocol: vCOW Token
0 ETH0.000365074.89449198
Swap All201819682024-06-27 8:55:596 days ago1719478559IN
CoW Protocol: vCOW Token
0 ETH0.000372945
Swap All201742332024-06-26 7:00:477 days ago1719385247IN
CoW Protocol: vCOW Token
0 ETH0.000204723.36118706
Swap All201654072024-06-25 1:26:238 days ago1719278783IN
CoW Protocol: vCOW Token
0 ETH0.000237883.90570708
Swap All201605802024-06-24 9:14:479 days ago1719220487IN
CoW Protocol: vCOW Token
0 ETH0.000439745.89559596
Swap All201591812024-06-24 4:33:119 days ago1719203591IN
CoW Protocol: vCOW Token
0 ETH0.000206612.77004497
View all transactions

Latest 7 internal transactions

Advanced mode:
Parent Transaction Hash Block From To Value
143009662022-03-01 11:57:34855 days ago1646135854
CoW Protocol: vCOW Token
747.27989479 ETH
142643482022-02-23 19:56:07860 days ago1645646167
CoW Protocol: vCOW Token
1.73731838 ETH
142631872022-02-23 15:36:19861 days ago1645630579
CoW Protocol: vCOW Token
1.73731838 ETH
142045112022-02-14 13:20:30870 days ago1644844830
CoW Protocol: vCOW Token
0.13477653 ETH
142042822022-02-14 12:29:06870 days ago1644841746
CoW Protocol: vCOW Token
1.15821225 ETH
141894032022-02-12 5:33:51872 days ago1644644031
CoW Protocol: vCOW Token
1.73731838 ETH
141868132022-02-11 20:05:15872 days ago1644609915  Contract Creation0 ETH
Loading...
Loading

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


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
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.

Validator Index Block Amount
View All Withdrawals

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

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