Source Code
Overview
ETH Balance
0 ETH
Token Holdings
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 2,925 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Create Order | 7236178 | 8 hrs ago | IN | 0.02 ETH | 0.00015313 | ||||
Create Order | 7235954 | 9 hrs ago | IN | 0.1 ETH | 0.0001608 | ||||
Create Order | 7231113 | 26 hrs ago | IN | 0.04 ETH | 0.00001826 | ||||
Create Order | 7225790 | 45 hrs ago | IN | 0.1 ETH | 0.00008809 | ||||
Create Order | 7225757 | 45 hrs ago | IN | 0.4 ETH | 0.00009195 | ||||
Create Order | 7225750 | 45 hrs ago | IN | 0.5 ETH | 0.00009241 | ||||
Create Order | 7221446 | 2 days ago | IN | 0.05 ETH | 0.0006185 | ||||
Create Order | 7216003 | 3 days ago | IN | 0.1 ETH | 0.00062731 | ||||
Create Order | 7215957 | 3 days ago | IN | 0.01 ETH | 0.00042312 | ||||
Create Order | 7215909 | 3 days ago | IN | 0.00445 ETH | 0.00056941 | ||||
Create Order | 7215614 | 3 days ago | IN | 0.5 ETH | 0.00108096 | ||||
Create Order | 7213193 | 3 days ago | IN | 0.099806 ETH | 0.0001365 | ||||
Create Order | 7213097 | 3 days ago | IN | 0.0903783 ETH | 0.00011697 | ||||
Create Order | 7212378 | 3 days ago | IN | 0.005 ETH | 0.00008492 | ||||
Invalidate Order... | 7212368 | 3 days ago | IN | 0 ETH | 0.00000078 | ||||
Create Order | 7212225 | 3 days ago | IN | 0.0012 ETH | 0.00008505 | ||||
Create Order | 7212210 | 3 days ago | IN | 0.028968 ETH | 0.00008519 | ||||
Create Order | 7212153 | 3 days ago | IN | 0.25 ETH | 0.00000125 | ||||
Create Order | 7209918 | 4 days ago | IN | 0.01 ETH | 0.00021867 | ||||
Create Order | 7204033 | 5 days ago | IN | 0.0508039 ETH | 0.00019332 | ||||
Create Order | 7196959 | 6 days ago | IN | 0.4 ETH | 0.0006282 | ||||
Create Order | 7196646 | 6 days ago | IN | 0.05343534 ETH | 0.00122857 | ||||
Invalidate Order | 7196641 | 6 days ago | IN | 0 ETH | 0.00124813 | ||||
Create Order | 7196586 | 6 days ago | IN | 0.05 ETH | 0.00068487 | ||||
Create Order | 7196014 | 6 days ago | IN | 0.005 ETH | 0.0005341 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
7236180 | 8 hrs ago | 0.02 ETH | ||||
7235956 | 9 hrs ago | 0.1 ETH | ||||
7231115 | 26 hrs ago | 0.04 ETH | ||||
7225792 | 45 hrs ago | 0.1 ETH | ||||
7225759 | 45 hrs ago | 0.4 ETH | ||||
7225752 | 45 hrs ago | 0.5 ETH | ||||
7221448 | 2 days ago | 0.05 ETH | ||||
7216005 | 3 days ago | 0.1 ETH | ||||
7215959 | 3 days ago | 0.01 ETH | ||||
7215911 | 3 days ago | 0.00445 ETH | ||||
7215616 | 3 days ago | 0.5 ETH | ||||
7213195 | 3 days ago | 0.099806 ETH | ||||
7213099 | 3 days ago | 0.0903783 ETH | ||||
7212380 | 3 days ago | 0.005 ETH | ||||
7212368 | 3 days ago | 0.0012 ETH | ||||
7212213 | 3 days ago | 0.028968 ETH | ||||
7212158 | 3 days ago | 0.25 ETH | ||||
7209920 | 4 days ago | 0.01 ETH | ||||
7204034 | 5 days ago | 0.0508039 ETH | ||||
7196963 | 6 days ago | 0.4 ETH | ||||
7196650 | 6 days ago | 0.05343534 ETH | ||||
7196641 | 6 days ago | 0.05 ETH | ||||
7196070 | 6 days ago | 0.005 ETH | ||||
7195242 | 6 days ago | 0.1 ETH | ||||
7195240 | 6 days ago | 0.1 ETH |
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x2671994c...87d42C69f The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
CoWSwapEthFlow
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
london 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 "../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; /// @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 "../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/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; 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 ); }
// 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 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 ) ); } }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
[{"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"}]
Deployed Bytecode
0x6080604052600436106100b55760003560e01c80637bc41b9611610069578063de0e9a3e1161004e578063de0e9a3e1461027c578063ea598cb01461029c578063ec30bb88146102bc57600080fd5b80637bc41b96146101c85780639c3f1e90146101e857600080fd5b8063322bba211161009a578063322bba21146101705780634c84c1c8146101915780634cb76498146101a857600080fd5b80631626ba7e146100c157806317fcb39b1461011757600080fd5b366100bc57005b600080fd5b3480156100cd57600080fd5b506100e16100dc36600461126e565b6102f0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020015b60405180910390f35b34801561012357600080fd5b5061014b7f000000000000000000000000fff9976782d46cc05630d1f6ebab18b2324d6b1481565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010e565b61018361017e36600461132b565b6103de565b60405190815260200161010e565b34801561019d57600080fd5b506101a6610720565b005b3480156101b457600080fd5b506101a66101c3366004611344565b61072b565b3480156101d457600080fd5b506101a66101e336600461132b565b610770565b3480156101f457600080fd5b5061024b6102033660046113ba565b60006020819052908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835263ffffffff90911660208301520161010e565b34801561028857600080fd5b506101a66102973660046113ba565b61077e565b3480156102a857600080fd5b506101a66102b73660046113ba565b610821565b3480156102c857600080fd5b5061014b7f0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab4181565b60008281526020818152604080832081518083019092525473ffffffffffffffffffffffffffffffffffffffff81168083527401000000000000000000000000000000000000000090910463ffffffff1692820192909252901580159061036f5750805173ffffffffffffffffffffffffffffffffffffffff90811614155b8015610385575042816020015163ffffffff1610155b156103b357507f1626ba7e0000000000000000000000000000000000000000000000000000000090506103d8565b507fffffffff0000000000000000000000000000000000000000000000000000000090505b92915050565b60006103f260a08301356040840135611402565b341461042a576040517f8b6ebb4d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160400135600003610468576040517feaec5c9d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4261047960e0840160c0850161142e565b63ffffffff1610156104b7576040517f89bb260100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152338152600090602081016104db60e0860160c0870161142e565b63ffffffff169052604080518082019091529091506000908082815260200130604051602001610536919060609190911b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815260140190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905290529050600061057c61012086016101008701611462565b6020808501516040516105c393920160c09290921b825260e01b7fffffffff00000000000000000000000000000000000000000000000000000000166008820152600c0190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052835190915061063a906106337f000000000000000000000000fff9976782d46cc05630d1f6ebab18b2324d6b1461062d368a90038a018a6114b1565b9061095b565b8484610b2a565b60008181526020819052604090205490945073ffffffffffffffffffffffffffffffffffffffff16156106a1576040517f56a1d2b2000000000000000000000000000000000000000000000000000000008152600481018590526024015b60405180910390fd5b505060008281526020818152604090912082518154929093015163ffffffff1674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff90931692909217179055919050565b61072947610821565b565b60005b8181101561076b5761075983838381811061074b5761074b61154b565b905061012002016000610c2c565b806107638161157a565b91505061072e565b505050565b61077b816001610c2c565b50565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000fff9976782d46cc05630d1f6ebab18b2324d6b1473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561080657600080fd5b505af115801561081a573d6000803e3d6000fd5b5050505050565b60007f000000000000000000000000fff9976782d46cc05630d1f6ebab18b2324d6b1473ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461081a576040519150601f19603f3d011682016040523d82523d6000602084013e61081a565b604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f6c85c0337eba1661327f94f3bf46c8a7f9311a563f4d5c948362567f5d8ed60c918101919091527ff9446b8e937d86f0bc87cac73923491692b123ca5f8761908494703758206adf6060820152466080820181905273ffffffffffffffffffffffffffffffffffffffff831660a083015260009160c00160405160208183030381529060405280519060200120915050919050565b604080516101808101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c0820181905260e082018190526101008201819052610120820181905261014082018190526101608201529083015173ffffffffffffffffffffffffffffffffffffffff16610a0a576040517fefc9ccdf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518061018001604052808373ffffffffffffffffffffffffffffffffffffffff168152602001846000015173ffffffffffffffffffffffffffffffffffffffff168152602001846020015173ffffffffffffffffffffffffffffffffffffffff168152602001846040015181526020018460600151815260200163ffffffff80168152602001846080015181526020018460a0015181526020017ff3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee34677581526020018460e00151151581526020017f5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc981526020017f5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc9815250905092915050565b60008473ffffffffffffffffffffffffffffffffffffffff167fcf5f9de2984132265203b5c335b25727702ca77262ff622e136baa7362bf1da9858585604051610b7693929190611676565b60405180910390a25050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a0822091526040517f190100000000000000000000000000000000000000000000000000000000000081527fdaee378bd0eb30ddf479272accf91761e697bc00e067a268f95f1d2732ed230b6002820152602281019190915260429020919050565b6000610c617f000000000000000000000000fff9976782d46cc05630d1f6ebab18b2324d6b1461062d368690038601866114b1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0810180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a082209152604080517f190100000000000000000000000000000000000000000000000000000000000081527fdaee378bd0eb30ddf479272accf91761e697bc00e067a268f95f1d2732ed230b600282015260228101929092526042909120600081815260208181529083902083518085019094525473ffffffffffffffffffffffffffffffffffffffff8082168086527401000000000000000000000000000000000000000090920463ffffffff1692850183905294955091934290911015911480610d8d5750815173ffffffffffffffffffffffffffffffffffffffff16155b80610db75750808015610db75750815173ffffffffffffffffffffffffffffffffffffffff163314155b15610dff578415610df7576040517ff8cc70ce00000000000000000000000000000000000000000000000000000000815260048101849052602401610698565b505050505050565b60008381526020818152604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff1790558051603880825260608201909252918201818036833750505060a0860151909150610e7a90829086903090611149565b8115610ebc577fb8bad102ac8bbacfef31ff1c906ec6d951c230b4dce750bb0376b812ad35852a81604051610eaf9190611790565b60405180910390a1610f0b565b3373ffffffffffffffffffffffffffffffffffffffff167f195271068a288191e4b265c641a56b9832919f69e9e7d6c2f31ba40278aeb85a82604051610f029190611790565b60405180910390a25b6040517f2479fb6e00000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab411690632479fb6e90610f80908590600401611790565b6020604051808303816000875af1158015610f9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc391906117a3565b90506000808760600151838960e001510281610fe157610fe16117bc565b048860e00151039050808389606001510301915050804710156110a4576040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815247820360048201819052907f000000000000000000000000fff9976782d46cc05630d1f6ebab18b2324d6b1473ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561108a57600080fd5b505af115801561109e573d6000803e3d6000fd5b50505050505b845160405160009173ffffffffffffffffffffffffffffffffffffffff169083908381818185875af1925050503d80600081146110fd576040519150601f19603f3d011682016040523d82523d6000602084013e611102565b606091505b505090508061113d576040517f6d963f8800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050505050505050565b60388451146111b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f475076323a2075696420627566666572206f766572666c6f77000000000000006044820152606401610698565b60388401526034830152602090910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610120810167ffffffffffffffff81118282101715611219576112196111c6565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611266576112666111c6565b604052919050565b6000806040838503121561128157600080fd5b8235915060208084013567ffffffffffffffff808211156112a157600080fd5b818601915086601f8301126112b557600080fd5b8135818111156112c7576112c76111c6565b6112f7847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161121f565b9150808252878482850101111561130d57600080fd5b80848401858401376000848284010152508093505050509250929050565b6000610120828403121561133e57600080fd5b50919050565b6000806020838503121561135757600080fd5b823567ffffffffffffffff8082111561136f57600080fd5b818501915085601f83011261138357600080fd5b81358181111561139257600080fd5b866020610120830285010111156113a857600080fd5b60209290920196919550909350505050565b6000602082840312156113cc57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156103d8576103d86113d3565b803563ffffffff8116811461142957600080fd5b919050565b60006020828403121561144057600080fd5b61144982611415565b9392505050565b8035600781900b811461142957600080fd5b60006020828403121561147457600080fd5b61144982611450565b803573ffffffffffffffffffffffffffffffffffffffff8116811461142957600080fd5b8035801515811461142957600080fd5b600061012082840312156114c457600080fd5b6114cc6111f5565b6114d58361147d565b81526114e36020840161147d565b602082015260408301356040820152606083013560608201526080830135608082015260a083013560a082015261151c60c08401611415565b60c082015261152d60e084016114a1565b60e0820152610100611540818501611450565b908201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036115ab576115ab6113d3565b5060010190565b6000815180845260005b818110156115d8576020818501810151868301820152016115bc565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b6000815160028110611651577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8084525060208201516040602085015261166e60408501826115b2565b949350505050565b835173ffffffffffffffffffffffffffffffffffffffff16815260006101c060208601516116bc602085018273ffffffffffffffffffffffffffffffffffffffff169052565b5060408601516116e4604085018273ffffffffffffffffffffffffffffffffffffffff169052565b50606086015160608401526080860151608084015260a086015161171060a085018263ffffffff169052565b5060c086015160c084015260e086015160e0840152610100808701518185015250610120808701516117458286018215159052565b505061014086810151908401526101608087015190840152610180830181905261177181840186611616565b90508281036101a084015261178681856115b2565b9695505050505050565b60208152600061144960208301846115b2565b6000602082840312156117b557600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fdfea2646970667358221220dd6ac68dca08d6be1c4da0e828b663868839c2a8d206f54f6cae8f64c576247564736f6c63430008100033
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.