ETH Price: $2,085.41 (-1.66%)

Contract

0xd6992aA2Aaa87802d0104e8c4b4DFaBE6F434fF7
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Advanced mode:
Parent Transaction Hash Method Block
From
To
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SecondarySwap

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
paris EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

import {ISecondarySwap} from "../interfaces/ISecondarySwap.sol";
import {IERC20Z} from "../interfaces/IERC20Z.sol";
import {ISwapRouter} from "../interfaces/uniswap/ISwapRouter.sol";
import {IWETH} from "../interfaces/IWETH.sol";

contract SecondarySwap is ISecondarySwap, ReentrancyGuard, ERC1155Holder {
    uint256 internal constant ONE_ERC_20 = 1e18;

    IWETH public immutable WETH;
    ISwapRouter public immutable swapRouter;
    uint24 public immutable uniswapFee;

    constructor(IWETH weth_, ISwapRouter swapRouter_, uint24 uniswapFee_) {
        WETH = weth_;
        swapRouter = swapRouter_;
        uniswapFee = uniswapFee_;
    }

    /// @notice ETH -> WETH -> ERC20Z -> ERC1155
    function buy1155(
        address erc20zAddress,
        uint256 num1155ToBuy,
        address payable recipient,
        address payable excessRefundRecipient,
        uint256 maxEthToSpend,
        uint160 sqrtPriceLimitX96
    ) external payable nonReentrant {
        // Ensure the recipient address is valid
        if (recipient == address(0)) {
            revert InvalidRecipient();
        }

        // Get the amount of ETH sent
        uint256 amountETHIn = msg.value;

        // Ensure ETH is sent with the transaction
        if (amountETHIn == 0) {
            revert NoETHSent();
        }

        // Convert ETH to WETH
        WETH.deposit{value: amountETHIn}();

        // Approve the swap router to spend WETH
        WETH.approve(address(swapRouter), amountETHIn);

        // Calculate the expected amount of ERC20Z
        uint256 expectedAmountERC20Out = num1155ToBuy * ONE_ERC_20;

        ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams({
            tokenIn: address(WETH),
            tokenOut: erc20zAddress,
            fee: uniswapFee,
            recipient: address(this),
            amountOut: expectedAmountERC20Out,
            amountInMaximum: maxEthToSpend,
            sqrtPriceLimitX96: sqrtPriceLimitX96
        });

        // Execute the swap and get the amount of WETH used
        uint256 amountWethUsed = swapRouter.exactOutputSingle(params);

        // Ensure that the expected amount of ERC20Z was received
        if (IERC20Z(erc20zAddress).balanceOf(address(this)) < expectedAmountERC20Out) {
            revert ERC20ZMinimumAmountNotReceived();
        }

        // Approve the ERC20Z tokens to be converted to ERC1155s
        IERC20Z(erc20zAddress).approve(erc20zAddress, expectedAmountERC20Out);

        // Convert ERC20Z to ERC1155
        IERC20Z(erc20zAddress).unwrap(expectedAmountERC20Out, recipient);

        // If there is any excess WETH:
        if (amountWethUsed < amountETHIn) {
            // Convert the excess WETH to ETH
            WETH.withdraw(amountETHIn - amountWethUsed);

            // Refund the excess ETH to the recipient
            Address.sendValue(excessRefundRecipient, msg.value - amountWethUsed);
        }

        emit SecondaryBuy(msg.sender, recipient, erc20zAddress, amountWethUsed, num1155ToBuy);
    }

    /// @notice ERC1155 -> ERC20Z -> WETH -> ETH
    function sell1155(
        address erc20zAddress,
        uint256 num1155ToSell,
        address payable recipient,
        uint256 minEthToAcquire,
        uint160 sqrtPriceLimitX96
    ) external nonReentrant {
        // Ensure the recipient is valid
        if (recipient == address(0)) {
            revert InvalidRecipient();
        }

        // Get the ERC1155 token info from ERC20Z
        IERC20Z.TokenInfo memory tokenInfo = IERC20Z(erc20zAddress).tokenInfo();

        // Transfer ERC1155 tokens from sender to this contract and wrap them
        IERC1155(tokenInfo.collection).safeTransferFrom(msg.sender, erc20zAddress, tokenInfo.tokenId, num1155ToSell, abi.encode(address(this)));

        // Calculate expected amount of ERC20Z
        uint256 expectedAmountERC20In = num1155ToSell * 1e18;

        // Ensure that the conversion was successful
        if (IERC20Z(erc20zAddress).balanceOf(address(this)) < expectedAmountERC20In) {
            revert ERC20ZEquivalentAmountNotConverted();
        }

        // Approve swap router to spend ERC20Z tokens
        IERC20Z(erc20zAddress).approve(address(swapRouter), expectedAmountERC20In);

        // Set up parameters for the swap from ERC20Z to WETH
        ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
            tokenIn: erc20zAddress,
            tokenOut: address(WETH),
            fee: uniswapFee,
            recipient: address(this),
            amountIn: expectedAmountERC20In,
            amountOutMinimum: minEthToAcquire,
            sqrtPriceLimitX96: sqrtPriceLimitX96
        });

        // Execute the swap and receive WETH
        uint256 amountWethOut = swapRouter.exactInputSingle(params);

        // Convert WETH to ETH
        WETH.withdraw(amountWethOut);

        // Transfer ETH to the recipient
        Address.sendValue(recipient, amountWethOut);

        emit SecondarySell(msg.sender, recipient, erc20zAddress, amountWethOut, num1155ToSell);
    }

    receive() external payable {
        if (msg.sender != address(WETH)) {
            revert OnlyWETH();
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the value of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(
        address[] calldata accounts,
        uint256[] calldata ids
    ) external view returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`.
     *
     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens
     * to an untrusted contract, when invoking {onERC1155Received} on the receiver.
     * Ensure to follow the checks-effects-interactions pattern and consider employing
     * reentrancy guards when interacting with untrusted contracts.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `value` amount.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * WARNING: This function can potentially allow a reentrancy attack when transferring tokens
     * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver.
     * Ensure to follow the checks-effects-interactions pattern and consider employing
     * reentrancy guards when interacting with untrusted contracts.
     *
     * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments.
     *
     * Requirements:
     *
     * - `ids` and `values` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/utils/ERC1155Holder.sol)

pragma solidity ^0.8.20;

import {IERC165, ERC165} from "../../../utils/introspection/ERC165.sol";
import {IERC1155Receiver} from "../IERC1155Receiver.sol";

/**
 * @dev Simple implementation of `IERC1155Receiver` that will allow a contract to hold ERC1155 tokens.
 *
 * IMPORTANT: When inheriting this contract, you must include a way to use the received tokens, otherwise they will be
 * stuck.
 */
abstract contract ERC1155Holder is ERC165, IERC1155Receiver {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
    }

    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}

File 6 of 15 : ISecondarySwap.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

/*


             ░░░░░░░░░░░░░░              
        ░░▒▒░░░░░░░░░░░░░░░░░░░░        
      ░░▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░      
    ░░▒▒▒▒░░░░░░░░░░░░░░    ░░░░░░░░    
   ░▓▓▒▒▒▒░░░░░░░░░░░░        ░░░░░░░    
  ░▓▓▓▒▒▒▒░░░░░░░░░░░░        ░░░░░░░░  
  ░▓▓▓▒▒▒▒░░░░░░░░░░░░░░    ░░░░░░░░░░  
  ░▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░  
  ░▓▓▓▓▓▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░  
   ░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░  
    ░░▓▓▓▓▒▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░    
    ░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒░░░░░░░░░▒▒▒▒▒░░    
      ░░▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░      
          ░░▓▓▓▓▓▓▓▓▓▓▓▓▒▒░░░          

               OURS TRULY,


*/

interface ISecondarySwap {
    event SecondaryBuy(address indexed msgSender, address indexed recipient, address indexed erc20zAddress, uint256 amountEthSold, uint256 num1155Purchased);
    event SecondarySell(address indexed msgSender, address indexed recipient, address indexed erc20zAddress, uint256 amountEthPurchased, uint256 num1155Sold);

    error InvalidRecipient();
    error NoETHSent();
    error ERC20ZMinimumAmountNotReceived();
    error ERC20ZEquivalentAmountNotConverted();
    error OnlyWETH();
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

interface IERC20Z is IERC20Metadata {
    /// @notice TokenInfo struct returned by the information function
    struct TokenInfo {
        /// @notice The collection address
        address collection;
        /// @notice The token ID
        uint256 tokenId;
        /// @notice The creator address
        address creator;
    }

    /// @notice Event for when the ERC1155s are directly converted to ERC20Zs
    /// @param erc20z ERC20Z Address
    /// @param amount20z ERC20Z Amount
    /// @param collection Collection address
    /// @param tokenId ID for the ERC1155 token swapped
    /// @param amount1155 Amount of 1155 converted
    /// @param recipient Recipient of the conversion
    event ConvertedTo20z(address indexed erc20z, uint256 amount20z, address collection, uint256 tokenId, uint256 amount1155, address recipient);

    /// @notice Event for when ERC20Zs are directly converted to ERC1155
    /// @param erc20z ERC20Z Address
    /// @param amount20z ERC20Z Amount
    /// @param collection Collection address
    /// @param tokenId ID for the ERC1155 token swapped
    /// @param amount1155 Amount of 1155 converted
    /// @param recipient Recipient of the conversion
    event ConvertedTo1155(address indexed erc20z, uint256 amount20z, address collection, uint256 tokenId, uint256 amount1155, address recipient);

    /// @notice Event for when the secondary market is activated
    /// @param token0 Token 0 for uniswap liquidity
    /// @param amount0 Amount 0 for uniswap liquidity
    /// @param token1 Token 1 for uniswap liquidity
    /// @param amount1 Amount 1 for uniswap liquidity
    /// @param fee Uniswap fee amount
    /// @param positionId ERC721 Position ID for the default liquidity
    /// @param lpLiquidity amount of lp liquidity held by this contract
    /// @param erc20Excess ERC20 excess amount burned
    /// @param erc1155Excess ERC1155 excess amount burned
    event SecondaryMarketActivated(
        address indexed token0,
        uint256 indexed amount0,
        address token1,
        uint256 amount1,
        uint256 fee,
        uint256 positionId,
        uint256 lpLiquidity,
        uint256 erc20Excess,
        uint256 erc1155Excess
    );

    /// @notice Event for when admin mint NFTs are received
    /// @param quantity the amount received
    event ReceivedAdminMintNFTs(uint256 quantity);

    /// @notice Errors when attempts to reactivate
    error AlreadyActivatedCannotReactivate();

    /// @notice ERC1155 Ids do not match values length
    error IDsDoNotMatchValuesLength();

    /// @notice Passing in wrong ERC1155 token id to swap
    error TokenIdNotValidToSwap();

    /// @notice Action sent with ERC1155 data call is not known
    error UnknownReceiveActionDataCall();

    /// @notice Only supports receiving ERC721 Pool NFTs
    error OnlySupportReceivingERC721UniswapPoolNFTs();

    /// @notice Error when trying to swap ERC1155 to ERC20Z without the market being started.
    error SecondaryMarketHasNotYetStarted();

    /// @notice Only supports recieving ERC1155 associated with ERC20Z NFTs.
    error OnlySupportReceivingERC1155AssociatedZoraNFT();

    /// @notice Unauthorized to call this function
    error OnlySaleStrategy();

    /// @notice Pool creation failed
    error PoolCreationFailed();

    /// @notice Params are invalid
    error InvalidParams();

    /// @notice Insufficient balance
    error InsufficientBalance();

    /// @notice Invalid amount of ERC20z tokens
    error InvalidAmount20z();

    /// @notice Invalid ERC20z transfer
    error Invalid20zTransfer();

    /// @notice Recipient address cannot be zero
    error RecipientAddressZero();

    /// @notice Token URI
    function tokenURI() external view returns (string memory);

    /// @notice Token information
    function tokenInfo() external view returns (TokenInfo memory);

    /// @notice Returns the ERC20Z contract URI
    function contractURI() external view returns (string memory);

    /// @notice Token liquidity information getter
    function tokenLiquidityInfo() external view returns (address pool, uint256 initialLiquidityPositionId);

    /// @notice Initialize the ERC20Z token
    /// @param collection The collection address
    /// @param tokenId The token ID
    /// @param name The token name
    /// @param symbol The token symbol
    function initialize(address collection, uint256 tokenId, string memory name, string memory symbol) external returns (address);

    /// @notice Activate the ERC20Z token
    /// @param erc20TotalSupply The total supply of the ERC20 token
    /// @param erc20Reserve The reserve of the ERC20 token
    /// @param erc20Liquidity The liquidity of the ERC20 token
    /// @param erc20Excess The excess of the ERC20 token
    /// @param erc1155Excess The excess of the ERC1155 token
    function activate(uint256 erc20TotalSupply, uint256 erc20Reserve, uint256 erc20Liquidity, uint256 erc20Excess, uint256 erc1155Excess) external;

    /// @notice Convert 1155 to ERC20z tokens
    /// @param amount1155 The amount of 1155 tokens to convert
    /// @param recipient The recipient address
    function wrap(uint256 amount1155, address recipient) external;

    /// @notice Convert ERC20z to 1155 tokens
    /// @param amount20z The amount of ERC20z tokens to convert
    /// @param recipient The recipient address
    function unwrap(uint256 amount20z, address recipient) external;
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {IUniswapV3SwapCallback} from "./IUniswapV3SwapCallback.sol";

/// @title Router token swapping functionality
/// @notice Functions for swapping tokens via Uniswap V3
interface ISwapRouter is IUniswapV3SwapCallback {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);

    /// @notice Swaps as little as possible of one token for `amountOut` of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

interface IWETH {
    function deposit() external payable;

    function withdraw(uint256 wad) external;

    function approve(address guy, uint256 wad) external returns (bool);

    function transfer(address dst, uint256 wad) external returns (bool);

    function transferFrom(address src, address dst, uint256 wad) external returns (bool);

    function balanceOf(address guy) external view returns (uint256);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

import {IERC165} from "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../../utils/introspection/IERC165.sol";

/**
 * @dev Interface that must be implemented by smart contracts in order to receive
 * ERC-1155 token transfers.
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

/// @title Callback for IUniswapV3PoolActions#swap
/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
interface IUniswapV3SwapCallback {
    /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
    /// @dev In the implementation you must pay the pool tokens owed for the swap.
    /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
    /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.
    /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.
    /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
    function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

Settings
{
  "remappings": [
    "ds-test/=node_modules/ds-test/src/",
    "forge-std/=node_modules/forge-std/src/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@zoralabs/protocol-rewards/=node_modules/@zoralabs/protocol-rewards/",
    "@zoralabs/shared-contracts/=node_modules/@zoralabs/shared-contracts/src/",
    "solady/=node_modules/solady/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IWETH","name":"weth_","type":"address"},{"internalType":"contract ISwapRouter","name":"swapRouter_","type":"address"},{"internalType":"uint24","name":"uniswapFee_","type":"uint24"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"ERC20ZEquivalentAmountNotConverted","type":"error"},{"inputs":[],"name":"ERC20ZMinimumAmountNotReceived","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"NoETHSent","type":"error"},{"inputs":[],"name":"OnlyWETH","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"address","name":"erc20zAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountEthSold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"num1155Purchased","type":"uint256"}],"name":"SecondaryBuy","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"msgSender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"address","name":"erc20zAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountEthPurchased","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"num1155Sold","type":"uint256"}],"name":"SecondarySell","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc20zAddress","type":"address"},{"internalType":"uint256","name":"num1155ToBuy","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"address payable","name":"excessRefundRecipient","type":"address"},{"internalType":"uint256","name":"maxEthToSpend","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"name":"buy1155","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20zAddress","type":"address"},{"internalType":"uint256","name":"num1155ToSell","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"},{"internalType":"uint256","name":"minEthToAcquire","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"name":"sell1155","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapRouter","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapFee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e0346100da57601f61158238819003918201601f19168301916001600160401b038311848410176100df578084926060946040528339810103126100da578051906001600160a01b039081831683036100da57602081015191821682036100da57604001519162ffffff831683036100da57600160005560805260a05260c05260405161148c90816100f6823960805181818160350152818161032d0152818161093e0152610c64015260a0518181816101bd015281816103970152610bc8015260c05181818161045d0152818161099c0152610c9f0152f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe6080604081815260049182361015610083575b50361561001e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016330361005d57005b517f01f180c9000000000000000000000000000000000000000000000000000000008152fd5b600090813560e01c90816301ffc9a7146110435750806355193c95146109c0578063637af4df14610962578063ad5c4648146108f3578063b3836da9146102a2578063bc197c81146101e5578063c31c9c07146101725763f23a6e6103610012573461016f5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261016f5761011b611100565b50610124611123565b506084359067ffffffffffffffff821161016f5750602092610148913691016112aa565b50517ff23a6e61000000000000000000000000000000000000000000000000000000008152f35b80fd5b5090346101e157817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101e1576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5080fd5b503461016f5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261016f5761021d611100565b50610226611123565b5067ffffffffffffffff906044358281116101e1576102489036908601611209565b506064358281116101e1576102609036908601611209565b5060843591821161016f575060209261027b913691016112aa565b50517fbc197c81000000000000000000000000000000000000000000000000000000008152f35b509160c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610741576102d6611100565b6024356102e1611146565b936064359173ffffffffffffffffffffffffffffffffffffffff80841684036107d85760a435968188168098036107d857819061031c611366565b169586156108cc5734156108a557817f00000000000000000000000000000000000000000000000000000000000000001690813b15610897578985517fd0e30db00000000000000000000000000000000000000000000000000000000081528181848134885af1801561089b57610883575b505082610416937f000000000000000000000000000000000000000000000000000000000000000016978b87518a817f095ea7b30000000000000000000000000000000000000000000000000000000093848252818060209b8c9534908c84016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03918a5af180156108775761085a575b50670de0b6b3a76400009283880293888504148815171561082e57868e918a5190610450826111ac565b88825285169e8f838301527f000000000000000000000000000000000000000000000000000000000000000062ffffff168c83015230606083015286608083015260843560a083015260c08201528a519c8d917f5023b4df0000000000000000000000000000000000000000000000000000000083528883016105309160c0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015262ffffff60408201511660408601528260608201511660608601526080810151608086015260a081015160a0860152015116910152565b81845a9260e493f19a8b15610822578d90829c6107ef575b50876024918b51928380927f70a08231000000000000000000000000000000000000000000000000000000008252308b8301525afa9182156107e4579085926107ae575b50106107865785838d8f97969594886105d5958d519687958694859384528b84016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af1801561077c5761074f575b508a3b1561072957838a60448d93838b5195869485937f7647691d0000000000000000000000000000000000000000000000000000000085528985015260248401525af180156107455790849161072d575b5050348810610678575b5050507f72d6b4b5ad0fb12b8a7bb3bcb60edd774c096403d611437859c156ecb3c03a36935082519485528401523392a46001815580f35b610682883461132a565b823b15610729576024849283895195869485937f2e1a7d4d0000000000000000000000000000000000000000000000000000000085528401525af1801561071f57610707575b50506106ff7f72d6b4b5ad0fb12b8a7bb3bcb60edd774c096403d611437859c156ecb3c03a36946106f9873461132a565b906113a1565b873880610640565b61071090611169565b61071b5787386106c8565b8780fd5b85513d84823e3d90fd5b8380fd5b61073690611169565b610741578238610636565b8280fd5b87513d86823e3d90fd5b61076e90863d8811610775575b61076681836111c8565b810190611312565b50386105e4565b503d61075c565b88513d87823e3d90fd5b8388517f25c596a9000000000000000000000000000000000000000000000000000000008152fd5b809250888092503d83116107dd575b6107c781836111c8565b810103126107d8578390513861058c565b600080fd5b503d6107bd565b8a51903d90823e3d90fd5b9b505050858a813d831161081b575b61080881836111c8565b810103126107d8579851988c8c87610548565b503d6107fe565b508851903d90823e3d90fd5b60248e6011877f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b61087090873d89116107755761076681836111c8565b5038610426565b8e8a51903d90823e3d90fd5b61088c90611169565b61089757893861038e565b8980fd5b87513d84823e3d90fd5b83517f16f98f86000000000000000000000000000000000000000000000000000000008152fd5b83517f9c8d2cd2000000000000000000000000000000000000000000000000000000008152fd5b5090346101e157817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101e1576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5090346101e157817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101e1576020905162ffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5090346101e15760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101e1576109f9611100565b602491823590610a07611146565b9160843573ffffffffffffffffffffffffffffffffffffffff80821680920361071b57610a32611366565b80851695861561101b578116968451927f6addb66300000000000000000000000000000000000000000000000000000000845260609283858d818d5afa948515611011578b95610f73575b508085511660208096015190885130888201528781528981019281841067ffffffffffffffff851117610f4757838b52823b15610f43579183918f938f7ff242432a000000000000000000000000000000000000000000000000000000008552336044840152606483015260848201528a60a482015260a060c482015280518060e48301528a855b828110610f2257505060c4827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f848961010481978b99010152011681010301925af18015610f1857610f05575b50670de0b6b3a764000090818702918783041487151715610eda5787517f70a0823100000000000000000000000000000000000000000000000000000000815230818f0152868186818f5afa908115610ed0579083918e91610e9f575b5010610e7757918b9c91838d888e9f9897969e9d9e7f000000000000000000000000000000000000000000000000000000000000000016809e8d5180948180947f095ea7b3000000000000000000000000000000000000000000000000000000008252898c830191610c45926020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af18015610e6d57938f919360e493610d6c958c97610e50575b507f000000000000000000000000000000000000000000000000000000000000000016988d5193610c91856111ac565b845289878501528d62ffffff7f000000000000000000000000000000000000000000000000000000000000000016908501523090840152608083015260643560a083015260c0820152878b519d8e9485937f04e45aaf0000000000000000000000000000000000000000000000000000000085528885019060c0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015262ffffff60408201511660408601528260608201511660608601526080810151608086015260a081015160a0860152015116910152565b5af1988915610745578499610e1d575b50823b15610729578391899183895195869485937f2e1a7d4d0000000000000000000000000000000000000000000000000000000085528401525af1801561071f5790879291610e06575b5050610df4907fce7a9659161c4da85bb2316f11bb01521a23f37c260ae347af58e5789f138920956113a1565b82519485528401523392a46001815580f35b610e11919250611169565b61071b57848838610dc7565b8580929a508195503d8311610e49575b610e3781836111c8565b810103126107d8578a92519738610d7c565b503d610e2d565b610e6690883d8a116107755761076681836111c8565b5038610c61565b8b513d8a823e3d90fd5b8c88517fa2b41e59000000000000000000000000000000000000000000000000000000008152fd5b809250888092503d8311610ec9575b610eb881836111c8565b810103126107d85782905138610bb1565b503d610eae565b89513d8f823e3d90fd5b838c60118f7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b610f11909b919b611169565b9938610b54565b88513d8e823e3d90fd5b919395509193508084016101048382015191015201918f93918a8694610b05565b8e80fd5b8f8f604189927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b9094508381813d831161100a575b610f8b81836111c8565b810103126110065786519084820182811067ffffffffffffffff821117610fda57610fcf9189918252610fbd816112f1565b845260208101516020850152016112f1565b878201529338610a7d565b50838c60418f7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b8a80fd5b503d610f81565b87513d8d823e3d90fd5b8985517f9c8d2cd2000000000000000000000000000000000000000000000000000000008152fd5b905083346107415760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261074157357fffffffff00000000000000000000000000000000000000000000000000000000811680910361074157602092507f4e2312e00000000000000000000000000000000000000000000000000000000081149081156110d6575b5015158152f35b7f01ffc9a700000000000000000000000000000000000000000000000000000000915014836110cf565b6004359073ffffffffffffffffffffffffffffffffffffffff821682036107d857565b6024359073ffffffffffffffffffffffffffffffffffffffff821682036107d857565b6044359073ffffffffffffffffffffffffffffffffffffffff821682036107d857565b67ffffffffffffffff811161117d57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60e0810190811067ffffffffffffffff82111761117d57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761117d57604052565b81601f820112156107d85780359160209167ffffffffffffffff841161117d578360051b906040519461123e858401876111c8565b855283808601928201019283116107d8578301905b828210611261575050505090565b81358152908301908301611253565b67ffffffffffffffff811161117d57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b81601f820112156107d8578035906112c182611270565b926112cf60405194856111c8565b828452602083830101116107d857816000926020809301838601378301015290565b519073ffffffffffffffffffffffffffffffffffffffff821682036107d857565b908160209103126107d8575180151581036107d85790565b9190820391821161133757565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600260005414611377576002600055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b81471061142657600080809373ffffffffffffffffffffffffffffffffffffffff8294165af13d15611421573d6113d781611270565b906113e560405192836111c8565b8152600060203d92013e5b156113f757565b60046040517f1425ea42000000000000000000000000000000000000000000000000000000008152fd5b6113f0565b60246040517fcd786059000000000000000000000000000000000000000000000000000000008152306004820152fdfea2646970667358221220375be32f0c65ad26939466d4333017d82de693635d81a5ca66bf1b0f8bebb71e64736f6c63430008170033000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc450000000000000000000000000000000000000000000000000000000000002710

Deployed Bytecode

0x6080604081815260049182361015610083575b50361561001e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216330361005d57005b517f01f180c9000000000000000000000000000000000000000000000000000000008152fd5b600090813560e01c90816301ffc9a7146110435750806355193c95146109c0578063637af4df14610962578063ad5c4648146108f3578063b3836da9146102a2578063bc197c81146101e5578063c31c9c07146101725763f23a6e6103610012573461016f5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261016f5761011b611100565b50610124611123565b506084359067ffffffffffffffff821161016f5750602092610148913691016112aa565b50517ff23a6e61000000000000000000000000000000000000000000000000000000008152f35b80fd5b5090346101e157817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101e1576020905173ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45168152f35b5080fd5b503461016f5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261016f5761021d611100565b50610226611123565b5067ffffffffffffffff906044358281116101e1576102489036908601611209565b506064358281116101e1576102609036908601611209565b5060843591821161016f575060209261027b913691016112aa565b50517fbc197c81000000000000000000000000000000000000000000000000000000008152f35b509160c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610741576102d6611100565b6024356102e1611146565b936064359173ffffffffffffffffffffffffffffffffffffffff80841684036107d85760a435968188168098036107d857819061031c611366565b169586156108cc5734156108a557817f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21690813b15610897578985517fd0e30db00000000000000000000000000000000000000000000000000000000081528181848134885af1801561089b57610883575b505082610416937f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc4516978b87518a817f095ea7b30000000000000000000000000000000000000000000000000000000093848252818060209b8c9534908c84016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03918a5af180156108775761085a575b50670de0b6b3a76400009283880293888504148815171561082e57868e918a5190610450826111ac565b88825285169e8f838301527f000000000000000000000000000000000000000000000000000000000000271062ffffff168c83015230606083015286608083015260843560a083015260c08201528a519c8d917f5023b4df0000000000000000000000000000000000000000000000000000000083528883016105309160c0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015262ffffff60408201511660408601528260608201511660608601526080810151608086015260a081015160a0860152015116910152565b81845a9260e493f19a8b15610822578d90829c6107ef575b50876024918b51928380927f70a08231000000000000000000000000000000000000000000000000000000008252308b8301525afa9182156107e4579085926107ae575b50106107865785838d8f97969594886105d5958d519687958694859384528b84016020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af1801561077c5761074f575b508a3b1561072957838a60448d93838b5195869485937f7647691d0000000000000000000000000000000000000000000000000000000085528985015260248401525af180156107455790849161072d575b5050348810610678575b5050507f72d6b4b5ad0fb12b8a7bb3bcb60edd774c096403d611437859c156ecb3c03a36935082519485528401523392a46001815580f35b610682883461132a565b823b15610729576024849283895195869485937f2e1a7d4d0000000000000000000000000000000000000000000000000000000085528401525af1801561071f57610707575b50506106ff7f72d6b4b5ad0fb12b8a7bb3bcb60edd774c096403d611437859c156ecb3c03a36946106f9873461132a565b906113a1565b873880610640565b61071090611169565b61071b5787386106c8565b8780fd5b85513d84823e3d90fd5b8380fd5b61073690611169565b610741578238610636565b8280fd5b87513d86823e3d90fd5b61076e90863d8811610775575b61076681836111c8565b810190611312565b50386105e4565b503d61075c565b88513d87823e3d90fd5b8388517f25c596a9000000000000000000000000000000000000000000000000000000008152fd5b809250888092503d83116107dd575b6107c781836111c8565b810103126107d8578390513861058c565b600080fd5b503d6107bd565b8a51903d90823e3d90fd5b9b505050858a813d831161081b575b61080881836111c8565b810103126107d8579851988c8c87610548565b503d6107fe565b508851903d90823e3d90fd5b60248e6011877f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b61087090873d89116107755761076681836111c8565b5038610426565b8e8a51903d90823e3d90fd5b61088c90611169565b61089757893861038e565b8980fd5b87513d84823e3d90fd5b83517f16f98f86000000000000000000000000000000000000000000000000000000008152fd5b83517f9c8d2cd2000000000000000000000000000000000000000000000000000000008152fd5b5090346101e157817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101e1576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168152f35b5090346101e157817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101e1576020905162ffffff7f0000000000000000000000000000000000000000000000000000000000002710168152f35b5090346101e15760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126101e1576109f9611100565b602491823590610a07611146565b9160843573ffffffffffffffffffffffffffffffffffffffff80821680920361071b57610a32611366565b80851695861561101b578116968451927f6addb66300000000000000000000000000000000000000000000000000000000845260609283858d818d5afa948515611011578b95610f73575b508085511660208096015190885130888201528781528981019281841067ffffffffffffffff851117610f4757838b52823b15610f43579183918f938f7ff242432a000000000000000000000000000000000000000000000000000000008552336044840152606483015260848201528a60a482015260a060c482015280518060e48301528a855b828110610f2257505060c4827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f848961010481978b99010152011681010301925af18015610f1857610f05575b50670de0b6b3a764000090818702918783041487151715610eda5787517f70a0823100000000000000000000000000000000000000000000000000000000815230818f0152868186818f5afa908115610ed0579083918e91610e9f575b5010610e7757918b9c91838d888e9f9897969e9d9e7f00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc4516809e8d5180948180947f095ea7b3000000000000000000000000000000000000000000000000000000008252898c830191610c45926020909392919373ffffffffffffffffffffffffffffffffffffffff60408201951681520152565b03925af18015610e6d57938f919360e493610d6c958c97610e50575b507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216988d5193610c91856111ac565b845289878501528d62ffffff7f000000000000000000000000000000000000000000000000000000000000271016908501523090840152608083015260643560a083015260c0820152878b519d8e9485937f04e45aaf0000000000000000000000000000000000000000000000000000000085528885019060c0908173ffffffffffffffffffffffffffffffffffffffff9182815116855282602082015116602086015262ffffff60408201511660408601528260608201511660608601526080810151608086015260a081015160a0860152015116910152565b5af1988915610745578499610e1d575b50823b15610729578391899183895195869485937f2e1a7d4d0000000000000000000000000000000000000000000000000000000085528401525af1801561071f5790879291610e06575b5050610df4907fce7a9659161c4da85bb2316f11bb01521a23f37c260ae347af58e5789f138920956113a1565b82519485528401523392a46001815580f35b610e11919250611169565b61071b57848838610dc7565b8580929a508195503d8311610e49575b610e3781836111c8565b810103126107d8578a92519738610d7c565b503d610e2d565b610e6690883d8a116107755761076681836111c8565b5038610c61565b8b513d8a823e3d90fd5b8c88517fa2b41e59000000000000000000000000000000000000000000000000000000008152fd5b809250888092503d8311610ec9575b610eb881836111c8565b810103126107d85782905138610bb1565b503d610eae565b89513d8f823e3d90fd5b838c60118f7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b610f11909b919b611169565b9938610b54565b88513d8e823e3d90fd5b919395509193508084016101048382015191015201918f93918a8694610b05565b8e80fd5b8f8f604189927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b9094508381813d831161100a575b610f8b81836111c8565b810103126110065786519084820182811067ffffffffffffffff821117610fda57610fcf9189918252610fbd816112f1565b845260208101516020850152016112f1565b878201529338610a7d565b50838c60418f7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b8a80fd5b503d610f81565b87513d8d823e3d90fd5b8985517f9c8d2cd2000000000000000000000000000000000000000000000000000000008152fd5b905083346107415760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261074157357fffffffff00000000000000000000000000000000000000000000000000000000811680910361074157602092507f4e2312e00000000000000000000000000000000000000000000000000000000081149081156110d6575b5015158152f35b7f01ffc9a700000000000000000000000000000000000000000000000000000000915014836110cf565b6004359073ffffffffffffffffffffffffffffffffffffffff821682036107d857565b6024359073ffffffffffffffffffffffffffffffffffffffff821682036107d857565b6044359073ffffffffffffffffffffffffffffffffffffffff821682036107d857565b67ffffffffffffffff811161117d57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60e0810190811067ffffffffffffffff82111761117d57604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761117d57604052565b81601f820112156107d85780359160209167ffffffffffffffff841161117d578360051b906040519461123e858401876111c8565b855283808601928201019283116107d8578301905b828210611261575050505090565b81358152908301908301611253565b67ffffffffffffffff811161117d57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b81601f820112156107d8578035906112c182611270565b926112cf60405194856111c8565b828452602083830101116107d857816000926020809301838601378301015290565b519073ffffffffffffffffffffffffffffffffffffffff821682036107d857565b908160209103126107d8575180151581036107d85790565b9190820391821161133757565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600260005414611377576002600055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b81471061142657600080809373ffffffffffffffffffffffffffffffffffffffff8294165af13d15611421573d6113d781611270565b906113e560405192836111c8565b8152600060203d92013e5b156113f757565b60046040517f1425ea42000000000000000000000000000000000000000000000000000000008152fd5b6113f0565b60246040517fcd786059000000000000000000000000000000000000000000000000000000008152306004820152fdfea2646970667358221220375be32f0c65ad26939466d4333017d82de693635d81a5ca66bf1b0f8bebb71e64736f6c63430008170033

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

000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc450000000000000000000000000000000000000000000000000000000000002710

-----Decoded View---------------
Arg [0] : weth_ (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [1] : swapRouter_ (address): 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45
Arg [2] : uniswapFee_ (uint24): 10000

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [1] : 00000000000000000000000068b3465833fb72a70ecdf485e0e4c7bd8665fc45
Arg [2] : 0000000000000000000000000000000000000000000000000000000000002710


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

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.