More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x7d3d59f89d91347809e21551bbec3d2b6ecfea73b69508b430b8fd0dd628c996 | Invalidate Order | (pending) | 27 hrs ago | IN | 0 ETH | (Pending) | |||
Create Order | 21680338 | 2 mins ago | IN | 0.215 ETH | 0.00054044 | ||||
Create Order | 21680334 | 2 mins ago | IN | 0.24 ETH | 0.00058991 | ||||
Create Order | 21680332 | 3 mins ago | IN | 0.3 ETH | 0.00054715 | ||||
Invalidate Order | 21680321 | 5 mins ago | IN | 0 ETH | 0.00065496 | ||||
Create Order | 21680300 | 9 mins ago | IN | 0.2 ETH | 0.00058574 | ||||
Create Order | 21680280 | 13 mins ago | IN | 2.1 ETH | 0.0005422 | ||||
Create Order | 21680279 | 13 mins ago | IN | 60 ETH | 0.00054534 | ||||
Create Order | 21680260 | 17 mins ago | IN | 0.003 ETH | 0.00051745 | ||||
Create Order | 21680255 | 18 mins ago | IN | 0.37 ETH | 0.00046522 | ||||
Create Order | 21680252 | 19 mins ago | IN | 0.3 ETH | 0.00049838 | ||||
Create Order | 21680249 | 19 mins ago | IN | 0.003 ETH | 0.00046589 | ||||
Create Order | 21680233 | 23 mins ago | IN | 0.065 ETH | 0.00056875 | ||||
Create Order | 21680221 | 25 mins ago | IN | 0.0225 ETH | 0.00052195 | ||||
Create Order | 21680217 | 26 mins ago | IN | 0.079 ETH | 0.00048487 | ||||
Invalidate Order | 21680201 | 29 mins ago | IN | 0 ETH | 0.00065581 | ||||
Create Order | 21680191 | 31 mins ago | IN | 0.3 ETH | 0.00053235 | ||||
Create Order | 21680191 | 31 mins ago | IN | 0.1 ETH | 0.00053281 | ||||
Create Order | 21680159 | 37 mins ago | IN | 0.2058 ETH | 0.00042981 | ||||
Create Order | 21680156 | 38 mins ago | IN | 0.15367141 ETH | 0.00049545 | ||||
Create Order | 21680144 | 40 mins ago | IN | 0.0887 ETH | 0.00049109 | ||||
Create Order | 21680144 | 40 mins ago | IN | 0.05 ETH | 0.00048899 | ||||
Create Order | 21680126 | 44 mins ago | IN | 0.03 ETH | 0.00051534 | ||||
Create Order | 21680121 | 45 mins ago | IN | 7 ETH | 0.00054992 | ||||
Create Order | 21680118 | 46 mins ago | IN | 0.03 ETH | 0.0005618 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21680343 | 1 min ago | 0.755 ETH | ||||
21680321 | 5 mins ago | 0.3 ETH | ||||
21680321 | 5 mins ago | 0.3 ETH | ||||
21680303 | 9 mins ago | 0.2 ETH | ||||
21680281 | 13 mins ago | 62.1 ETH | ||||
21680262 | 17 mins ago | 0.003 ETH | ||||
21680259 | 17 mins ago | 0.37 ETH | ||||
21680252 | 19 mins ago | 0.303 ETH | ||||
21680237 | 22 mins ago | 0.065 ETH | ||||
21680223 | 25 mins ago | 0.1015 ETH | ||||
21680201 | 29 mins ago | 0.3 ETH | ||||
21680201 | 29 mins ago | 0.3 ETH | ||||
21680194 | 30 mins ago | 0.4 ETH | ||||
21680160 | 37 mins ago | 0.35947141 ETH | ||||
21680146 | 40 mins ago | 0.1387 ETH | ||||
21680128 | 44 mins ago | 0.03 ETH | ||||
21680124 | 44 mins ago | 7 ETH | ||||
21680121 | 45 mins ago | 0.03 ETH | ||||
21680117 | 46 mins ago | 0.02 ETH | ||||
21680107 | 48 mins ago | 3.169 ETH | ||||
21680099 | 49 mins ago | 0.05 ETH | ||||
21680081 | 53 mins ago | 0.04 ETH | ||||
21680073 | 55 mins ago | 0.03 ETH | ||||
21680026 | 1 hr ago | 2.5 ETH | ||||
21680011 | 1 hr ago | 0.1 ETH |
Loading...
Loading
Contract Name:
CoWSwapEthFlow
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; import "./libraries/EthFlowOrder.sol"; import "./interfaces/ICoWSwapSettlement.sol"; import "./interfaces/ICoWSwapEthFlow.sol"; import "./interfaces/IWrappedNativeToken.sol"; import "./mixins/CoWSwapOnchainOrders.sol"; import "./vendored/GPv2EIP1271.sol"; /// @title CoW Swap ETH Flow /// @author CoW Swap Developers contract CoWSwapEthFlow is CoWSwapOnchainOrders, EIP1271Verifier, ICoWSwapEthFlow { using EthFlowOrder for EthFlowOrder.Data; using GPv2Order for GPv2Order.Data; using GPv2Order for bytes; /// @dev The address of the CoW Swap settlement contract that will be used to settle orders created by this /// contract. ICoWSwapSettlement public immutable cowSwapSettlement; /// @dev The address of the contract representing the default native token in the current chain (e.g., WETH for /// Ethereum mainnet). IWrappedNativeToken public immutable wrappedNativeToken; /// @dev Each ETH flow order as described in [`EthFlowOrder.Data`] can be converted to a CoW Swap order. Distinct /// CoW Swap orders have non-colliding order hashes. This mapping associates some extra data to a specific CoW Swap /// order. This data is stored onchain and is used to verify the ownership and validity of an ETH flow order. /// An ETH flow order can be settled onchain only if converting it to a CoW Swap order and hashing yields valid /// onchain data. mapping(bytes32 => EthFlowOrder.OnchainData) public orders; /// @param _cowSwapSettlement The CoW Swap settlement contract. /// @param _wrappedNativeToken The default native token in the current chain (e.g., WETH on mainnet). constructor( ICoWSwapSettlement _cowSwapSettlement, IWrappedNativeToken _wrappedNativeToken ) CoWSwapOnchainOrders(address(_cowSwapSettlement)) { cowSwapSettlement = _cowSwapSettlement; wrappedNativeToken = _wrappedNativeToken; _wrappedNativeToken.approve( cowSwapSettlement.vaultRelayer(), type(uint256).max ); } // The contract needs to be able to receive native tokens when unwrapping. // solhint-disable-next-line no-empty-blocks receive() external payable {} /// @inheritdoc ICoWSwapEthFlow function wrapAll() external { wrap(address(this).balance); } /// @inheritdoc ICoWSwapEthFlow function wrap(uint256 amount) public { // The fallback implementation of the standard WETH9 contract just calls `deposit`. Using the fallback instead // of directly calling `deposit` is slightly cheaper in terms of gas. // solhint-disable-next-line avoid-low-level-calls (bool success, ) = payable(address(wrappedNativeToken)).call{ value: amount }(""); // The success value is intentionally disregarded. The callback of the standard WETH9 contract has no revert // path in the code, so it could only revert if the internal call runs out of gas. This is not considered a // security risk since a reverting internal call would just mean that calling this function has no effect. success; } /// @inheritdoc ICoWSwapEthFlow function unwrap(uint256 amount) external { wrappedNativeToken.withdraw(amount); } /// @inheritdoc ICoWSwapEthFlow function createOrder(EthFlowOrder.Data calldata order) external payable returns (bytes32 orderHash) { if (msg.value != order.sellAmount + order.feeAmount) { revert IncorrectEthAmount(); } if (0 == order.sellAmount) { revert NotAllowedZeroSellAmount(); } // solhint-disable-next-line not-rely-on-time if (order.validTo < block.timestamp) { revert OrderIsAlreadyExpired(); } EthFlowOrder.OnchainData memory onchainData = EthFlowOrder.OnchainData( msg.sender, order.validTo ); OnchainSignature memory signature = OnchainSignature( OnchainSigningScheme.Eip1271, abi.encodePacked(address(this)) ); // The data event field includes extra information needed to settle orders with the CoW Swap API. bytes memory data = abi.encodePacked( order.quoteId, onchainData.validTo ); orderHash = broadcastOrder( onchainData.owner, order.toCoWSwapOrder(wrappedNativeToken), signature, data ); if (orders[orderHash].owner != EthFlowOrder.NO_OWNER) { revert OrderIsAlreadyOwned(orderHash); } orders[orderHash] = onchainData; } /// @inheritdoc ICoWSwapEthFlow function invalidateOrdersIgnoringNotAllowed( EthFlowOrder.Data[] calldata orderArray ) external { for (uint256 i = 0; i < orderArray.length; i++) { _invalidateOrder(orderArray[i], false); } } /// @inheritdoc ICoWSwapEthFlow function invalidateOrder(EthFlowOrder.Data calldata order) public { _invalidateOrder(order, true); } /// @dev Performs the same tasks as `invalidateOrder` (see documentation in `ICoWSwapEthFlow`), but also allows the /// caller to ignore the revert condition `NotAllowedToInvalidateOrder`. Instead of reverting, it stops execution /// without causing any state change. /// /// @param order order to be invalidated. /// @param revertOnInvalidDeletion controls whether the function call should revert or just return. function _invalidateOrder( EthFlowOrder.Data calldata order, bool revertOnInvalidDeletion ) internal { GPv2Order.Data memory cowSwapOrder = order.toCoWSwapOrder( wrappedNativeToken ); bytes32 orderHash = cowSwapOrder.hash(cowSwapDomainSeparator); EthFlowOrder.OnchainData memory orderData = orders[orderHash]; // solhint-disable-next-line not-rely-on-time bool isTradable = orderData.validTo >= block.timestamp; if ( orderData.owner == EthFlowOrder.INVALIDATED_OWNER || orderData.owner == EthFlowOrder.NO_OWNER || (isTradable && orderData.owner != msg.sender) ) { if (revertOnInvalidDeletion) { revert NotAllowedToInvalidateOrder(orderHash); } else { return; } } orders[orderHash].owner = EthFlowOrder.INVALIDATED_OWNER; bytes memory orderUid = new bytes(GPv2Order.UID_LENGTH); orderUid.packOrderUidParams( orderHash, address(this), cowSwapOrder.validTo ); // solhint-disable-next-line not-rely-on-time if (isTradable) { // Order is valid but its owner decided to invalidate it. emit OrderInvalidation(orderUid); } else { // The order cannot be traded anymore, so this transaction is likely triggered to get back the ETH. We are // interested in knowing who is the source of the refund. emit OrderRefund(orderUid, msg.sender); } uint256 filledAmount = cowSwapSettlement.filledAmount(orderUid); // This comment argues that a CoW Swap trader does not pay more fees if a partially fillable order is // (partially) settled in multiple batches rather than in one single batch of the combined size. // This also means that we can refund the user assuming the worst case of settling the filled amount in a single // batch without risking giving out more funds than available in the contract because of rounding issues. // A CoW Swap trader is always charged exactly the amount of fees that is proportional to the filled amount // rounded down to the smaller integer. The code is here: // https://github.com/cowprotocol/contracts/blob/d4e0fcd58367907bf1aff54d182222eeaee793dd/src/contracts/GPv2Settlement.sol#L385-L387 // We show that a trader pays less in fee to CoW Swap when settiling a partially fillable order in two // executions rather than a single one for the combined amount; by induction this proves our original statement. // Our previous statement is equivalent to `floor(a/c) + floor(b/c) ≤ floor((a+b)/c)`. Writing a and b in terms // of reminders (`a = ad*c+ar`, `b = bd*c+br`) the equation becomes `ad + bd ≤ ad + bd + floor((ar+br)/c)`, // which is immediately true. uint256 refundAmount; unchecked { // - Multiplication overflow: since this smart contract never invalidates orders on CoW Swap, // `filledAmount <= sellAmount`. Also, `feeAmount + sellAmount` is an amount of native tokens that was // originally sent by the user. As such, it cannot be larger than the amount of native tokens available, // which is smaller than 2¹²⁸/10¹⁸ ≈ 10²⁰ in all networks supported by CoW Swap so far. Since both values // are smaller than 2¹²⁸, their product does not overflow a uint256. // - Subtraction underflow: again `filledAmount ≤ sellAmount`, meaning: // feeAmount * filledAmount / sellAmount ≤ feeAmount uint256 feeRefundAmount = cowSwapOrder.feeAmount - ((cowSwapOrder.feeAmount * filledAmount) / cowSwapOrder.sellAmount); // - Subtraction underflow: as noted before, filledAmount ≤ sellAmount. // - Addition overflow: as noted before, the user already sent feeAmount + sellAmount native tokens, which // did not overflow. refundAmount = cowSwapOrder.sellAmount - filledAmount + feeRefundAmount; } // If not enough native token is available in the contract, unwrap the needed amount. if (address(this).balance < refundAmount) { uint256 withdrawAmount; unchecked { withdrawAmount = refundAmount - address(this).balance; } wrappedNativeToken.withdraw(withdrawAmount); } // Using low level calls to perform the transfer avoids setting arbitrary limits to the amount of gas used in a // call. Reentrancy is avoided thanks to the `nonReentrant` function modifier. // solhint-disable-next-line avoid-low-level-calls (bool success, ) = payable(orderData.owner).call{value: refundAmount}( "" ); if (!success) { revert EthTransferFailed(); } } /// @inheritdoc ICoWSwapEthFlow function isValidSignature(bytes32 orderHash, bytes memory) external view override(EIP1271Verifier, ICoWSwapEthFlow) returns (bytes4) { // Note: the signature parameter is ignored since all information needed to verify the validity of the order is // already available onchain. EthFlowOrder.OnchainData memory orderData = orders[orderHash]; if ( (orderData.owner != EthFlowOrder.NO_OWNER) && (orderData.owner != EthFlowOrder.INVALIDATED_OWNER) && // solhint-disable-next-line not-rely-on-time (orderData.validTo >= block.timestamp) ) { return GPv2EIP1271.MAGICVALUE; } else { return bytes4(type(uint32).max); } } }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; import "../libraries/EthFlowOrder.sol"; /// @title CoW Swap ETH Flow Event Interface /// @author CoW Swap Developers interface ICoWSwapEthFlowEvents { /// @dev Event emitted to notify that an order was refunded. Note that this event is not fired every time the order /// is invalidated (even though the user receives all unspent ETH back). This is because we want to differenciate /// the case where the user invalidates a valid order and when the user receives back the funds from an expired /// order. /// /// @param orderUid CoW Swap's unique order identifier of the order that has been invalidated (and refunded). /// @param refunder The address that triggered the order refund. event OrderRefund(bytes orderUid, address indexed refunder); } /// @title CoW Swap ETH Flow Interface /// @author CoW Swap Developers interface ICoWSwapEthFlow is ICoWSwapEthFlowEvents { /// @dev Error thrown when trying to create a new order whose order hash is the same as an order hash that was /// already assigned. error OrderIsAlreadyOwned(bytes32 orderHash); /// @dev Error thrown when trying to create an order that would be expired at the time of creation error OrderIsAlreadyExpired(); /// @dev Error thrown when trying to create an order without sending the expected amount of ETH to this contract. error IncorrectEthAmount(); /// @dev Error thrown when trying to create an order with a sell amount == 0 error NotAllowedZeroSellAmount(); /// @dev Error thrown if trying to invalidate an order while not allowed. error NotAllowedToInvalidateOrder(bytes32 orderHash); /// @dev Error thrown when unsuccessfully sending ETH to an address. error EthTransferFailed(); /// @dev Function that creates and broadcasts an ETH flow order that sells native ETH. The order is paid for when /// the caller sends out the transaction. The caller takes ownership of the new order. /// /// @param order The data describing the order to be created. See [`EthFlowOrder.Data`] for extra information on /// each parameter. /// @return orderHash The hash of the CoW Swap order that is created to settle the new ETH order. function createOrder(EthFlowOrder.Data calldata order) external payable returns (bytes32 orderHash); /// @dev Marks existing ETH-flow orders as invalid and, for each order, refunds the ETH that hasn't been traded yet. /// The function call will not revert, if some orders are not refundable. It will silently ignore these orders. /// Note that some parameters of the orders are ignored, as for example the order expiration date and the quote id. /// /// @param orderArray Array of orders to be invalidated. function invalidateOrdersIgnoringNotAllowed( EthFlowOrder.Data[] calldata orderArray ) external; /// @dev Marks an existing ETH-flow order as invalid and refunds the ETH that hasn't been traded yet. /// Note that some parameters of the orders are ignored, as for example the order expiration date and the quote id. /// /// @param order Order to be invalidated. function invalidateOrder(EthFlowOrder.Data calldata order) external; /// @dev EIP1271-compliant onchain signature verification function. /// This function is used by the CoW Swap settlement contract to determine if an order that is signed with an /// EIP1271 signature is valid. As this contract has approved the vault relayer contract, a valid signature for an /// order means that the order can be traded on CoW Swap. /// /// @param orderHash Hash of the order to be signed. This is the EIP-712 signing hash for the specified order as /// defined in the CoW Swap settlement contract. /// @param signature Signature byte array. This parameter is unused since as all information needed to verify if an /// order is already available onchain. /// @return magicValue Either the EIP-1271 "magic value" indicating success (0x1626ba7e) or a different value /// indicating failure (0xffffffff). function isValidSignature(bytes32 orderHash, bytes memory signature) external view returns (bytes4 magicValue); /// @dev This function reads the chain's native token balance of this contract (e.g., ETH for mainnet) and converts // the entire amount to its wrapped version (e.g., WETH). function wrapAll() external; /// @dev This function takes the specified amount of the chain's native token (e.g., ETH for mainnet) stored by this /// contract and converts it to its wrapped version (e.g., WETH). /// /// @param amount The amount of native tokens to convert to wrapped native tokens. function wrap(uint256 amount) external; /// @dev This function takes the specified amount of the chain's wrapped native token (e.g., WETH for mainnet) /// and converts it to its unwrapped version (e.g., ETH). /// /// @param amount The amount of wrapped native tokens to convert to native tokens. function unwrap(uint256 amount) external; }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; import "../vendored/GPv2Order.sol"; /// @title CoW Swap Onchain Order Creator Interface /// @author CoW Swap Developers interface ICoWSwapOnchainOrders { /// @dev List of signature schemes that are supported by this contract to create orders onchain. enum OnchainSigningScheme { Eip1271, PreSign } /// @dev Struct containing information on the signign scheme used plus the corresponding signature. struct OnchainSignature { /// @dev The signing scheme used by the signature data. OnchainSigningScheme scheme; /// @dev The data used as an order signature. bytes data; } /// @dev Event emitted to broadcast an order onchain. /// /// @param sender The user who triggered the creation of the order. Note that this address does *not* need to be /// the actual owner of the order and does not need to be related to the order or signature in any way. /// For example, if a smart contract creates orders on behalf of the user, then the sender would be the user who /// triggers the creation of the order, while the actual owner of the order would be the smart contract that /// creates it. /// @param order Information on the order that is created in this transacion. The order is expected to be a valid /// order for the CoW Swap settlement contract and contain all information needed to settle it in a batch. /// @param signature The signature that can be used to verify the newly created order. Note that it is always /// possible to recover the owner of the order from a valid signature. /// @param data Any extra data that should be passed along with the order. This will be used by the services that /// collects onchain orders and no specific encoding is enforced on this field. It is supposed to encode extra /// information that is not included in the order data so that it can be passed along when decoding an onchain /// order. As an example, a contract that creates orders on behalf of a user could set a different expiration date /// than the one specified in the order. event OrderPlacement( address indexed sender, GPv2Order.Data order, OnchainSignature signature, bytes data ); /// @dev Event emitted to notify that an order was invalidated. /// /// @param orderUid CoW Swap's unique order identifier of the order that has been invalidated. event OrderInvalidation(bytes orderUid); }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; /// @title CoW Swap Settlement Contract Interface /// @author CoW Swap Developers /// @dev This interface collects the functions of the CoW Swap settlement contract that are used by the ETH flow /// contract. interface ICoWSwapSettlement { /// @dev Map each user order by UID to the amount that has been filled so /// far. If this amount is larger than or equal to the amount traded in the /// order (amount sold for sell orders, amount bought for buy orders) then /// the order cannot be traded anymore. If the order is fill or kill, then /// this value is only used to determine whether the order has already been /// executed. /// @param orderUid The uinique identifier to use to retrieve the filled amount. function filledAmount(bytes memory orderUid) external returns (uint256); /// @dev The address of the vault relayer: the contract that handles withdrawing tokens from the user to the /// settlement contract. A user who wants to sell a token on CoW Swap must approve this contract to spend the token. function vaultRelayer() external returns (address); }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; import "../vendored/IERC20.sol"; /// @title CoW Swap Wrapped Native Token Interface /// @author CoW Swap Developers interface IWrappedNativeToken is IERC20 { /// @dev Deposit native token in exchange for wrapped netive tokens. function deposit() external payable; /// @dev Burn wrapped native tokens in exchange for native tokens. /// @param amount Amount of wrapped tokens to exchange for native tokens. function withdraw(uint256 amount) external; }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; /// @title CoW Swap EIP-712 Encoding Library /// @author CoW Swap Developers /// @dev The code in this contract was largely taken from: /// <https://raw.githubusercontent.com/cowprotocol/contracts/v1.0.0/src/contracts/mixins/GPv2Signing.sol> library CoWSwapEip712 { /// @dev The EIP-712 domain type hash used for computing the domain separator. bytes32 private constant DOMAIN_TYPE_HASH = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); /// @dev The EIP-712 domain name used for computing the domain separator. bytes32 private constant DOMAIN_NAME = keccak256("Gnosis Protocol"); /// @dev The EIP-712 domain version used for computing the domain separator. bytes32 private constant DOMAIN_VERSION = keccak256("v2"); /// @dev Computes the EIP-712 domain separator of the CoW Swap settlement contract on the current network. /// /// @param cowSwapAddress The address of the CoW Swap settlement contract for which to compute the domain separator. /// Note that there are no checks to verify that the input address points to an actual contract. /// @return The domain separator of the settlement contract for the input address as computed by the settlement /// contract internally. function domainSeparator(address cowSwapAddress) internal view returns (bytes32) { // NOTE: Currently, the only way to get the chain ID in solidity is using assembly. uint256 chainId; // solhint-disable-next-line no-inline-assembly assembly { chainId := chainid() } return keccak256( abi.encode( DOMAIN_TYPE_HASH, DOMAIN_NAME, DOMAIN_VERSION, chainId, cowSwapAddress ) ); } }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; import "../vendored/GPv2Order.sol"; import "../vendored/IERC20.sol"; /// @title CoW Swap ETH Flow Order Library /// @author CoW Swap Developers library EthFlowOrder { /// @dev Struct collecting all parameters of an ETH flow order that need to be stored onchain. struct OnchainData { /// @dev The address of the user whom the order belongs to. address owner; /// @dev The latest timestamp in seconds when the order can be settled. uint32 validTo; } /// @dev Data describing all parameters of an ETH flow order. struct Data { /// @dev The address of the token that should be bought for ETH. It follows the same format as in the CoW Swap /// contracts, meaning that the token GPv2Transfer.BUY_ETH_ADDRESS (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) /// represents native ETH (and should most likely not be used in this context). IERC20 buyToken; /// @dev The address that should receive the proceeds from the order. Note that using the address /// GPv2Order.RECEIVER_SAME_AS_OWNER (i.e., the zero address) as the receiver is not allowed. address receiver; /// @dev The exact amount of ETH that should be sold in this order. uint256 sellAmount; /// @dev The minimum amount of buyToken that should be received to settle this order. uint256 buyAmount; /// @dev Extra data to include in the order. It is used by the CoW Swap infrastructure as extra information on /// the order and has no direct effect on on-chain execution. bytes32 appData; /// @dev The exact amount of ETH that should be paid by the user to the CoW Swap contract after the order is /// settled. uint256 feeAmount; /// @dev The latest timestamp in seconds when the order can be settled. uint32 validTo; /// @dev Flag indicating whether the order is fill-or-kill or can be filled partially. bool partiallyFillable; /// @dev quoteId The quote id obtained from the CoW Swap API to lock in the current price. It is not directly /// used by any onchain component but is part of the information emitted onchain on order creation and may be /// required for an order to be automatically picked up by the CoW Swap orderbook. int64 quoteId; } /// @dev An order that is owned by this address is an order that has not yet been assigned. address internal constant NO_OWNER = address(0); /// @dev An order that is owned by this address is an order that has been invalidated. Note that this address cannot /// be directly used to create orders. address internal constant INVALIDATED_OWNER = address(type(uint160).max); /// @dev Error returned if the receiver of the ETH flow order is unspecified (`GPv2Order.RECEIVER_SAME_AS_OWNER`). error ReceiverMustBeSet(); /// @dev Transforms an ETH flow order into the CoW Swap order that can be settled by the ETH flow contract. /// /// @param order The ETH flow order to be converted. /// @param wrappedNativeToken The address of the wrapped native token for the current network (e.g., WETH for /// Ethereum mainet). /// @return The CoW Swap order data that represents the user order in the ETH flow contract. function toCoWSwapOrder(Data memory order, IERC20 wrappedNativeToken) internal pure returns (GPv2Order.Data memory) { if (order.receiver == GPv2Order.RECEIVER_SAME_AS_OWNER) { // The receiver field specified which address is going to receive the proceeds from the orders. If using // `RECEIVER_SAME_AS_OWNER`, then the receiver is implicitly assumed by the CoW Swap Protocol to be the // same as the order owner. // However, the owner of an ETH flow order is always the ETH flow smart contract, and any ERC20 tokens sent // to this contract would be lost. revert ReceiverMustBeSet(); } // Note that not all fields from `order` are used in creating the corresponding CoW Swap order. // For example, validTo and quoteId are ignored. return GPv2Order.Data( wrappedNativeToken, // IERC20 sellToken order.buyToken, // IERC20 buyToken order.receiver, // address receiver order.sellAmount, // uint256 sellAmount order.buyAmount, // uint256 buyAmount // This CoW Swap order is not allowed to expire. If it expired, then any solver of CoW Swap contract // would be allowed to clear the `filledAmount` for this order using `freeFilledAmountStorage`, making // it impossible to detect if the order has been previously filled. // Note that order.validTo is disregarded in building the CoW Swap order. type(uint32).max, // uint32 validTo order.appData, // bytes32 appData order.feeAmount, // uint256 feeAmount // Only sell orders are allowed. In a buy order, any leftover ETH would stay in the ETH flow contract // and would need to be sent back to the user, whose extra gas cost is usually not worth it. GPv2Order.KIND_SELL, // bytes32 kind order.partiallyFillable, // bool partiallyFillable // We do not currently support interacting with the Balancer vault. GPv2Order.BALANCE_ERC20, // bytes32 sellTokenBalance GPv2Order.BALANCE_ERC20 // bytes32 buyTokenBalance ); } }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; import "../vendored/GPv2Order.sol"; import "../interfaces/ICoWSwapOnchainOrders.sol"; import "../libraries/CoWSwapEip712.sol"; /// @title CoW Swap Onchain Order Creator Event Emitter /// @author CoW Swap Developers contract CoWSwapOnchainOrders is ICoWSwapOnchainOrders { using GPv2Order for GPv2Order.Data; using GPv2Order for bytes; /// @dev The domain separator for the CoW Swap settlement contract. bytes32 internal immutable cowSwapDomainSeparator; /// @param settlementContractAddress The address of CoW Swap's settlement contract on the chain where this contract /// is deployed. constructor(address settlementContractAddress) { cowSwapDomainSeparator = CoWSwapEip712.domainSeparator( settlementContractAddress ); } /// @dev Emits an event with all information needed to execute an order onchain and returns the corresponding order /// hash. /// /// See [`ICoWSwapOnchainOrders.OrderPlacement`] for details on the meaning of each parameter. /// @return The EIP-712 hash of the order data as computed by the CoW Swap settlement contract. function broadcastOrder( address sender, GPv2Order.Data memory order, OnchainSignature memory signature, bytes memory data ) internal returns (bytes32) { emit OrderPlacement(sender, order, signature, data); return order.hash(cowSwapDomainSeparator); } }
// SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity ^0.8; // Vendored from GPv2 contracts v1.0.0, see: // <https://raw.githubusercontent.com/cowprotocol/contracts/main/src/contracts/interfaces/GPv2EIP1271.sol> // The following changes were made: // - Bumped up Solidity version. library GPv2EIP1271 { /// @dev Value returned by a call to `isValidSignature` if the signature /// was verified successfully. The value is defined in EIP-1271 as: /// bytes4(keccak256("isValidSignature(bytes32,bytes)")) bytes4 internal constant MAGICVALUE = 0x1626ba7e; } /// @title EIP1271 Interface /// @dev Standardized interface for an implementation of smart contract /// signatures as described in EIP-1271. The code that follows is identical to /// the code in the standard with the exception of formatting and syntax /// changes to adapt the code to our Solidity version. interface EIP1271Verifier { /// @dev Should return whether the signature provided is valid for the /// provided data /// @param _hash Hash of the data to be signed /// @param _signature Signature byte array associated with _data /// /// MUST return the bytes4 magic value 0x1626ba7e when function passes. /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for /// solc > 0.5) /// MUST allow external calls /// function isValidSignature(bytes32 _hash, bytes memory _signature) external view returns (bytes4 magicValue); }
// SPDX-License-Identifier: LGPL-3.0-or-later // Vendored from GPv2 contracts v1.0.0, see: // <https://raw.githubusercontent.com/cowprotocol/contracts/v1.0.0/src/contracts/libraries/GPv2Order.sol> // The following changes were made: // - Bumped up Solidity version. // - Vendored imports. pragma solidity ^0.8; import "./IERC20.sol"; /// @title Gnosis Protocol v2 Order Library /// @author Gnosis Developers library GPv2Order { /// @dev The complete data for a Gnosis Protocol order. This struct contains /// all order parameters that are signed for submitting to GP. struct Data { IERC20 sellToken; IERC20 buyToken; address receiver; uint256 sellAmount; uint256 buyAmount; uint32 validTo; bytes32 appData; uint256 feeAmount; bytes32 kind; bool partiallyFillable; bytes32 sellTokenBalance; bytes32 buyTokenBalance; } /// @dev The order EIP-712 type hash for the [`GPv2Order.Data`] struct. /// /// This value is pre-computed from the following expression: /// ``` /// keccak256( /// "Order(" + /// "address sellToken," + /// "address buyToken," + /// "address receiver," + /// "uint256 sellAmount," + /// "uint256 buyAmount," + /// "uint32 validTo," + /// "bytes32 appData," + /// "uint256 feeAmount," + /// "string kind," + /// "bool partiallyFillable" + /// "string sellTokenBalance" + /// "string buyTokenBalance" + /// ")" /// ) /// ``` bytes32 internal constant TYPE_HASH = hex"d5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e489"; /// @dev The marker value for a sell order for computing the order struct /// hash. This allows the EIP-712 compatible wallets to display a /// descriptive string for the order kind (instead of 0 or 1). /// /// This value is pre-computed from the following expression: /// ``` /// keccak256("sell") /// ``` bytes32 internal constant KIND_SELL = hex"f3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee346775"; /// @dev The OrderKind marker value for a buy order for computing the order /// struct hash. /// /// This value is pre-computed from the following expression: /// ``` /// keccak256("buy") /// ``` bytes32 internal constant KIND_BUY = hex"6ed88e868af0a1983e3886d5f3e95a2fafbd6c3450bc229e27342283dc429ccc"; /// @dev The TokenBalance marker value for using direct ERC20 balances for /// computing the order struct hash. /// /// This value is pre-computed from the following expression: /// ``` /// keccak256("erc20") /// ``` bytes32 internal constant BALANCE_ERC20 = hex"5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc9"; /// @dev The TokenBalance marker value for using Balancer Vault external /// balances (in order to re-use Vault ERC20 approvals) for computing the /// order struct hash. /// /// This value is pre-computed from the following expression: /// ``` /// keccak256("external") /// ``` bytes32 internal constant BALANCE_EXTERNAL = hex"abee3b73373acd583a130924aad6dc38cfdc44ba0555ba94ce2ff63980ea0632"; /// @dev The TokenBalance marker value for using Balancer Vault internal /// balances for computing the order struct hash. /// /// This value is pre-computed from the following expression: /// ``` /// keccak256("internal") /// ``` bytes32 internal constant BALANCE_INTERNAL = hex"4ac99ace14ee0a5ef932dc609df0943ab7ac16b7583634612f8dc35a4289a6ce"; /// @dev Marker address used to indicate that the receiver of the trade /// proceeds should the owner of the order. /// /// This is chosen to be `address(0)` for gas efficiency as it is expected /// to be the most common case. address internal constant RECEIVER_SAME_AS_OWNER = address(0); /// @dev The byte length of an order unique identifier. uint256 internal constant UID_LENGTH = 56; /// @dev Returns the actual receiver for an order. This function checks /// whether or not the [`receiver`] field uses the marker value to indicate /// it is the same as the order owner. /// /// @return receiver The actual receiver of trade proceeds. function actualReceiver(Data memory order, address owner) internal pure returns (address receiver) { if (order.receiver == RECEIVER_SAME_AS_OWNER) { receiver = owner; } else { receiver = order.receiver; } } /// @dev Return the EIP-712 signing hash for the specified order. /// /// @param order The order to compute the EIP-712 signing hash for. /// @param domainSeparator The EIP-712 domain separator to use. /// @return orderDigest The 32 byte EIP-712 struct hash. function hash(Data memory order, bytes32 domainSeparator) internal pure returns (bytes32 orderDigest) { bytes32 structHash; // NOTE: Compute the EIP-712 order struct hash in place. As suggested // in the EIP proposal, noting that the order struct has 10 fields, and // including the type hash `(12 + 1) * 32 = 416` bytes to hash. // <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#rationale-for-encodedata> // solhint-disable-next-line no-inline-assembly assembly { let dataStart := sub(order, 32) let temp := mload(dataStart) mstore(dataStart, TYPE_HASH) structHash := keccak256(dataStart, 416) mstore(dataStart, temp) } // NOTE: Now that we have the struct hash, compute the EIP-712 signing // hash using scratch memory past the free memory pointer. The signing // hash is computed from `"\x19\x01" || domainSeparator || structHash`. // <https://docs.soliditylang.org/en/v0.8.16/internals/layout_in_memory.html#layout-in-memory> // <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#specification> // solhint-disable-next-line no-inline-assembly assembly { let freeMemoryPointer := mload(0x40) mstore(freeMemoryPointer, "\x19\x01") mstore(add(freeMemoryPointer, 2), domainSeparator) mstore(add(freeMemoryPointer, 34), structHash) orderDigest := keccak256(freeMemoryPointer, 66) } } /// @dev Packs order UID parameters into the specified memory location. The /// result is equivalent to `abi.encodePacked(...)` with the difference that /// it allows re-using the memory for packing the order UID. /// /// This function reverts if the order UID buffer is not the correct size. /// /// @param orderUid The buffer pack the order UID parameters into. /// @param orderDigest The EIP-712 struct digest derived from the order /// parameters. /// @param owner The address of the user who owns this order. /// @param validTo The epoch time at which the order will stop being valid. function packOrderUidParams( bytes memory orderUid, bytes32 orderDigest, address owner, uint32 validTo ) internal pure { require(orderUid.length == UID_LENGTH, "GPv2: uid buffer overflow"); // NOTE: Write the order UID to the allocated memory buffer. The order // parameters are written to memory in **reverse order** as memory // operations write 32-bytes at a time and we want to use a packed // encoding. This means, for example, that after writing the value of // `owner` to bytes `20:52`, writing the `orderDigest` to bytes `0:32` // will **overwrite** bytes `20:32`. This is desirable as addresses are // only 20 bytes and `20:32` should be `0`s: // // | 1111111111222222222233333333334444444444555555 // byte | 01234567890123456789012345678901234567890123456789012345 // -------+--------------------------------------------------------- // field | [.........orderDigest..........][......owner.......][vT] // -------+--------------------------------------------------------- // mstore | [000000000000000000000000000.vT] // | [00000000000.......owner.......] // | [.........orderDigest..........] // // Additionally, since Solidity `bytes memory` are length prefixed, // 32 needs to be added to all the offsets. // // solhint-disable-next-line no-inline-assembly assembly { mstore(add(orderUid, 56), validTo) mstore(add(orderUid, 52), owner) mstore(add(orderUid, 32), orderDigest) } } /// @dev Extracts specific order information from the standardized unique /// order id of the protocol. /// /// @param orderUid The unique identifier used to represent an order in /// the protocol. This uid is the packed concatenation of the order digest, /// the validTo order parameter and the address of the user who created the /// order. It is used by the user to interface with the contract directly, /// and not by calls that are triggered by the solvers. /// @return orderDigest The EIP-712 signing digest derived from the order /// parameters. /// @return owner The address of the user who owns this order. /// @return validTo The epoch time at which the order will stop being valid. function extractOrderUidParams(bytes calldata orderUid) internal pure returns ( bytes32 orderDigest, address owner, uint32 validTo ) { require(orderUid.length == UID_LENGTH, "GPv2: invalid uid"); // Use assembly to efficiently decode packed calldata. // solhint-disable-next-line no-inline-assembly assembly { orderDigest := calldataload(orderUid.offset) owner := shr(96, calldataload(add(orderUid.offset, 32))) validTo := shr(224, calldataload(add(orderUid.offset, 52))) } } }
// 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 ); }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "evmVersion": "london", "remappings": [ ":ds-test/=lib/forge-std/lib/ds-test/src/", ":forge-std/=lib/forge-std/src/", ":openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ICoWSwapSettlement","name":"_cowSwapSettlement","type":"address"},{"internalType":"contract IWrappedNativeToken","name":"_wrappedNativeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EthTransferFailed","type":"error"},{"inputs":[],"name":"IncorrectEthAmount","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"NotAllowedToInvalidateOrder","type":"error"},{"inputs":[],"name":"NotAllowedZeroSellAmount","type":"error"},{"inputs":[],"name":"OrderIsAlreadyExpired","type":"error"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"name":"OrderIsAlreadyOwned","type":"error"},{"inputs":[],"name":"ReceiverMustBeSet","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"orderUid","type":"bytes"}],"name":"OrderInvalidation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"components":[{"internalType":"contract IERC20","name":"sellToken","type":"address"},{"internalType":"contract IERC20","name":"buyToken","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"buyAmount","type":"uint256"},{"internalType":"uint32","name":"validTo","type":"uint32"},{"internalType":"bytes32","name":"appData","type":"bytes32"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"bytes32","name":"kind","type":"bytes32"},{"internalType":"bool","name":"partiallyFillable","type":"bool"},{"internalType":"bytes32","name":"sellTokenBalance","type":"bytes32"},{"internalType":"bytes32","name":"buyTokenBalance","type":"bytes32"}],"indexed":false,"internalType":"struct GPv2Order.Data","name":"order","type":"tuple"},{"components":[{"internalType":"enum ICoWSwapOnchainOrders.OnchainSigningScheme","name":"scheme","type":"uint8"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct ICoWSwapOnchainOrders.OnchainSignature","name":"signature","type":"tuple"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"OrderPlacement","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"orderUid","type":"bytes"},{"indexed":true,"internalType":"address","name":"refunder","type":"address"}],"name":"OrderRefund","type":"event"},{"inputs":[],"name":"cowSwapSettlement","outputs":[{"internalType":"contract ICoWSwapSettlement","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"buyToken","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"buyAmount","type":"uint256"},{"internalType":"bytes32","name":"appData","type":"bytes32"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint32","name":"validTo","type":"uint32"},{"internalType":"bool","name":"partiallyFillable","type":"bool"},{"internalType":"int64","name":"quoteId","type":"int64"}],"internalType":"struct EthFlowOrder.Data","name":"order","type":"tuple"}],"name":"createOrder","outputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"buyToken","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"buyAmount","type":"uint256"},{"internalType":"bytes32","name":"appData","type":"bytes32"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint32","name":"validTo","type":"uint32"},{"internalType":"bool","name":"partiallyFillable","type":"bool"},{"internalType":"int64","name":"quoteId","type":"int64"}],"internalType":"struct EthFlowOrder.Data","name":"order","type":"tuple"}],"name":"invalidateOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IERC20","name":"buyToken","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"buyAmount","type":"uint256"},{"internalType":"bytes32","name":"appData","type":"bytes32"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint32","name":"validTo","type":"uint32"},{"internalType":"bool","name":"partiallyFillable","type":"bool"},{"internalType":"int64","name":"quoteId","type":"int64"}],"internalType":"struct EthFlowOrder.Data[]","name":"orderArray","type":"tuple[]"}],"name":"invalidateOrdersIgnoringNotAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"orderHash","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"orders","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint32","name":"validTo","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unwrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wrap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrapAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wrappedNativeToken","outputs":[{"internalType":"contract IWrappedNativeToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e06040523480156200001157600080fd5b5060405162001b2a38038062001b2a83398101604081905262000034916200021e565b816200004b816200015260201b6200089b1760201c565b608052506001600160a01b0380831660a081905290821660c081905260408051634daa966160e11b81529051919263095ea7b3929091639b552cc291600480830192602092919082900301816000875af1158015620000ae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000d491906200025d565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260001960248201526044016020604051808303816000875af115801562000123573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000149919062000284565b505050620002a8565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f6c85c0337eba1661327f94f3bf46c8a7f9311a563f4d5c948362567f5d8ed60c918101919091527ff9446b8e937d86f0bc87cac73923491692b123ca5f8761908494703758206adf606082015246608082018190526001600160a01b03831660a083015260009160c00160405160208183030381529060405280519060200120915050919050565b6001600160a01b03811681146200021b57600080fd5b50565b600080604083850312156200023257600080fd5b82516200023f8162000205565b6020840151909250620002528162000205565b809150509250929050565b6000602082840312156200027057600080fd5b81516200027d8162000205565b9392505050565b6000602082840312156200029757600080fd5b815180151581146200027d57600080fd5b60805160a05160c0516118216200030960003960008181610129015281816105ff015281816107ad0152818161082501528181610c3301526110310152600081816102ce0152610f4b015260008181610bf70152610cd901526118216000f3fe6080604052600436106100b55760003560e01c80637bc41b9611610069578063de0e9a3e1161004e578063de0e9a3e1461027c578063ea598cb01461029c578063ec30bb88146102bc57600080fd5b80637bc41b96146101c85780639c3f1e90146101e857600080fd5b8063322bba211161009a578063322bba21146101705780634c84c1c8146101915780634cb76498146101a857600080fd5b80631626ba7e146100c157806317fcb39b1461011757600080fd5b366100bc57005b600080fd5b3480156100cd57600080fd5b506100e16100dc36600461126e565b6102f0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b34801561012357600080fd5b5061014b7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010e565b61018361017e36600461132b565b6103de565b60405190815260200161010e565b34801561019d57600080fd5b506101a6610720565b005b3480156101b457600080fd5b506101a66101c3366004611344565b61072b565b3480156101d457600080fd5b506101a66101e336600461132b565b610770565b3480156101f457600080fd5b5061024b6102033660046113ba565b60006020819052908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835263ffffffff90911660208301520161010e565b34801561028857600080fd5b506101a66102973660046113ba565b61077e565b3480156102a857600080fd5b506101a66102b73660046113ba565b610821565b3480156102c857600080fd5b5061014b7f000000000000000000000000000000000000000000000000000000000000000081565b60008281526020818152604080832081518083019092525473ffffffffffffffffffffffffffffffffffffffff81168083527401000000000000000000000000000000000000000090910463ffffffff1692820192909252901580159061036f5750805173ffffffffffffffffffffffffffffffffffffffff90811614155b8015610385575042816020015163ffffffff1610155b156103b357507f1626ba7e0000000000000000000000000000000000000000000000000000000090506103d8565b507fffffffff0000000000000000000000000000000000000000000000000000000090505b92915050565b60006103f260a08301356040840135611402565b341461042a576040517f8b6ebb4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160400135600003610468576040517feaec5c9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4261047960e0840160c0850161142e565b63ffffffff1610156104b7576040517f89bb260100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152338152600090602081016104db60e0860160c0870161142e565b63ffffffff169052604080518082019091529091506000908082815260200130604051602001610536919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290529050600061057c61012086016101008701611462565b6020808501516040516105c393920160c09290921b825260e01b7fffffffff00000000000000000000000000000000000000000000000000000000166008820152600c0190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052835190915061063a906106337f000000000000000000000000000000000000000000000000000000000000000061062d368a90038a018a6114b1565b9061095b565b8484610b2a565b60008181526020819052604090205490945073ffffffffffffffffffffffffffffffffffffffff16156106a1576040517f56a1d2b2000000000000000000000000000000000000000000000000000000008152600481018590526024015b60405180910390fd5b505060008281526020818152604090912082518154929093015163ffffffff1674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff90931692909217179055919050565b61072947610821565b565b60005b8181101561076b5761075983838381811061074b5761074b61154b565b905061012002016000610c2c565b806107638161157a565b91505061072e565b505050565b61077b816001610c2c565b50565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561080657600080fd5b505af115801561081a573d6000803e3d6000fd5b5050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461081a576040519150601f19603f3d011682016040523d82523d6000602084013e61081a565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f6c85c0337eba1661327f94f3bf46c8a7f9311a563f4d5c948362567f5d8ed60c918101919091527ff9446b8e937d86f0bc87cac73923491692b123ca5f8761908494703758206adf6060820152466080820181905273ffffffffffffffffffffffffffffffffffffffff831660a083015260009160c00160405160208183030381529060405280519060200120915050919050565b604080516101808101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082018190526101008201819052610120820181905261014082018190526101608201529083015173ffffffffffffffffffffffffffffffffffffffff16610a0a576040517fefc9ccdf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518061018001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001846000015173ffffffffffffffffffffffffffffffffffffffff168152602001846020015173ffffffffffffffffffffffffffffffffffffffff168152602001846040015181526020018460600151815260200163ffffffff80168152602001846080015181526020018460a0015181526020017ff3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee34677581526020018460e00151151581526020017f5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc981526020017f5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc9815250905092915050565b60008473ffffffffffffffffffffffffffffffffffffffff167fcf5f9de2984132265203b5c335b25727702ca77262ff622e136baa7362bf1da9858585604051610b7693929190611676565b60405180910390a25050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a0822091526040517f190100000000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006002820152602281019190915260429020919050565b6000610c617f000000000000000000000000000000000000000000000000000000000000000061062d368690038601866114b1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a082209152604080517f190100000000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600282015260228101929092526042909120600081815260208181529083902083518085019094525473ffffffffffffffffffffffffffffffffffffffff8082168086527401000000000000000000000000000000000000000090920463ffffffff1692850183905294955091934290911015911480610d8d5750815173ffffffffffffffffffffffffffffffffffffffff16155b80610db75750808015610db75750815173ffffffffffffffffffffffffffffffffffffffff163314155b15610dff578415610df7576040517ff8cc70ce00000000000000000000000000000000000000000000000000000000815260048101849052602401610698565b505050505050565b60008381526020818152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff1790558051603880825260608201909252918201818036833750505060a0860151909150610e7a90829086903090611149565b8115610ebc577fb8bad102ac8bbacfef31ff1c906ec6d951c230b4dce750bb0376b812ad35852a81604051610eaf9190611790565b60405180910390a1610f0b565b3373ffffffffffffffffffffffffffffffffffffffff167f195271068a288191e4b265c641a56b9832919f69e9e7d6c2f31ba40278aeb85a82604051610f029190611790565b60405180910390a25b6040517f2479fb6e00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690632479fb6e90610f80908590600401611790565b6020604051808303816000875af1158015610f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc391906117a3565b90506000808760600151838960e001510281610fe157610fe16117bc565b048860e00151039050808389606001510301915050804710156110a4576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815247820360048201819052907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561108a57600080fd5b505af115801561109e573d6000803e3d6000fd5b50505050505b845160405160009173ffffffffffffffffffffffffffffffffffffffff169083908381818185875af1925050503d80600081146110fd576040519150601f19603f3d011682016040523d82523d6000602084013e611102565b606091505b505090508061113d576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b60388451146111b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f475076323a2075696420627566666572206f766572666c6f77000000000000006044820152606401610698565b60388401526034830152602090910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715611219576112196111c6565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611266576112666111c6565b604052919050565b6000806040838503121561128157600080fd5b8235915060208084013567ffffffffffffffff808211156112a157600080fd5b818601915086601f8301126112b557600080fd5b8135818111156112c7576112c76111c6565b6112f7847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161121f565b9150808252878482850101111561130d57600080fd5b80848401858401376000848284010152508093505050509250929050565b6000610120828403121561133e57600080fd5b50919050565b6000806020838503121561135757600080fd5b823567ffffffffffffffff8082111561136f57600080fd5b818501915085601f83011261138357600080fd5b81358181111561139257600080fd5b866020610120830285010111156113a857600080fd5b60209290920196919550909350505050565b6000602082840312156113cc57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103d8576103d86113d3565b803563ffffffff8116811461142957600080fd5b919050565b60006020828403121561144057600080fd5b61144982611415565b9392505050565b8035600781900b811461142957600080fd5b60006020828403121561147457600080fd5b61144982611450565b803573ffffffffffffffffffffffffffffffffffffffff8116811461142957600080fd5b8035801515811461142957600080fd5b600061012082840312156114c457600080fd5b6114cc6111f5565b6114d58361147d565b81526114e36020840161147d565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015261151c60c08401611415565b60c082015261152d60e084016114a1565b60e0820152610100611540818501611450565b908201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115ab576115ab6113d3565b5060010190565b6000815180845260005b818110156115d8576020818501810151868301820152016115bc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6000815160028110611651577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8084525060208201516040602085015261166e60408501826115b2565b949350505050565b835173ffffffffffffffffffffffffffffffffffffffff16815260006101c060208601516116bc602085018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408601516116e4604085018273ffffffffffffffffffffffffffffffffffffffff169052565b50606086015160608401526080860151608084015260a086015161171060a085018263ffffffff169052565b5060c086015160c084015260e086015160e0840152610100808701518185015250610120808701516117458286018215159052565b505061014086810151908401526101608087015190840152610180830181905261177181840186611616565b90508281036101a084015261178681856115b2565b9695505050505050565b60208152600061144960208301846115b2565b6000602082840312156117b557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea2646970667358221220dd6ac68dca08d6be1c4da0e828b663868839c2a8d206f54f6cae8f64c576247564736f6c634300081000330000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab41000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Deployed Bytecode
0x6080604052600436106100b55760003560e01c80637bc41b9611610069578063de0e9a3e1161004e578063de0e9a3e1461027c578063ea598cb01461029c578063ec30bb88146102bc57600080fd5b80637bc41b96146101c85780639c3f1e90146101e857600080fd5b8063322bba211161009a578063322bba21146101705780634c84c1c8146101915780634cb76498146101a857600080fd5b80631626ba7e146100c157806317fcb39b1461011757600080fd5b366100bc57005b600080fd5b3480156100cd57600080fd5b506100e16100dc36600461126e565b6102f0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b34801561012357600080fd5b5061014b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010e565b61018361017e36600461132b565b6103de565b60405190815260200161010e565b34801561019d57600080fd5b506101a6610720565b005b3480156101b457600080fd5b506101a66101c3366004611344565b61072b565b3480156101d457600080fd5b506101a66101e336600461132b565b610770565b3480156101f457600080fd5b5061024b6102033660046113ba565b60006020819052908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835263ffffffff90911660208301520161010e565b34801561028857600080fd5b506101a66102973660046113ba565b61077e565b3480156102a857600080fd5b506101a66102b73660046113ba565b610821565b3480156102c857600080fd5b5061014b7f0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4181565b60008281526020818152604080832081518083019092525473ffffffffffffffffffffffffffffffffffffffff81168083527401000000000000000000000000000000000000000090910463ffffffff1692820192909252901580159061036f5750805173ffffffffffffffffffffffffffffffffffffffff90811614155b8015610385575042816020015163ffffffff1610155b156103b357507f1626ba7e0000000000000000000000000000000000000000000000000000000090506103d8565b507fffffffff0000000000000000000000000000000000000000000000000000000090505b92915050565b60006103f260a08301356040840135611402565b341461042a576040517f8b6ebb4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160400135600003610468576040517feaec5c9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4261047960e0840160c0850161142e565b63ffffffff1610156104b7576040517f89bb260100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152338152600090602081016104db60e0860160c0870161142e565b63ffffffff169052604080518082019091529091506000908082815260200130604051602001610536919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290529050600061057c61012086016101008701611462565b6020808501516040516105c393920160c09290921b825260e01b7fffffffff00000000000000000000000000000000000000000000000000000000166008820152600c0190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052835190915061063a906106337f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261062d368a90038a018a6114b1565b9061095b565b8484610b2a565b60008181526020819052604090205490945073ffffffffffffffffffffffffffffffffffffffff16156106a1576040517f56a1d2b2000000000000000000000000000000000000000000000000000000008152600481018590526024015b60405180910390fd5b505060008281526020818152604090912082518154929093015163ffffffff1674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff90931692909217179055919050565b61072947610821565b565b60005b8181101561076b5761075983838381811061074b5761074b61154b565b905061012002016000610c2c565b806107638161157a565b91505061072e565b505050565b61077b816001610c2c565b50565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561080657600080fd5b505af115801561081a573d6000803e3d6000fd5b5050505050565b60007f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461081a576040519150601f19603f3d011682016040523d82523d6000602084013e61081a565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f6c85c0337eba1661327f94f3bf46c8a7f9311a563f4d5c948362567f5d8ed60c918101919091527ff9446b8e937d86f0bc87cac73923491692b123ca5f8761908494703758206adf6060820152466080820181905273ffffffffffffffffffffffffffffffffffffffff831660a083015260009160c00160405160208183030381529060405280519060200120915050919050565b604080516101808101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082018190526101008201819052610120820181905261014082018190526101608201529083015173ffffffffffffffffffffffffffffffffffffffff16610a0a576040517fefc9ccdf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518061018001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001846000015173ffffffffffffffffffffffffffffffffffffffff168152602001846020015173ffffffffffffffffffffffffffffffffffffffff168152602001846040015181526020018460600151815260200163ffffffff80168152602001846080015181526020018460a0015181526020017ff3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee34677581526020018460e00151151581526020017f5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc981526020017f5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc9815250905092915050565b60008473ffffffffffffffffffffffffffffffffffffffff167fcf5f9de2984132265203b5c335b25727702ca77262ff622e136baa7362bf1da9858585604051610b7693929190611676565b60405180910390a25050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a0822091526040517f190100000000000000000000000000000000000000000000000000000000000081527fc078f884a2676e1345748b1feace7b0abee5d00ecadb6e574dcdd109a63e89436002820152602281019190915260429020919050565b6000610c617f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261062d368690038601866114b1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a082209152604080517f190100000000000000000000000000000000000000000000000000000000000081527fc078f884a2676e1345748b1feace7b0abee5d00ecadb6e574dcdd109a63e8943600282015260228101929092526042909120600081815260208181529083902083518085019094525473ffffffffffffffffffffffffffffffffffffffff8082168086527401000000000000000000000000000000000000000090920463ffffffff1692850183905294955091934290911015911480610d8d5750815173ffffffffffffffffffffffffffffffffffffffff16155b80610db75750808015610db75750815173ffffffffffffffffffffffffffffffffffffffff163314155b15610dff578415610df7576040517ff8cc70ce00000000000000000000000000000000000000000000000000000000815260048101849052602401610698565b505050505050565b60008381526020818152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff1790558051603880825260608201909252918201818036833750505060a0860151909150610e7a90829086903090611149565b8115610ebc577fb8bad102ac8bbacfef31ff1c906ec6d951c230b4dce750bb0376b812ad35852a81604051610eaf9190611790565b60405180910390a1610f0b565b3373ffffffffffffffffffffffffffffffffffffffff167f195271068a288191e4b265c641a56b9832919f69e9e7d6c2f31ba40278aeb85a82604051610f029190611790565b60405180910390a25b6040517f2479fb6e00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab411690632479fb6e90610f80908590600401611790565b6020604051808303816000875af1158015610f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc391906117a3565b90506000808760600151838960e001510281610fe157610fe16117bc565b048860e00151039050808389606001510301915050804710156110a4576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815247820360048201819052907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561108a57600080fd5b505af115801561109e573d6000803e3d6000fd5b50505050505b845160405160009173ffffffffffffffffffffffffffffffffffffffff169083908381818185875af1925050503d80600081146110fd576040519150601f19603f3d011682016040523d82523d6000602084013e611102565b606091505b505090508061113d576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b60388451146111b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f475076323a2075696420627566666572206f766572666c6f77000000000000006044820152606401610698565b60388401526034830152602090910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715611219576112196111c6565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611266576112666111c6565b604052919050565b6000806040838503121561128157600080fd5b8235915060208084013567ffffffffffffffff808211156112a157600080fd5b818601915086601f8301126112b557600080fd5b8135818111156112c7576112c76111c6565b6112f7847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161121f565b9150808252878482850101111561130d57600080fd5b80848401858401376000848284010152508093505050509250929050565b6000610120828403121561133e57600080fd5b50919050565b6000806020838503121561135757600080fd5b823567ffffffffffffffff8082111561136f57600080fd5b818501915085601f83011261138357600080fd5b81358181111561139257600080fd5b866020610120830285010111156113a857600080fd5b60209290920196919550909350505050565b6000602082840312156113cc57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103d8576103d86113d3565b803563ffffffff8116811461142957600080fd5b919050565b60006020828403121561144057600080fd5b61144982611415565b9392505050565b8035600781900b811461142957600080fd5b60006020828403121561147457600080fd5b61144982611450565b803573ffffffffffffffffffffffffffffffffffffffff8116811461142957600080fd5b8035801515811461142957600080fd5b600061012082840312156114c457600080fd5b6114cc6111f5565b6114d58361147d565b81526114e36020840161147d565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015261151c60c08401611415565b60c082015261152d60e084016114a1565b60e0820152610100611540818501611450565b908201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115ab576115ab6113d3565b5060010190565b6000815180845260005b818110156115d8576020818501810151868301820152016115bc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6000815160028110611651577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8084525060208201516040602085015261166e60408501826115b2565b949350505050565b835173ffffffffffffffffffffffffffffffffffffffff16815260006101c060208601516116bc602085018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408601516116e4604085018273ffffffffffffffffffffffffffffffffffffffff169052565b50606086015160608401526080860151608084015260a086015161171060a085018263ffffffff169052565b5060c086015160c084015260e086015160e0840152610100808701518185015250610120808701516117458286018215159052565b505061014086810151908401526101608087015190840152610180830181905261177181840186611616565b90508281036101a084015261178681856115b2565b9695505050505050565b60208152600061144960208301846115b2565b6000602082840312156117b557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea2646970667358221220dd6ac68dca08d6be1c4da0e828b663868839c2a8d206f54f6cae8f64c576247564736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab41000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
-----Decoded View---------------
Arg [0] : _cowSwapSettlement (address): 0x9008D19f58AAbD9eD0D60971565AA8510560ab41
Arg [1] : _wrappedNativeToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab41
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Loading...
Loading
Loading...
Loading
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.