Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SecondarySwap
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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();
}
}
}// 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);
}{
"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
- No Contract Security Audit Submitted- Submit Audit Here
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"}]Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.