false
false
0

Contract Address Details

0x353F4106641Db62384cF0e4F1Ef15F8Ac9A9fb4B

Contract Name
LSSVMPairFactory
Creator
0x94a47b–b522b5 at 0xc26ef7–23f11a
Balance
1,012.008446161691920778 EOS
Tokens
Fetching tokens...
Transactions
1,069 Transactions
Transfers
0 Transfers
Gas Used
220,816,414
Last Balance Update
61719068
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
LSSVMPairFactory




Optimization enabled
true
Compiler version
v0.8.13+commit.abaa5c0e




Optimization runs
200
EVM Version
default




Verified at
2024-01-31T11:38:45.900033Z

Constructor Arguments

0x0000000000000000000000004f65da64c4b1cad8f58fdf06a55bca73e6a840ec000000000000000000000000523c60dbc05feeba61f28eef1f6db3770e3034d000000000000000000000000056d990d832ba60deb6f45d6769c7cf4727fc86a20000000000000000000000000724fb6d3cdbd560a805850a87e9544e461d1b0e000000000000000000000000487b214a849ef6c5cf21793ead9468848f451a440000000000000000000000000c4401940338396b2f75ba419bfbd7c6f18068f100000000000000000000000094a47b89c600962eff6f4cf53dfd05aa05b522b5000000000000000000000000000000000000000000000000002386f26fc10000

Arg [0] (address) : 0x4f65da64c4b1cad8f58fdf06a55bca73e6a840ec
Arg [1] (address) : 0x523c60dbc05feeba61f28eef1f6db3770e3034d0
Arg [2] (address) : 0x56d990d832ba60deb6f45d6769c7cf4727fc86a2
Arg [3] (address) : 0x0724fb6d3cdbd560a805850a87e9544e461d1b0e
Arg [4] (address) : 0x487b214a849ef6c5cf21793ead9468848f451a44
Arg [5] (address) : 0x0c4401940338396b2f75ba419bfbd7c6f18068f1
Arg [6] (address) : 0x94a47b89c600962eff6f4cf53dfd05aa05b522b5
Arg [7] (uint256) : 10000000000000000

              

contracts/v2/LSSVMPairFactory.sol

Sol2uml
new
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {IERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
// @dev Solmate's ERC20 is used instead of OZ's ERC20 so we can use safeTransferLib for cheaper safeTransfers for
// ETH and ERC20 tokens
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {SafeTransferLib} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol";
import {LSSVMPair} from "./LSSVMPair.sol";
import {LSSVMPair1155} from "./LSSVMPair1155.sol";
import {LSSVMRouter} from "./LSSVMRouter.sol";
import {LSSVMPairETH} from "./LSSVMPairETH.sol";
import {LSSVMPair1155ETH} from "./LSSVMPair1155ETH.sol";
import {ICurve} from "./bonding-curves/ICurve.sol";
import {LSSVMPairERC20} from "./LSSVMPairERC20.sol";
import {LSSVMPair1155ERC20} from "./LSSVMPair1155ERC20.sol";
import {LSSVMPairCloner} from "./lib/LSSVMPairCloner.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {LSSVMPairEnumerableETH} from "./LSSVMPairEnumerableETH.sol";
import {LSSVMPairEnumerableERC20} from "./LSSVMPairEnumerableERC20.sol";
import {LSSVMPairMissingEnumerableETH} from "./LSSVMPairMissingEnumerableETH.sol";
import {LSSVMPairMissingEnumerableERC20} from "./LSSVMPairMissingEnumerableERC20.sol";
import {LSSVMPair1155MissingEnumerableETH} from "./LSSVMPair1155MissingEnumerableETH.sol";
import {LSSVMPair1155MissingEnumerableERC20} from "./LSSVMPair1155MissingEnumerableERC20.sol";
contract LSSVMPairFactory is Ownable, ILSSVMPairFactoryLike {
using LSSVMPairCloner for address;
using SafeTransferLib for address payable;
using SafeTransferLib for ERC20;
using EnumerableSet for EnumerableSet.AddressSet;
bytes4 private constant INTERFACE_ID_ERC721_ENUMERABLE =
type(IERC721Enumerable).interfaceId;
 
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/utils/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMRouter.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {SafeTransferLib} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol";
import {LSSVMPair} from "./LSSVMPair.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {CurveErrorCodes} from "./bonding-curves/CurveErrorCodes.sol";
contract LSSVMRouter {
using SafeTransferLib for address payable;
using SafeTransferLib for ERC20;
struct PairSwapAny {
LSSVMPair pair;
uint256 numItems;
}
struct PairSwapSpecific {
LSSVMPair pair;
uint256[] nftIds;
uint256[] nftCounts;
}
struct RobustPairSwapAny {
PairSwapAny swapInfo;
uint256 maxCost;
}
struct RobustPairSwapSpecific {
PairSwapSpecific swapInfo;
uint256 maxCost;
}
struct RobustPairSwapSpecificForToken {
PairSwapSpecific swapInfo;
uint256 minOutput;
}
 
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/utils/introspection/ERC165Checker.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Library used to query support of an interface declared via {IERC165}.
*
* Note that these functions return the actual result of the query: they do not
* `revert` if an interface is not supported. It is up to the caller to decide
* what to do in these cases.
*/
library ERC165Checker {
// As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
/**
* @dev Returns true if `account` supports the {IERC165} interface,
*/
function supportsERC165(address account) internal view returns (bool) {
// Any contract that implements ERC165 must explicitly indicate support of
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
return
_supportsERC165Interface(account, type(IERC165).interfaceId) &&
!_supportsERC165Interface(account, _INTERFACE_ID_INVALID);
}
/**
* @dev Returns true if `account` supports the interface defined by
* `interfaceId`. Support for {IERC165} itself is queried automatically.
*
* See {IERC165-supportsInterface}.
*/
function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
// query support of both ERC165 as per the spec and support of _interfaceId
return supportsERC165(account) && _supportsERC165Interface(account, interfaceId);
}
/**
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/ILSSVMPairFactoryLike.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {LSSVMRouter} from "./LSSVMRouter.sol";
// TODO
interface ILSSVMPairFactoryLike {
enum PairVariant {
ENUMERABLE_ETH,
MISSING_ENUMERABLE_ETH,
ENUMERABLE_ERC20,
MISSING_ENUMERABLE_ERC20,
MISSING_ENUMERABLE_1155_ETH,
MISSING_ENUMERABLE_1155_ERC20
}
function protocolFeeMultiplier() external view returns (uint256);
function protocolFeeRecipient() external view returns (address payable);
function callAllowed(address target) external view returns (bool);
function operatorProtocolFeeRecipients(address nft,address operator) external view returns (address);
function operatorProtocolFeeMultipliers(address nft,address operator) external view returns (uint256);
function getNftOperators(address nft) external view returns (address[] memory);
function routerStatus(LSSVMRouter router)
external
view
returns (bool allowed, bool wasEverAllowed);
function isPair(address potentialPair, PairVariant variant)
external
view
returns (bool);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPairETH.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {SafeTransferLib} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol";
import {LSSVMPair} from "./LSSVMPair.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {ICurve} from "./bonding-curves/ICurve.sol";
import {CurveErrorCodes} from "./bonding-curves/CurveErrorCodes.sol";
/**
@title An NFT/Token pair where the token is ETH
@author boredGenius and 0xmons
*/
abstract contract LSSVMPairETH is LSSVMPair {
using SafeTransferLib for address payable;
using SafeTransferLib for ERC20;
uint256 internal constant IMMUTABLE_PARAMS_LENGTH = 61;
/// @inheritdoc LSSVMPair
function _pullTokenInputAndPayProtocolFee(
uint256 inputAmount,
bool, /*isRouter*/
address, /*routerCaller*/
ILSSVMPairFactoryLike _factory,
CurveErrorCodes.ProtocolFeeStruct memory protocolFeeStruct
) internal override {
require(msg.value >= inputAmount, "Sent too little ETH");
// Transfer inputAmount ETH to assetRecipient if it's been set
address payable _assetRecipient = getAssetRecipient();
if (_assetRecipient != address(this)) {
_assetRecipient.safeTransferETH(inputAmount - protocolFeeStruct.totalProtocolFeeAmount);
}
// Take protocol fee
for (uint i = 0; i < protocolFeeStruct.protocolFeeAmount.length;) {
uint protocolFee = protocolFeeStruct.protocolFeeAmount[i];
if (protocolFee > address(this).balance) {
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPairEnumerable.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {LSSVMRouter} from "./LSSVMRouter.sol";
import {LSSVMPair} from "./LSSVMPair.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
/**
@title An NFT/Token pair for an NFT that implements ERC721Enumerable
@author boredGenius and 0xmons
*/
abstract contract LSSVMPairEnumerable is LSSVMPair {
/// @inheritdoc LSSVMPair
function _sendAnyNFTsToRecipient(
IERC721 _nft,
address nftRecipient,
uint256 numNFTs
) internal override {
// Send NFTs to recipient
// (we know NFT implements IERC721Enumerable so we just iterate)
uint256 lastIndex = _nft.balanceOf(address(this)) - 1;
for (uint256 i = 0; i < numNFTs; ) {
uint256 nftId = IERC721Enumerable(address(_nft))
.tokenOfOwnerByIndex(address(this), lastIndex);
_nft.safeTransferFrom(address(this), nftRecipient, nftId);
unchecked {
--lastIndex;
++i;
}
}
}
/// @inheritdoc LSSVMPair
function _sendSpecificNFTsToRecipient(
IERC721 _nft,
address nftRecipient,
uint256[] calldata nftIds
) internal override {
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPair1155MissingEnumerable.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {Arrays} from "@openzeppelin/contracts/utils/Arrays.sol";
import {LSSVMPair1155} from "./LSSVMPair1155.sol";
import {LSSVMRouter} from "./LSSVMRouter.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
/**
@title An NFT/Token pair for an NFT that does not implement ERC721Enumerable
@author boredGenius and 0xmons
*/
abstract contract LSSVMPair1155MissingEnumerable is LSSVMPair1155 {
using Arrays for uint256[];
/// @inheritdoc LSSVMPair1155
function _sendSpecificNFTsToRecipient(
IERC1155 _nft,
address nftRecipient,
uint256 nftId,
uint256 nftCount
) internal override {
// Send NFTs to caller
_nft.safeTransferFrom(
address(this),
nftRecipient,
nftId,
nftCount,
""
);
}
/// @inheritdoc LSSVMPair1155
function getAllHeldIds() external view override returns (uint256[] memory) {
uint256[] memory Ids = new uint256[](1);
Ids[0] = nftId;
return Ids;
}
/**
@dev When safeTransfering an ERC1155 in, we add ID to the idSet
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Enumerable is IERC721 {
/**
* @dev Returns the total amount of tokens stored by the contract.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns a token ID owned by `owner` at a given `index` of its token list.
* Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
*/
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
/**
* @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
* Use along with {totalSupply} to enumerate all tokens.
*/
function tokenByIndex(uint256 index) external view returns (uint256);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/lib/LSSVMPairCloner.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {ICurve} from "../bonding-curves/ICurve.sol";
import {ILSSVMPairFactoryLike} from "../ILSSVMPairFactoryLike.sol";
library LSSVMPairCloner {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*
* During the delegate call, extra data is copied into the calldata which can then be
* accessed by the implementation contract.
*/
function cloneETHPair(
address implementation,
ILSSVMPairFactoryLike factory,
ICurve bondingCurve,
IERC721 nft,
uint8 poolType
) internal returns (address instance) {
assembly {
let ptr := mload(0x40)
// -------------------------------------------------------------------------------------------------------------
// CREATION (9 bytes)
// -------------------------------------------------------------------------------------------------------------
// creation size = 09
// runtime size = 72
// 60 runtime | PUSH1 runtime (r) | r | –
// 3d | RETURNDATASIZE | 0 r | –
// 81 | DUP2 | r 0 r | –
// 60 creation | PUSH1 creation (c) | c r 0 r | –
 
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/utils/ERC1155Holder.sol)
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
/**
* Simple implementation of `ERC1155Receiver` 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.
*
* @dev _Available since v3.1._
*/
contract ERC1155Holder is ERC1155Receiver {
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;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/token/ERC721/IERC721.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/lib/OwnableWithTransferCallback.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.4;
import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol";
import {IOwnershipTransferCallback} from "./IOwnershipTransferCallback.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
abstract contract OwnableWithTransferCallback {
using ERC165Checker for address;
using Address for address;
bytes4 constant TRANSFER_CALLBACK =
type(IOwnershipTransferCallback).interfaceId;
error Ownable_NotOwner();
error Ownable_NewOwnerZeroAddress();
address private _owner;
event OwnershipTransferred(address indexed newOwner);
/// @dev Initializes the contract setting the deployer as the initial owner.
function __Ownable_init(address initialOwner) internal {
_owner = initialOwner;
}
/// @dev Returns the address of the current owner.
function owner() public view virtual returns (address) {
return _owner;
}
/// @dev Throws if called by any account other than the owner.
modifier onlyOwner() {
if (owner() != msg.sender) revert Ownable_NotOwner();
_;
}
/// @dev Transfers ownership of the contract to a new account (`newOwner`).
/// Disallows setting to the zero address as a way to more gas-efficiently avoid reinitialization
/// When ownership is transferred, if the new owner implements IOwnershipTransferCallback, we make a callback
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPairEnumerableETH.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {LSSVMPairETH} from "./LSSVMPairETH.sol";
import {LSSVMPairEnumerable} from "./LSSVMPairEnumerable.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
/**
@title An NFT/Token pair where the NFT implements ERC721Enumerable, and the token is ETH
@author boredGenius and 0xmons
*/
contract LSSVMPairEnumerableETH is LSSVMPairEnumerable, LSSVMPairETH {
/**
@notice Returns the LSSVMPair type
*/
function pairVariant()
public
pure
override
returns (ILSSVMPairFactoryLike.PairVariant)
{
return ILSSVMPairFactoryLike.PairVariant.ENUMERABLE_ETH;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPair1155MissingEnumerableERC20.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {LSSVMPair1155ERC20} from "./LSSVMPair1155ERC20.sol";
import {LSSVMPair1155MissingEnumerable} from "./LSSVMPair1155MissingEnumerable.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
contract LSSVMPair1155MissingEnumerableERC20 is
LSSVMPair1155MissingEnumerable,
LSSVMPair1155ERC20
{
function pairVariant()
public
pure
override
returns (ILSSVMPairFactoryLike.PairVariant)
{
return ILSSVMPairFactoryLike.PairVariant.MISSING_ENUMERABLE_1155_ERC20;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPairERC20.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {SafeTransferLib} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol";
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {LSSVMPair} from "./LSSVMPair.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {LSSVMRouter} from "./LSSVMRouter.sol";
import {ICurve} from "./bonding-curves/ICurve.sol";
import {CurveErrorCodes} from "./bonding-curves/CurveErrorCodes.sol";
/**
@title An NFT/Token pair where the token is an ERC20
@author boredGenius and 0xmons
*/
abstract contract LSSVMPairERC20 is LSSVMPair {
using SafeTransferLib for ERC20;
uint256 internal constant IMMUTABLE_PARAMS_LENGTH = 81;
/**
@notice Returns the ERC20 token associated with the pair
@dev See LSSVMPairCloner for an explanation on how this works
*/
function token() public pure returns (ERC20 _token) {
uint256 paramsLength = _immutableParamsLength();
assembly {
_token := shr(
0x60,
calldataload(add(sub(calldatasize(), paramsLength), 61))
)
}
}
/// @inheritdoc LSSVMPair
function _pullTokenInputAndPayProtocolFee(
uint256 inputAmount,
bool isRouter,
address routerCaller,
ILSSVMPairFactoryLike _factory,
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/utils/introspection/IERC165.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @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);
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/lib/IOwnershipTransferCallback.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.4;
interface IOwnershipTransferCallback {
function onOwnershipTransfer(address oldOwner) external;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPairMissingEnumerableETH.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {LSSVMPairETH} from "./LSSVMPairETH.sol";
import {LSSVMPairMissingEnumerable} from "./LSSVMPairMissingEnumerable.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
contract LSSVMPairMissingEnumerableETH is
LSSVMPairMissingEnumerable,
LSSVMPairETH
{
function pairVariant()
public
pure
override
returns (ILSSVMPairFactoryLike.PairVariant)
{
return ILSSVMPairFactoryLike.PairVariant.MISSING_ENUMERABLE_ETH;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPair.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {OwnableWithTransferCallback} from "./lib/OwnableWithTransferCallback.sol";
import {ReentrancyGuard} from "./lib/ReentrancyGuard.sol";
import {ICurve} from "./bonding-curves/ICurve.sol";
import {LSSVMRouter} from "./LSSVMRouter.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {CurveErrorCodes} from "./bonding-curves/CurveErrorCodes.sol";
import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
/// @title The base contract for an NFT/TOKEN AMM pair
/// @author boredGenius and 0xmons
/// @notice This implements the core swap logic from NFT to TOKEN
abstract contract LSSVMPair is
OwnableWithTransferCallback,
ReentrancyGuard,
ERC1155Holder
{
enum PoolType {
TOKEN,
NFT,
TRADE
}
// 90%, must <= 1 - MAX_PROTOCOL_FEE (set in LSSVMPairFactory)
uint256 internal constant MAX_FEE = 0.50e18;
// The current price of the NFT
// @dev This is generally used to mean the immediate sell price for the next marginal NFT.
// However, this should NOT be assumed, as future bonding curves may use spotPrice in different ways.
// Use getBuyNFTQuote and getSellNFTQuote for accurate pricing info.
uint128 public spotPrice;
// The parameter for the pair's bonding curve.
// Units and meaning are bonding curve dependent.
uint128 public delta;
 
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPairMissingEnumerable.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {LSSVMPair} from "./LSSVMPair.sol";
import {LSSVMRouter} from "./LSSVMRouter.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
/**
@title An NFT/Token pair for an NFT that does not implement ERC721Enumerable
@author boredGenius and 0xmons
*/
abstract contract LSSVMPairMissingEnumerable is LSSVMPair {
using EnumerableSet for EnumerableSet.UintSet;
// Used for internal ID tracking
EnumerableSet.UintSet private idSet;
/// @inheritdoc LSSVMPair
function _sendAnyNFTsToRecipient(
IERC721 _nft,
address nftRecipient,
uint256 numNFTs
) internal override {
// Send NFTs to recipient
// We're missing enumerable, so we also update the pair's own ID set
// NOTE: We start from last index to first index to save on gas
uint256 lastIndex = idSet.length() - 1;
for (uint256 i; i < numNFTs; ) {
uint256 nftId = idSet.at(lastIndex);
_nft.safeTransferFrom(address(this), nftRecipient, nftId);
idSet.remove(nftId);
unchecked {
--lastIndex;
++i;
}
}
}
/// @inheritdoc LSSVMPair
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev _Available since v3.1._
*/
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)"))`
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPair1155.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {OwnableWithTransferCallback} from "./lib/OwnableWithTransferCallback.sol";
import {ReentrancyGuard} from "./lib/ReentrancyGuard.sol";
import {ICurve} from "./bonding-curves/ICurve.sol";
import {LSSVMRouter} from "./LSSVMRouter.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {CurveErrorCodes} from "./bonding-curves/CurveErrorCodes.sol";
import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
/// @title The base contract for an NFT/TOKEN AMM pair
/// @author boredGenius and 0xmons
/// @notice This implements the core swap logic from NFT to TOKEN
abstract contract LSSVMPair1155 is
OwnableWithTransferCallback,
ReentrancyGuard,
ERC721Holder
{
enum PoolType {
TOKEN,
NFT,
TRADE
}
// 90%, must <= 1 - MAX_PROTOCOL_FEE (set in LSSVMPairFactory)
uint256 internal constant MAX_FEE = 0.50e18;
// The current price of the NFT
// @dev This is generally used to mean the immediate sell price for the next marginal NFT.
// However, this should NOT be assumed, as future bonding curves may use spotPrice in different ways.
// Use getBuyNFTQuote and getSellNFTQuote for accurate pricing info.
uint128 public spotPrice;
// The parameter for the pair's bonding curve.
// Units and meaning are bonding curve dependent.
uint128 public delta;
 
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPair1155ETH.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {SafeTransferLib} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol";
import {LSSVMPair1155} from "./LSSVMPair1155.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {ICurve} from "./bonding-curves/ICurve.sol";
import {CurveErrorCodes} from "./bonding-curves/CurveErrorCodes.sol";
/**
@title An NFT/Token pair where the token is ETH
@author boredGenius and 0xmons
*/
abstract contract LSSVMPair1155ETH is LSSVMPair1155 {
using SafeTransferLib for address payable;
using SafeTransferLib for ERC20;
uint256 internal constant IMMUTABLE_PARAMS_LENGTH = 93;
/// @inheritdoc LSSVMPair1155
function _pullTokenInputAndPayProtocolFee(
uint256 inputAmount,
bool, /*isRouter*/
address, /*routerCaller*/
ILSSVMPairFactoryLike _factory,
CurveErrorCodes.ProtocolFeeStruct memory protocolFeeStruct
) internal override {
require(msg.value >= inputAmount, "Sent too little ETH");
// Transfer inputAmount ETH to assetRecipient if it's been set
address payable _assetRecipient = getAssetRecipient();
if (_assetRecipient != address(this)) {
_assetRecipient.safeTransferETH(inputAmount - protocolFeeStruct.totalProtocolFeeAmount);
}
// Take protocol fee
for (uint i = 0; i < protocolFeeStruct.protocolFeeAmount.length;) {
uint protocolFee = protocolFeeStruct.protocolFeeAmount[i];
if (protocolFee > address(this).balance) {
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPair1155ERC20.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {SafeTransferLib} from "@rari-capital/solmate/src/utils/SafeTransferLib.sol";
import {ERC20} from "@rari-capital/solmate/src/tokens/ERC20.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import {LSSVMPair1155} from "./LSSVMPair1155.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {LSSVMRouter} from "./LSSVMRouter.sol";
import {ICurve} from "./bonding-curves/ICurve.sol";
import {CurveErrorCodes} from "./bonding-curves/CurveErrorCodes.sol";
/**
@title An NFT/Token pair where the token is an ERC20
@author boredGenius and 0xmons
*/
abstract contract LSSVMPair1155ERC20 is LSSVMPair1155 {
using SafeTransferLib for ERC20;
uint256 internal constant IMMUTABLE_PARAMS_LENGTH = 113;
/**
@notice Returns the ERC20 token associated with the pair
@dev See LSSVMPairCloner for an explanation on how this works
*/
function token() public pure returns (ERC20 _token) {
uint256 paramsLength = _immutableParamsLength();
assembly {
_token := shr(
0x60,
calldataload(add(sub(calldatasize(), paramsLength), 61))
)
}
}
/// @inheritdoc LSSVMPair1155
function _pullTokenInputAndPayProtocolFee(
uint256 inputAmount,
bool isRouter,
address routerCaller,
ILSSVMPairFactoryLike _factory,
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/lib/ReentrancyGuard.sol

// SPDX-License-Identifier: MIT
// Forked from OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol),
// removed initializer check as we already do that in our modified Ownable
pragma solidity ^0.8.0;
/**
* @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;
function __ReentrancyGuard_init() internal {
_status = _NOT_ENTERED;
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPairEnumerableERC20.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {LSSVMPairERC20} from "./LSSVMPairERC20.sol";
import {LSSVMPairEnumerable} from "./LSSVMPairEnumerable.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
/**
@title An NFT/Token pair where the NFT implements ERC721Enumerable, and the token is an ERC20
@author boredGenius and 0xmons
*/
contract LSSVMPairEnumerableERC20 is LSSVMPairEnumerable, LSSVMPairERC20 {
/**
@notice Returns the LSSVMPair type
*/
function pairVariant()
public
pure
override
returns (ILSSVMPairFactoryLike.PairVariant)
{
return ILSSVMPairFactoryLike.PairVariant.ENUMERABLE_ERC20;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/utils/math/Math.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@rari-capital/solmate/src/utils/SafeTransferLib.sol

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
import {ERC20} from "../tokens/ERC20.sol";
/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
library SafeTransferLib {
/*///////////////////////////////////////////////////////////////
ETH OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferETH(address to, uint256 amount) internal {
bool callStatus;
assembly {
// Transfer the ETH and store if it succeeded or not.
callStatus := call(gas(), to, amount, 0, 0, 0, 0)
}
require(callStatus, "ETH_TRANSFER_FAILED");
}
/*///////////////////////////////////////////////////////////////
ERC20 OPERATIONS
//////////////////////////////////////////////////////////////*/
function safeTransferFrom(
ERC20 token,
address from,
address to,
uint256 amount
) internal {
bool callStatus;
assembly {
// Get a pointer to some free memory.
let freeMemoryPointer := mload(0x40)
// Write the abi-encoded calldata to memory piece by piece:
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/utils/ERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
/**
* @dev _Available since v3.1._
*/
abstract contract ERC1155Receiver 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);
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/bonding-curves/ICurve.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {CurveErrorCodes} from "./CurveErrorCodes.sol";
interface ICurve {
/**
@notice Validates if a delta value is valid for the curve. The criteria for
validity can be different for each type of curve, for instance ExponentialCurve
requires delta to be greater than 1.
@param delta The delta value to be validated
@return valid True if delta is valid, false otherwise
*/
function validateDelta(uint128 delta) external pure returns (bool valid);
/**
@notice Validates if a new spot price is valid for the curve. Spot price is generally assumed to be the immediate sell price of 1 NFT to the pool, in units of the pool's paired token.
@param newSpotPrice The new spot price to be set
@return valid True if the new spot price is valid, false otherwise
*/
function validateSpotPrice(uint128 newSpotPrice)
external
view
returns (bool valid);
/**
@notice Given the current state of the pair and the trade, computes how much the user
should pay to purchase an NFT from the pair, the new spot price, and other values.
@param spotPrice The current selling spot price of the pair, in tokens
@param delta The delta parameter of the pair, what it means depends on the curve
@param numItems The number of NFTs the user is buying from the pair
@param feeMultiplier Determines how much fee the LP takes from this trade, 18 decimals
@param protocolFeeMultipliers protocol fee multipliers
@return error Any math calculation errors, only Error.OK means the returned values are valid
@return newSpotPrice The updated selling spot price, in tokens
@return newDelta The updated delta, used to parameterize the bonding curve
@return inputValue The amount that the user should pay, in tokens
@return protocolFeeStruct protocol fee struct
*/
function getBuyInfo(
 
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@rari-capital/solmate/src/tokens/ERC20.sol

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
abstract contract ERC20 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
/*///////////////////////////////////////////////////////////////
METADATA STORAGE
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
uint8 public immutable decimals;
/*///////////////////////////////////////////////////////////////
ERC20 STORAGE
//////////////////////////////////////////////////////////////*/
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
/*///////////////////////////////////////////////////////////////
EIP-2612 STORAGE
//////////////////////////////////////////////////////////////*/
bytes32 public constant PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPair1155MissingEnumerableETH.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {LSSVMPair1155ETH} from "./LSSVMPair1155ETH.sol";
import {LSSVMPair1155MissingEnumerable} from "./LSSVMPair1155MissingEnumerable.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
contract LSSVMPair1155MissingEnumerableETH is
LSSVMPair1155MissingEnumerable,
LSSVMPair1155ETH
{
function pairVariant()
public
pure
override
returns (ILSSVMPairFactoryLike.PairVariant)
{
return ILSSVMPairFactoryLike.PairVariant.MISSING_ENUMERABLE_1155_ETH;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/utils/Address.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
 
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/utils/introspection/ERC165.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./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);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/token/ERC1155/IERC1155.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155 is IERC165 {
/**
* @dev Emitted when `value` tokens of token 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
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/utils/ERC721Holder.sol)
pragma solidity ^0.8.0;
import "../IERC721Receiver.sol";
/**
* @dev Implementation of the {IERC721Receiver} interface.
*
* Accepts all token transfers.
* Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}.
*/
contract ERC721Holder is IERC721Receiver {
/**
* @dev See {IERC721Receiver-onERC721Received}.
*
* Always returns `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address,
address,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/LSSVMPairMissingEnumerableERC20.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {LSSVMPairERC20} from "./LSSVMPairERC20.sol";
import {LSSVMPairMissingEnumerable} from "./LSSVMPairMissingEnumerable.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
contract LSSVMPairMissingEnumerableERC20 is
LSSVMPairMissingEnumerable,
LSSVMPairERC20
{
function pairVariant()
public
pure
override
returns (ILSSVMPairFactoryLike.PairVariant)
{
return ILSSVMPairFactoryLike.PairVariant.MISSING_ENUMERABLE_ERC20;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/utils/structs/EnumerableSet.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/utils/Arrays.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
/**
* @dev Collection of functions related to array types.
*/
library Arrays {
/**
* @dev Searches a sorted `array` and returns the first index that contains
* a value greater or equal to `element`. If no such index exists (i.e. all
* values in the array are strictly less than `element`), the array length is
* returned. Time complexity O(log n).
*
* `array` is expected to be sorted in ascending order, and to contain no
* repeated elements.
*/
function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {
if (array.length == 0) {
return 0;
}
uint256 low = 0;
uint256 high = array.length;
while (low < high) {
uint256 mid = Math.average(low, high);
// Note that mid will always be strictly less than high (i.e. it will be a valid array index)
// because Math.average rounds down (it does integer division with truncation).
if (array[mid] > element) {
high = mid;
} else {
low = mid + 1;
}
}
// At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

@openzeppelin/contracts/access/Ownable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

contracts/v2/bonding-curves/CurveErrorCodes.sol

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
contract CurveErrorCodes {
enum Error {
OK, // No error
INVALID_NUMITEMS, // The numItem value is 0
SPOT_PRICE_OVERFLOW // The updated spot price doesn't fit into 128 bits
}
/**
* @return totalProtocolFeeMultiplier totalProtocol fee multiplier
* @return totalProtocolFeeAmount total protocol fee amount
* @return protocolFeeAmount protocol fee amount
* @return protocolFeeReceiver protocol fee receiver
*/
struct ProtocolFeeStruct {
uint totalProtocolFeeMultiplier;
uint totalProtocolFeeAmount;
uint[] protocolFeeAmount;
address[] protocolFeeReceiver;
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Compiler Settings

{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true,"details":{"yul":false}},"libraries":{}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_enumerableETHTemplate","internalType":"contract LSSVMPairEnumerableETH"},{"type":"address","name":"_missingEnumerableETHTemplate","internalType":"contract LSSVMPairMissingEnumerableETH"},{"type":"address","name":"_enumerableERC20Template","internalType":"contract LSSVMPairEnumerableERC20"},{"type":"address","name":"_missingEnumerableERC20Template","internalType":"contract LSSVMPairMissingEnumerableERC20"},{"type":"address","name":"_missingEnumerable1155ETHTemplate","internalType":"contract LSSVMPair1155MissingEnumerableETH"},{"type":"address","name":"_missingEnumerable1155ERC20Template","internalType":"contract LSSVMPair1155MissingEnumerableERC20"},{"type":"address","name":"_protocolFeeRecipient","internalType":"address payable"},{"type":"uint256","name":"_protocolFeeMultiplier","internalType":"uint256"}]},{"type":"event","name":"BondingCurveStatusUpdate","inputs":[{"type":"address","name":"bondingCurve","internalType":"contract ICurve","indexed":false},{"type":"bool","name":"isAllowed","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"CallTargetStatusUpdate","inputs":[{"type":"address","name":"target","internalType":"address","indexed":false},{"type":"bool","name":"isAllowed","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"NFTDeposit","inputs":[{"type":"address","name":"poolAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"NewPair","inputs":[{"type":"address","name":"poolAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OperatorProtocolFeeStatusUpdate","inputs":[{"type":"address","name":"nft","internalType":"address","indexed":false},{"type":"address","name":"callAddress","internalType":"address","indexed":false},{"type":"address","name":"operatorProtocolFeeRecipient","internalType":"address","indexed":false},{"type":"uint256","name":"operatorProtocolFeeMultiplier","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalOperatorProtocolFeeMultipliers","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ProtocolFeeMultiplierUpdate","inputs":[{"type":"uint256","name":"newMultiplier","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ProtocolFeeRecipientUpdate","inputs":[{"type":"address","name":"recipientAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"RouterStatusUpdate","inputs":[{"type":"address","name":"router","internalType":"contract LSSVMRouter","indexed":false},{"type":"bool","name":"isAllowed","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"TokenDeposit","inputs":[{"type":"address","name":"poolAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"authorize","inputs":[{"type":"address","name":"nft","internalType":"address"},{"type":"address","name":"operator","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"bondingCurveAllowed","inputs":[{"type":"address","name":"","internalType":"contract ICurve"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"callAllowed","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeProtocolFeeMultiplier","inputs":[{"type":"uint256","name":"_protocolFeeMultiplier","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeProtocolFeeRecipient","inputs":[{"type":"address","name":"_protocolFeeRecipient","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"pair","internalType":"contract LSSVMPair1155ERC20"}],"name":"createPair1155ERC20","inputs":[{"type":"tuple","name":"params","internalType":"struct LSSVMPairFactory.Create1155ERC20PairParams","components":[{"type":"address","name":"token","internalType":"contract ERC20"},{"type":"address","name":"nft","internalType":"contract IERC1155"},{"type":"address","name":"bondingCurve","internalType":"contract ICurve"},{"type":"address","name":"assetRecipient","internalType":"address payable"},{"type":"uint8","name":"poolType","internalType":"enum LSSVMPair.PoolType"},{"type":"uint128","name":"delta","internalType":"uint128"},{"type":"uint96","name":"fee","internalType":"uint96"},{"type":"uint128","name":"spotPrice","internalType":"uint128"},{"type":"uint256","name":"nftId","internalType":"uint256"},{"type":"uint256","name":"initialNFTCount","internalType":"uint256"},{"type":"uint256","name":"initialTokenBalance","internalType":"uint256"}]}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"address","name":"pair","internalType":"contract LSSVMPair1155ETH"}],"name":"createPair1155ETH","inputs":[{"type":"tuple","name":"params","internalType":"struct LSSVMPairFactory.CreatePair1155ETHParams","components":[{"type":"address","name":"nft","internalType":"contract IERC1155"},{"type":"address","name":"bondingCurve","internalType":"contract ICurve"},{"type":"address","name":"assetRecipient","internalType":"address payable"},{"type":"uint8","name":"poolType","internalType":"enum LSSVMPair1155.PoolType"},{"type":"uint128","name":"delta","internalType":"uint128"},{"type":"uint96","name":"fee","internalType":"uint96"},{"type":"uint128","name":"spotPrice","internalType":"uint128"},{"type":"uint256","name":"nftId","internalType":"uint256"},{"type":"uint256","name":"initialNFTCount","internalType":"uint256"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"pair","internalType":"contract LSSVMPairERC20"}],"name":"createPairERC20","inputs":[{"type":"tuple","name":"params","internalType":"struct LSSVMPairFactory.CreateERC20PairParams","components":[{"type":"address","name":"token","internalType":"contract ERC20"},{"type":"address","name":"nft","internalType":"contract IERC721"},{"type":"address","name":"bondingCurve","internalType":"contract ICurve"},{"type":"address","name":"assetRecipient","internalType":"address payable"},{"type":"uint8","name":"poolType","internalType":"enum LSSVMPair.PoolType"},{"type":"uint128","name":"delta","internalType":"uint128"},{"type":"uint96","name":"fee","internalType":"uint96"},{"type":"uint128","name":"spotPrice","internalType":"uint128"},{"type":"uint256[]","name":"initialNFTIDs","internalType":"uint256[]"},{"type":"uint256","name":"initialTokenBalance","internalType":"uint256"}]}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"address","name":"pair","internalType":"contract LSSVMPairETH"}],"name":"createPairETH","inputs":[{"type":"tuple","name":"params","internalType":"struct LSSVMPairFactory.CreatePairETHParams","components":[{"type":"address","name":"nft","internalType":"contract IERC721"},{"type":"address","name":"bondingCurve","internalType":"contract ICurve"},{"type":"address","name":"assetRecipient","internalType":"address payable"},{"type":"uint8","name":"poolType","internalType":"enum LSSVMPair.PoolType"},{"type":"uint128","name":"delta","internalType":"uint128"},{"type":"uint96","name":"fee","internalType":"uint96"},{"type":"uint128","name":"spotPrice","internalType":"uint128"},{"type":"uint256[]","name":"initialNFTIDs","internalType":"uint256[]"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"depositERC20","inputs":[{"type":"address","name":"token","internalType":"contract ERC20"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"depositNFTs","inputs":[{"type":"address","name":"_nft","internalType":"contract IERC721"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"},{"type":"address","name":"recipient","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"depositNFTs1155","inputs":[{"type":"address","name":"_nft","internalType":"contract IERC1155"},{"type":"uint256[]","name":"ids","internalType":"uint256[]"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256[]","name":"counts","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract LSSVMPairEnumerableERC20"}],"name":"enumerableERC20Template","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract LSSVMPairEnumerableETH"}],"name":"enumerableETHTemplate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getNftOperators","inputs":[{"type":"address","name":"nft","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPair","inputs":[{"type":"address","name":"potentialPair","internalType":"address"},{"type":"uint8","name":"variant","internalType":"enum ILSSVMPairFactoryLike.PairVariant"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract LSSVMPair1155MissingEnumerableERC20"}],"name":"missingEnumerable1155ERC20Template","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract LSSVMPair1155MissingEnumerableETH"}],"name":"missingEnumerable1155ETHTemplate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract LSSVMPairMissingEnumerableERC20"}],"name":"missingEnumerableERC20Template","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract LSSVMPairMissingEnumerableETH"}],"name":"missingEnumerableETHTemplate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"operatorProtocolFeeMultipliers","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"operatorProtocolFeeRecipients","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"protocolFeeMultiplier","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"protocolFeeRecipient","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"allowed","internalType":"bool"},{"type":"bool","name":"wasEverAllowed","internalType":"bool"}],"name":"routerStatus","inputs":[{"type":"address","name":"","internalType":"contract LSSVMRouter"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBondingCurveAllowed","inputs":[{"type":"address","name":"bondingCurve","internalType":"contract ICurve"},{"type":"bool","name":"isAllowed","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCallAllowed","inputs":[{"type":"address","name":"target","internalType":"address payable"},{"type":"bool","name":"isAllowed","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setOperatorProtocolFee","inputs":[{"type":"address","name":"nft","internalType":"address"},{"type":"address","name":"operatorProtocolFeeRecipient","internalType":"address"},{"type":"uint256","name":"operatorProtocolFeeMultiplier","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRouterAllowed","inputs":[{"type":"address","name":"_router","internalType":"contract LSSVMRouter"},{"type":"bool","name":"isAllowed","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unauthorize","inputs":[{"type":"address","name":"nft","internalType":"address"},{"type":"address","name":"operator","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawERC20ProtocolFees","inputs":[{"type":"address","name":"token","internalType":"contract ERC20"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawETHProtocolFees","inputs":[]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

0x6101406040523480156200001257600080fd5b50604051620034ca380380620034ca83398101604081905262000035916200018d565b6200004033620000ca565b6001600160a01b0388811660805287811660a05286811660c05285811660e0528481166101005283811661012052600180546001600160a01b03191691841691909117905567016345785d8a0000811115620000b95760405162461bcd60e51b8152600401620000b09062000252565b60405180910390fd5b600255506200027e95505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006001600160a01b0382165b92915050565b600062000127826200011a565b62000145816200012d565b81146200015157600080fd5b50565b805162000127816200013a565b62000145816200011a565b8051620001278162000161565b8062000145565b8051620001278162000179565b600080600080600080600080610100898b031215620001af57620001af600080fd5b6000620001bd8b8b62000154565b9850506020620001d08b828c0162000154565b9750506040620001e38b828c0162000154565b9650506060620001f68b828c0162000154565b9550506080620002098b828c0162000154565b94505060a06200021c8b828c0162000154565b93505060c06200022f8b828c016200016c565b92505060e0620002428b828c0162000180565b9150509295985092959890939650565b602080825281016200012781600d81526c46656520746f6f206c6172676560981b602082015260400190565b60805160a05160c05160e051610100516101205161319a620003306000396000818161048b015281816108f7015261097f01526000818161057a015281816108b301526110900152600081816103c9015281816107e701528181610ee80152610f130152600081816106190152818161079c0152610f390152600081816102250152818161086f0152818161137f01526113aa0152600081816106c40152818161082b01526113d0015261319a6000f3fe6080604052600436106102075760003560e01c806365d0d04f11610118578063a427f1ad116100a0578063b483eddc1161006f578063b483eddc146106e6578063cc5bc20b146106fb578063eaca56331461071b578063ebd0f6931461073b578063f2fde38b1461075b57600080fd5b8063a427f1ad14610607578063a82719c81461063b578063a93ec68b1461066b578063ad2e5770146106b257600080fd5b80637565b6e7116100e75780637565b6e71461054857806387506e87146105685780638da5cb5b1461059c5780639617b70e146105ba5780639c3c11d2146105e757600080fd5b806365d0d04f146104e05780636cc88edb14610500578063715018a6146105205780637235fc1f1461053557600080fd5b80632cdb394b1161019b578063573226a71161016a578063573226a71461040b57806359722caa146104595780635cf96ddb1461047957806361f0a527146104ad57806364df049e146104c057600080fd5b80632cdb394b146103775780634bf107c1146103975780634c6bc433146103b7578063514f0330146103eb57600080fd5b80631cad5a40116101d75780631cad5a40146102ef5780631ce4c78b146103115780631fba95e8146103275780632bef45951461035757600080fd5b80624885ea1461021357806307b3a6a51461025d57806308f25a8f146102a25780630bc3d6a4146102cf57600080fd5b3661020e57005b600080fd5b34801561021f57600080fd5b506102477f000000000000000000000000000000000000000000000000000000000000000081565b60405161025491906124f9565b60405180910390f35b34801561026957600080fd5b50610295610278366004612526565b600460209081526000928352604080842090915290825290205481565b6040516102549190612569565b3480156102ae57600080fd5b506102c26102bd36600461258f565b61077b565b60405161025491906125ca565b3480156102db57600080fd5b506102476102ea3660046125f4565b610926565b3480156102fb57600080fd5b5061030f61030a366004612643565b610ac2565b005b34801561031d57600080fd5b5061029560025481565b34801561033357600080fd5b506102c2610342366004612693565b60076020526000908152604090205460ff1681565b34801561036357600080fd5b5061030f610372366004612526565b610bc0565b34801561038357600080fd5b5061030f610392366004612706565b610c14565b3480156103a357600080fd5b5061030f6103b2366004612789565b610d28565b3480156103c357600080fd5b506102477f000000000000000000000000000000000000000000000000000000000000000081565b3480156103f757600080fd5b5061030f610406366004612693565b610d92565b34801561041757600080fd5b5061044c610426366004612526565b60036020908152600092835260408084209091529082529020546001600160a01b031681565b60405161025491906127c5565b34801561046557600080fd5b506102476104743660046127e9565b610e16565b34801561048557600080fd5b506102477f000000000000000000000000000000000000000000000000000000000000000081565b6102476104bb36600461283a565b611040565b3480156104cc57600080fd5b5060015461044c906001600160a01b031681565b3480156104ec57600080fd5b5061030f6104fb366004612526565b61116c565b34801561050c57600080fd5b5061030f61051b366004612789565b6111d3565b34801561052c57600080fd5b5061030f61129c565b610247610543366004612872565b6112b0565b34801561055457600080fd5b5061030f6105633660046128ad565b6114ae565b34801561057457600080fd5b506102477f000000000000000000000000000000000000000000000000000000000000000081565b3480156105a857600080fd5b506000546001600160a01b031661044c565b3480156105c657600080fd5b506105da6105d5366004612693565b6115db565b60405161025491906129ac565b3480156105f357600080fd5b5061030f6106023660046129bd565b6115ff565b34801561061357600080fd5b506102477f000000000000000000000000000000000000000000000000000000000000000081565b34801561064757600080fd5b506102c26106563660046129de565b60066020526000908152604090205460ff1681565b34801561067757600080fd5b506106a46106863660046129de565b60086020526000908152604090205460ff8082169161010090041682565b6040516102549291906129ff565b3480156106be57600080fd5b506102477f000000000000000000000000000000000000000000000000000000000000000081565b3480156106f257600080fd5b5061030f611664565b34801561070757600080fd5b5061030f610716366004612a1a565b611682565b34801561072757600080fd5b5061030f610736366004612a4d565b6116a4565b34801561074757600080fd5b5061030f610756366004612a71565b61184c565b34801561076757600080fd5b5061030f610776366004612693565b6118ee565b6000600282600581111561079157610791612a93565b036107c8576107c1307f000000000000000000000000000000000000000000000000000000000000000085611928565b9050610920565b60038260058111156107dc576107dc612a93565b0361080c576107c1307f000000000000000000000000000000000000000000000000000000000000000085611928565b600082600581111561082057610820612a93565b03610850576107c1307f0000000000000000000000000000000000000000000000000000000000000000856119a2565b600182600581111561086457610864612a93565b03610894576107c1307f0000000000000000000000000000000000000000000000000000000000000000856119a2565b60048260058111156108a8576108a8612a93565b036108d8576107c1307f000000000000000000000000000000000000000000000000000000000000000085611a1c565b60058260058111156108ec576108ec612a93565b0361091c576107c1307f000000000000000000000000000000000000000000000000000000000000000085611a96565b5060005b92915050565b600060068161093b60608501604086016129de565b6001600160a01b0316815260208101919091526040016000205460ff1661097d5760405162461bcd60e51b815260040161097490612ae0565b60405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000610a0a306109b260608601604087016129de565b6109c260408701602088016129de565b6109d260a0880160808901612b08565b60028111156109e3576109e3612a93565b6109f060208901896129de565b6001600160a01b03871694939291906101008a0135611b10565b9150610a8582610a1d60208601866129de565b610a2d60408701602088016129de565b610a3d6080880160608901612693565b610a4d60c0890160a08a01612b43565b610a5d60e08a0160c08b01612b83565b610a6e6101008b0160e08c01612b43565b8a61010001358b61012001358c6101400135611b9a565b7ff5bdc103c3e68a20d5f97d2d46792d3fdddfa4efeb6761f8141e6a7b936ca66c82604051610ab491906127c5565b60405180910390a150919050565b610ad76001600160a01b038416338484611c88565b610ae282600261077b565b80610af35750610af382600361077b565b80610b045750610b0482600561077b565b15610bbb57816001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6b9190612baf565b6001600160a01b0316836001600160a01b031603610bbb577f831faf3fbb75c9fc66e318de7e95905d24c0430822da168c1c06fd49cba8f5f782604051610bb291906127c5565b60405180910390a15b505050565b610bc8611cee565b6001600160a01b0382166000908152600560205260409020610bea9082611d18565b610c10576001600160a01b0382166000908152600560205260409020610bbb9082611d3d565b5050565b8160005b81811015610ca557856001600160a01b03166342842e0e3385888886818110610c4357610c43612bd0565b905060200201356040518463ffffffff1660e01b8152600401610c6893929190612be6565b600060405180830381600087803b158015610c8257600080fd5b505af1158015610c96573d6000803e3d6000fd5b50505050806001019050610c18565b50610cb182600261077b565b80610cc25750610cc282600061077b565b80610cd35750610cd382600361077b565b80610ce45750610ce482600161077b565b15610d21577f4fd0cd7c14badac45ff0bee670a9d8dd80e87907afcf2c121e0fd4b8b4b0047f82604051610d1891906127c5565b60405180910390a15b5050505050565b610d30611cee565b6001600160a01b03821660009081526006602052604090819020805460ff1916831515179055517f1da28d127ec72d2dde6a533c98857664b25cd827680fb1f39f57394c2b444d9190610d869084908490612c0e565b60405180910390a15050565b610d9a611cee565b6001600160a01b038116610dc05760405162461bcd60e51b815260040161097490612c3c565b600180546001600160a01b0319166001600160a01b0383161790556040517fceec08a75d1f3b12c14c6cdc16c081aec1c401c2eac1d8c6ea91e9d73b92921190610e0b9083906124f9565b60405180910390a150565b6000600681610e2b60608501604086016129de565b6001600160a01b0316815260208101919091526040016000205460ff16610e645760405162461bcd60e51b815260040161097490612ae0565b6000610e7660408401602085016129de565b6001600160a01b03166301ffc9a763780e9d6360e01b6040518263ffffffff1660e01b8152600401610ea89190612c5c565b602060405180830381865afa925050508015610ee1575060408051601f3d908101601f19168201909252610ede91810190612c75565b60015b610f0c57507f0000000000000000000000000000000000000000000000000000000000000000610f5d565b80610f37577f0000000000000000000000000000000000000000000000000000000000000000610f59565b7f00000000000000000000000000000000000000000000000000000000000000005b9150505b610fc330610f7160608601604087016129de565b610f8160408701602088016129de565b610f9160a0880160808901612b08565b6002811115610fa257610fa2612a93565b610faf60208901896129de565b6001600160a01b0387169493929190611d52565b9150610a8582610fd660208601866129de565b610fe660408701602088016129de565b610ff66080880160608901612693565b61100660c0890160a08a01612b43565b61101660e08a0160c08b01612b83565b6110276101008b0160e08c01612b43565b6110356101008c018c612c96565b8c6101200135611dd5565b600060068161105560408501602086016129de565b6001600160a01b0316815260208101919091526040016000205460ff1661108e5760405162461bcd60e51b815260040161097490612ae0565b7f0000000000000000000000000000000000000000000000000000000000000000611109306110c360408601602087016129de565b6110d060208701876129de565b6110e06080880160608901612b08565b60028111156110f1576110f1612a93565b6001600160a01b0386169392919060e0890135611ef0565b9150610a858261111c60208601866129de565b61112c6060870160408801612693565b61113c60a0880160808901612b43565b61114c60c0890160a08a01612b83565b61115c60e08a0160c08b01612b43565b8960e001358a6101000135611f70565b611174611cee565b6001600160a01b03808316600081815260036020908152604080832094861680845294825280832080546001600160a01b031916905583835260048252808320948352938152838220829055918152600590915220610bbb908261205c565b6111db611cee565b801561121a576001600160a01b03821660009081526007602052604090205460ff161561121a5760405162461bcd60e51b815260040161097490612d1b565b6040805180820182528215158152600160208083019182526001600160a01b0386166000908152600890915283902091518254915161ffff1990921690151561ff0019161761010091151591909102179055517f24e274cfd23919da24a57044266685f5474338837aecdcca3136b2102f78fee590610d869084908490612c0e565b6112a4611cee565b6112ae6000612071565b565b60006006816112c560408501602086016129de565b6001600160a01b0316815260208101919091526040016000205460ff166112fe5760405162461bcd60e51b815260040161097490612ae0565b600061130d60208401846129de565b6001600160a01b03166301ffc9a763780e9d6360e01b6040518263ffffffff1660e01b815260040161133f9190612c5c565b602060405180830381865afa925050508015611378575060408051601f3d908101601f1916820190925261137591810190612c75565b60015b6113a357507f00000000000000000000000000000000000000000000000000000000000000006113f4565b806113ce577f00000000000000000000000000000000000000000000000000000000000000006113f0565b7f00000000000000000000000000000000000000000000000000000000000000005b9150505b6114493061140860408601602087016129de565b61141560208701876129de565b6114256080880160608901612b08565b600281111561143657611436612a93565b6001600160a01b038616939291906120c1565b9150610a858261145c60208601866129de565b61146c6060870160408801612693565b61147c60a0880160808901612b43565b61148c60c0890160a08a01612b83565b61149c60e08a0160c08b01612b43565b6114a960e08b018b612c96565b61213a565b8381146114cd5760405162461bcd60e51b815260040161097490612d5f565b8360005b8181101561157857876001600160a01b031663f242432a33878a8a868181106114fc576114fc612bd0565b9050602002013588888781811061151557611515612bd0565b905060200201356040518563ffffffff1660e01b815260040161153b9493929190612d6f565b600060405180830381600087803b15801561155557600080fd5b505af1158015611569573d6000803e3d6000fd5b505050508060010190506114d1565b5061158484600561077b565b80611595575061159584600461077b565b156115d2577f4fd0cd7c14badac45ff0bee670a9d8dd80e87907afcf2c121e0fd4b8b4b0047f846040516115c991906127c5565b60405180910390a15b50505050505050565b6001600160a01b038116600090815260056020526040902060609061092090612251565b611607611cee565b67016345785d8a000081111561162f5760405162461bcd60e51b815260040161097490612de3565b60028190556040517f7c5d30e0df5c540841a598b27bd89807223a2e6348125bb4aa74f1a8cb9ce76890610e0b908390612569565b61166c611cee565b6001546112ae906001600160a01b03164761225e565b61168a611cee565b600154610c10906001600160a01b03848116911683612289565b6001600160a01b03831660009081526005602052604090206116c69033611d18565b6116e25760405162461bcd60e51b815260040161097490612e1f565b67016345785d8a000081111561170a5760405162461bcd60e51b815260040161097490612e63565b6001600160a01b0383811660008181526003602090815260408083203380855290835281842080546001600160a01b0319169689169690961790955583835260048252808320948352938152838220859055918152600590915290812061177090612251565b90506000805b82518110156117ec576001600160a01b038616600090815260046020526040812084519091908590849081106117ae576117ae612bd0565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054826117e29190612e89565b9150600101611776565b5067058d15e1762800008111156118155760405162461bcd60e51b815260040161097490612ee6565b7fdc2660390ef65d8c05512fd9bf8414e27dd0e0232c2c6725dda9c177f372d87a8533868685604051610d18959493929190612ef6565b611854611cee565b8015611898576001600160a01b038216600090815260086020526040902054610100900460ff16156118985760405162461bcd60e51b815260040161097490612d1b565b6001600160a01b03821660009081526007602052604090819020805460ff1916831515179055517fab2e2e8d21d5efbffb30945e9b6ee1fb43620ef65a228f871f5028bf8a6e004a90610d869084908490612c0e565b6118f6611cee565b6001600160a01b03811661191c5760405162461bcd60e51b815260040161097490612f7b565b61192581612071565b50565b6000604051733d3d3d3d363d3d37605160353639366051013d7360601b81528360601b60148201526c5af43d3d93803e603357fd5bf360981b60288201528460601b6035820152604981016049600082863c6029810151602983015114602082015160208401511416815183511416925050509392505050565b6000604051733d3d3d3d363d3d37603d6035363936603d013d7360601b81528360601b60148201526c5af43d3d93803e603357fd5bf360981b60288201528460601b6035820152604981016049600082863c6029810151602983015114602082015160208401511416815183511416925050509392505050565b6000604051733d3d3d3d363d3d37605d6035363936605d013d7360601b81528360601b60148201526c5af43d3d93803e603357fd5bf360981b60288201528460601b6035820152604981016049600082863c6029810151602983015114602082015160208401511416815183511416925050509392505050565b6000604051733d3d3d3d363d3d37607160353639366071013d7360601b81528360601b60148201526c5af43d3d93803e603357fd5bf360981b60288201528460601b6035820152604981016049600082863c6029810151602983015114602082015160208401511416815183511416925050509392505050565b60006040517f60a63d8160093d39f33d3d3d3d363d3d37607160353639366071013d7300000081528860601b601d8201526c5af43d3d93803e603357fd5bf360981b60318201528760601b603e8201528660601b60528201528560601b606682015284607a8201538360601b607b82015282608f82015260af816000f09998505050505050505050565b604051633f03961560e11b81526001600160a01b038b1690637e072c2a90611bd09033908b908b908b908b908b90600401612fae565b600060405180830381600087803b158015611bea57600080fd5b505af1158015611bfe573d6000803e3d6000fd5b50611c18925050506001600160a01b038a16338c84611c88565b604051637921219560e11b81526001600160a01b0389169063f242432a90611c4a9033908e9088908890600401612d6f565b600060405180830381600087803b158015611c6457600080fd5b505af1158015611c78573d6000803e3d6000fd5b5050505050505050505050505050565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af1915050611cd2816122e6565b610d215760405162461bcd60e51b815260040161097490613033565b6000546001600160a01b031633146112ae5760405162461bcd60e51b815260040161097490613075565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b6000611d36836001600160a01b03841661232d565b60006040517f60863d8160093d39f33d3d3d3d363d3d37605160353639366051013d7300000081528760601b601d8201526c5af43d3d93803e603357fd5bf360981b60318201528660601b603e8201528560601b60528201528460601b606682015283607a8201538260601b607b820152608f816000f098975050505050505050565b60405163fd17aef960e01b81526001600160a01b038b169063fd17aef990611e099033908b908b908b908b90600401613085565b600060405180830381600087803b158015611e2357600080fd5b505af1158015611e37573d6000803e3d6000fd5b50611e51925050506001600160a01b038a16338c84611c88565b8160005b81811015611ee257896001600160a01b03166342842e0e338e888886818110611e8057611e80612bd0565b905060200201356040518463ffffffff1660e01b8152600401611ea593929190612be6565b600060405180830381600087803b158015611ebf57600080fd5b505af1158015611ed3573d6000803e3d6000fd5b50505050806001019050611e55565b505050505050505050505050565b60006040517f60923d8160093d39f33d3d3d3d363d3d37605d6035363936605d013d7300000081528760601b601d8201526c5af43d3d93803e603357fd5bf360981b60318201528660601b603e8201528560601b60528201528460601b606682015283607a82015382607b820152609b816000f098975050505050505050565b604051633f03961560e11b81526001600160a01b03891690637e072c2a90611fa69033908a908a908a908a908a90600401612fae565b600060405180830381600087803b158015611fc057600080fd5b505af1158015611fd4573d6000803e3d6000fd5b50611fec925050506001600160a01b0389163461225e565b801561205257604051637921219560e11b81526001600160a01b0388169063f242432a906120249033908c9087908790600401612d6f565b600060405180830381600087803b15801561203e57600080fd5b505af1158015611ee2573d6000803e3d6000fd5b5050505050505050565b6000611d36836001600160a01b038416612374565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006040517f60723d8160093d39f33d3d3d3d363d3d37603d6035363936603d013d7300000081528660601b601d8201526c5af43d3d93803e603357fd5bf360981b60318201528560601b603e8201528460601b60528201528360601b606682015282607a820153607b816000f0979650505050505050565b60405163fd17aef960e01b81526001600160a01b0389169063fd17aef99061216e9033908a908a908a908a90600401613085565b600060405180830381600087803b15801561218857600080fd5b505af115801561219c573d6000803e3d6000fd5b506121b4925050506001600160a01b0389163461225e565b8060005b8181101561224557886001600160a01b03166342842e0e338c8787868181106121e3576121e3612bd0565b905060200201356040518463ffffffff1660e01b815260040161220893929190612be6565b600060405180830381600087803b15801561222257600080fd5b505af1158015612236573d6000803e3d6000fd5b505050508060010190506121b8565b50505050505050505050565b60606000611d3683612467565b600080600080600085875af1905080610bbb5760405162461bcd60e51b8152600401610974906130f1565b600060405163a9059cbb60e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506122c4816122e6565b6122e05760405162461bcd60e51b815260040161097490613127565b50505050565b60003d826122f857806000803e806000fd5b80602081146123105780156123215760009250612326565b816000803e60005115159250612326565b600192505b5050919050565b600081815260018301602052604081205461091c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610920565b6000818152600183016020526040812054801561245d576000612398600183613137565b85549091506000906123ac90600190613137565b90508181146124115760008660000182815481106123cc576123cc612bd0565b90600052602060002001549050808760000184815481106123ef576123ef612bd0565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806124225761242261314e565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610920565b6000915050610920565b6060816000018054806020026020016040519081016040528092919081815260200182805480156124b757602002820191906000526020600020905b8154815260200190600101908083116124a3575b50505050509050919050565b60006001600160a01b038216610920565b6000610920826124c3565b6000610920826124d4565b6124f3816124df565b82525050565b6020810161092082846124ea565b612510816124c3565b811461192557600080fd5b803561092081612507565b6000806040838503121561253c5761253c600080fd5b6000612548858561251b565b92505060206125598582860161251b565b9150509250929050565b806124f3565b602081016109208284612563565b6006811061192557600080fd5b803561092081612577565b600080604083850312156125a5576125a5600080fd5b60006125b1858561251b565b925050602061255985828601612584565b8015156124f3565b6020810161092082846125c2565b600061016082840312156125ee576125ee600080fd5b50919050565b6000610160828403121561260a5761260a600080fd5b600061261684846125d8565b949350505050565b612510816124d4565b80356109208161261e565b80612510565b803561092081612632565b60008060006060848603121561265b5761265b600080fd5b60006126678686612627565b93505060206126788682870161251b565b925050604061268986828701612638565b9150509250925092565b6000602082840312156126a8576126a8600080fd5b6000612616848461251b565b60008083601f8401126126c9576126c9600080fd5b50813567ffffffffffffffff8111156126e4576126e4600080fd5b6020830191508360208202830111156126ff576126ff600080fd5b9250929050565b6000806000806060858703121561271f5761271f600080fd5b600061272b8787612627565b945050602085013567ffffffffffffffff81111561274b5761274b600080fd5b612757878288016126b4565b9350935050604061276a8782880161251b565b91505092959194509250565b801515612510565b803561092081612776565b6000806040838503121561279f5761279f600080fd5b60006127ab8585612627565b92505060206125598582860161277e565b6124f3816124c3565b6020810161092082846127bc565b600061014082840312156125ee576125ee600080fd5b6000602082840312156127fe576127fe600080fd5b813567ffffffffffffffff81111561281857612818600080fd5b612616848285016127d3565b600061012082840312156125ee576125ee600080fd5b6000610120828403121561285057612850600080fd5b60006126168484612824565b600061010082840312156125ee576125ee600080fd5b60006020828403121561288757612887600080fd5b813567ffffffffffffffff8111156128a1576128a1600080fd5b6126168482850161285c565b600080600080600080608087890312156128c9576128c9600080fd5b60006128d58989612627565b965050602087013567ffffffffffffffff8111156128f5576128f5600080fd5b61290189828a016126b4565b9550955050604061291489828a0161251b565b935050606087013567ffffffffffffffff81111561293457612934600080fd5b61294089828a016126b4565b92509250509295509295509295565b600061295b83836127bc565b505060200190565b600061296d825190565b80845260209384019383018060005b838110156129a1578151612990888261294f565b97506020830192505060010161297c565b509495945050505050565b60208082528101611d368184612963565b6000602082840312156129d2576129d2600080fd5b60006126168484612638565b6000602082840312156129f3576129f3600080fd5b60006126168484612627565b60408101612a0d82856125c2565b611d3660208301846125c2565b60008060408385031215612a3057612a30600080fd5b6000612a3c8585612627565b925050602061255985828601612638565b600080600060608486031215612a6557612a65600080fd5b6000612667868661251b565b60008060408385031215612a8757612a87600080fd5b60006127ab858561251b565b634e487b7160e01b600052602160045260246000fd5b601d81526000602082017f426f6e64696e67206375727665206e6f742077686974656c6973746564000000815291505b5060200190565b6020808252810161092081612aa9565b6003811061192557600080fd5b803561092081612af0565b600060208284031215612b1d57612b1d600080fd5b60006126168484612afd565b6001600160801b038116612510565b803561092081612b29565b600060208284031215612b5857612b58600080fd5b60006126168484612b38565b6bffffffffffffffffffffffff8116612510565b803561092081612b64565b600060208284031215612b9857612b98600080fd5b60006126168484612b78565b80516109208161261e565b600060208284031215612bc457612bc4600080fd5b60006126168484612ba4565b634e487b7160e01b600052603260045260246000fd5b60608101612bf482866127bc565b612c0160208301856127bc565b6126166040830184612563565b60408101612a0d82856124ea565b600981526000602082016830206164647265737360b81b81529150612ad9565b6020808252810161092081612c1c565b6001600160e01b031981166124f3565b602081016109208284612c4c565b805161092081612776565b600060208284031215612c8a57612c8a600080fd5b60006126168484612c6a565b6000808335601e1936859003018112612cb157612cb1600080fd5b80840192508235915067ffffffffffffffff821115612cd257612cd2600080fd5b60209283019282023603831315612ceb57612ceb600080fd5b509250929050565b601181526000602082017021b0b713ba1031b0b636103937baba32b960791b81529150612ad9565b6020808252810161092081612cf3565b601e81526000602082017f6e667420616e6420636f756e74206c656e677468206d7573742073616d65000081529150612ad9565b6020808252810161092081612d2b565b60a08101612d7d82876127bc565b612d8a60208301866127bc565b612d976040830185612563565b612da46060830184612563565b818103608083015260008152602081015b9695505050505050565b600d81526000602082016c46656520746f6f206c6172676560981b81529150612ad9565b6020808252810161092081612dbf565b60158152600060208201743ab730baba3437b934bd32b21037b832b930ba37b960591b81529150612ad9565b6020808252810161092081612df3565b601f81526000602082017f4f70657261746f722070726f746f636f6c2066656520746f6f206c617267650081529150612ad9565b6020808252810161092081612e2f565b634e487b7160e01b600052601160045260246000fd5b60008219821115612e9c57612e9c612e73565b500190565b602581526000602082017f546f74616c206f70657261746f722070726f746f636f6c2066656520746f6f208152646c6172676560d81b602082015291505b5060400190565b6020808252810161092081612ea1565b60a08101612f0482886127bc565b612f1160208301876127bc565b612f1e60408301866127bc565b612f2b6060830185612563565b612db56080830184612563565b602681526000602082017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b60208201529150612edf565b6020808252810161092081612f38565b6001600160801b0381166124f3565b6bffffffffffffffffffffffff81166124f3565b60c08101612fbc82896127bc565b612fc960208301886127bc565b612fd66040830187612f8b565b612fe36060830186612f9a565b612ff06080830185612f8b565b612ffd60a0830184612563565b979650505050505050565b60148152600060208201731514905394d1915497d19493d357d1905253115160621b81529150612ad9565b6020808252810161092081613008565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657291019081526000612ad9565b6020808252810161092081613043565b60a0810161309382886127bc565b6130a060208301876127bc565b6130ad6040830186612f8b565b6130ba6060830185612f9a565b612db56080830184612f8b565b601381526000602082017211551217d514905394d1915497d19052531151606a1b81529150612ad9565b60208082528101610920816130c7565b600f81526000602082016e1514905394d1915497d19052531151608a1b81529150612ad9565b6020808252810161092081613101565b60008282101561314957613149612e73565b500390565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220922b14f6bed1570a30b9f95b3b46cee53a4d319a6e2416f1f8c66da0486f4ed664736f6c634300080d00330000000000000000000000004f65da64c4b1cad8f58fdf06a55bca73e6a840ec000000000000000000000000523c60dbc05feeba61f28eef1f6db3770e3034d000000000000000000000000056d990d832ba60deb6f45d6769c7cf4727fc86a20000000000000000000000000724fb6d3cdbd560a805850a87e9544e461d1b0e000000000000000000000000487b214a849ef6c5cf21793ead9468848f451a440000000000000000000000000c4401940338396b2f75ba419bfbd7c6f18068f100000000000000000000000094a47b89c600962eff6f4cf53dfd05aa05b522b5000000000000000000000000000000000000000000000000002386f26fc10000

Deployed ByteCode

0x6080604052600436106102075760003560e01c806365d0d04f11610118578063a427f1ad116100a0578063b483eddc1161006f578063b483eddc146106e6578063cc5bc20b146106fb578063eaca56331461071b578063ebd0f6931461073b578063f2fde38b1461075b57600080fd5b8063a427f1ad14610607578063a82719c81461063b578063a93ec68b1461066b578063ad2e5770146106b257600080fd5b80637565b6e7116100e75780637565b6e71461054857806387506e87146105685780638da5cb5b1461059c5780639617b70e146105ba5780639c3c11d2146105e757600080fd5b806365d0d04f146104e05780636cc88edb14610500578063715018a6146105205780637235fc1f1461053557600080fd5b80632cdb394b1161019b578063573226a71161016a578063573226a71461040b57806359722caa146104595780635cf96ddb1461047957806361f0a527146104ad57806364df049e146104c057600080fd5b80632cdb394b146103775780634bf107c1146103975780634c6bc433146103b7578063514f0330146103eb57600080fd5b80631cad5a40116101d75780631cad5a40146102ef5780631ce4c78b146103115780631fba95e8146103275780632bef45951461035757600080fd5b80624885ea1461021357806307b3a6a51461025d57806308f25a8f146102a25780630bc3d6a4146102cf57600080fd5b3661020e57005b600080fd5b34801561021f57600080fd5b506102477f000000000000000000000000523c60dbc05feeba61f28eef1f6db3770e3034d081565b60405161025491906124f9565b60405180910390f35b34801561026957600080fd5b50610295610278366004612526565b600460209081526000928352604080842090915290825290205481565b6040516102549190612569565b3480156102ae57600080fd5b506102c26102bd36600461258f565b61077b565b60405161025491906125ca565b3480156102db57600080fd5b506102476102ea3660046125f4565b610926565b3480156102fb57600080fd5b5061030f61030a366004612643565b610ac2565b005b34801561031d57600080fd5b5061029560025481565b34801561033357600080fd5b506102c2610342366004612693565b60076020526000908152604090205460ff1681565b34801561036357600080fd5b5061030f610372366004612526565b610bc0565b34801561038357600080fd5b5061030f610392366004612706565b610c14565b3480156103a357600080fd5b5061030f6103b2366004612789565b610d28565b3480156103c357600080fd5b506102477f0000000000000000000000000724fb6d3cdbd560a805850a87e9544e461d1b0e81565b3480156103f757600080fd5b5061030f610406366004612693565b610d92565b34801561041757600080fd5b5061044c610426366004612526565b60036020908152600092835260408084209091529082529020546001600160a01b031681565b60405161025491906127c5565b34801561046557600080fd5b506102476104743660046127e9565b610e16565b34801561048557600080fd5b506102477f0000000000000000000000000c4401940338396b2f75ba419bfbd7c6f18068f181565b6102476104bb36600461283a565b611040565b3480156104cc57600080fd5b5060015461044c906001600160a01b031681565b3480156104ec57600080fd5b5061030f6104fb366004612526565b61116c565b34801561050c57600080fd5b5061030f61051b366004612789565b6111d3565b34801561052c57600080fd5b5061030f61129c565b610247610543366004612872565b6112b0565b34801561055457600080fd5b5061030f6105633660046128ad565b6114ae565b34801561057457600080fd5b506102477f000000000000000000000000487b214a849ef6c5cf21793ead9468848f451a4481565b3480156105a857600080fd5b506000546001600160a01b031661044c565b3480156105c657600080fd5b506105da6105d5366004612693565b6115db565b60405161025491906129ac565b3480156105f357600080fd5b5061030f6106023660046129bd565b6115ff565b34801561061357600080fd5b506102477f00000000000000000000000056d990d832ba60deb6f45d6769c7cf4727fc86a281565b34801561064757600080fd5b506102c26106563660046129de565b60066020526000908152604090205460ff1681565b34801561067757600080fd5b506106a46106863660046129de565b60086020526000908152604090205460ff8082169161010090041682565b6040516102549291906129ff565b3480156106be57600080fd5b506102477f0000000000000000000000004f65da64c4b1cad8f58fdf06a55bca73e6a840ec81565b3480156106f257600080fd5b5061030f611664565b34801561070757600080fd5b5061030f610716366004612a1a565b611682565b34801561072757600080fd5b5061030f610736366004612a4d565b6116a4565b34801561074757600080fd5b5061030f610756366004612a71565b61184c565b34801561076757600080fd5b5061030f610776366004612693565b6118ee565b6000600282600581111561079157610791612a93565b036107c8576107c1307f00000000000000000000000056d990d832ba60deb6f45d6769c7cf4727fc86a285611928565b9050610920565b60038260058111156107dc576107dc612a93565b0361080c576107c1307f0000000000000000000000000724fb6d3cdbd560a805850a87e9544e461d1b0e85611928565b600082600581111561082057610820612a93565b03610850576107c1307f0000000000000000000000004f65da64c4b1cad8f58fdf06a55bca73e6a840ec856119a2565b600182600581111561086457610864612a93565b03610894576107c1307f000000000000000000000000523c60dbc05feeba61f28eef1f6db3770e3034d0856119a2565b60048260058111156108a8576108a8612a93565b036108d8576107c1307f000000000000000000000000487b214a849ef6c5cf21793ead9468848f451a4485611a1c565b60058260058111156108ec576108ec612a93565b0361091c576107c1307f0000000000000000000000000c4401940338396b2f75ba419bfbd7c6f18068f185611a96565b5060005b92915050565b600060068161093b60608501604086016129de565b6001600160a01b0316815260208101919091526040016000205460ff1661097d5760405162461bcd60e51b815260040161097490612ae0565b60405180910390fd5b7f0000000000000000000000000c4401940338396b2f75ba419bfbd7c6f18068f1610a0a306109b260608601604087016129de565b6109c260408701602088016129de565b6109d260a0880160808901612b08565b60028111156109e3576109e3612a93565b6109f060208901896129de565b6001600160a01b03871694939291906101008a0135611b10565b9150610a8582610a1d60208601866129de565b610a2d60408701602088016129de565b610a3d6080880160608901612693565b610a4d60c0890160a08a01612b43565b610a5d60e08a0160c08b01612b83565b610a6e6101008b0160e08c01612b43565b8a61010001358b61012001358c6101400135611b9a565b7ff5bdc103c3e68a20d5f97d2d46792d3fdddfa4efeb6761f8141e6a7b936ca66c82604051610ab491906127c5565b60405180910390a150919050565b610ad76001600160a01b038416338484611c88565b610ae282600261077b565b80610af35750610af382600361077b565b80610b045750610b0482600561077b565b15610bbb57816001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6b9190612baf565b6001600160a01b0316836001600160a01b031603610bbb577f831faf3fbb75c9fc66e318de7e95905d24c0430822da168c1c06fd49cba8f5f782604051610bb291906127c5565b60405180910390a15b505050565b610bc8611cee565b6001600160a01b0382166000908152600560205260409020610bea9082611d18565b610c10576001600160a01b0382166000908152600560205260409020610bbb9082611d3d565b5050565b8160005b81811015610ca557856001600160a01b03166342842e0e3385888886818110610c4357610c43612bd0565b905060200201356040518463ffffffff1660e01b8152600401610c6893929190612be6565b600060405180830381600087803b158015610c8257600080fd5b505af1158015610c96573d6000803e3d6000fd5b50505050806001019050610c18565b50610cb182600261077b565b80610cc25750610cc282600061077b565b80610cd35750610cd382600361077b565b80610ce45750610ce482600161077b565b15610d21577f4fd0cd7c14badac45ff0bee670a9d8dd80e87907afcf2c121e0fd4b8b4b0047f82604051610d1891906127c5565b60405180910390a15b5050505050565b610d30611cee565b6001600160a01b03821660009081526006602052604090819020805460ff1916831515179055517f1da28d127ec72d2dde6a533c98857664b25cd827680fb1f39f57394c2b444d9190610d869084908490612c0e565b60405180910390a15050565b610d9a611cee565b6001600160a01b038116610dc05760405162461bcd60e51b815260040161097490612c3c565b600180546001600160a01b0319166001600160a01b0383161790556040517fceec08a75d1f3b12c14c6cdc16c081aec1c401c2eac1d8c6ea91e9d73b92921190610e0b9083906124f9565b60405180910390a150565b6000600681610e2b60608501604086016129de565b6001600160a01b0316815260208101919091526040016000205460ff16610e645760405162461bcd60e51b815260040161097490612ae0565b6000610e7660408401602085016129de565b6001600160a01b03166301ffc9a763780e9d6360e01b6040518263ffffffff1660e01b8152600401610ea89190612c5c565b602060405180830381865afa925050508015610ee1575060408051601f3d908101601f19168201909252610ede91810190612c75565b60015b610f0c57507f0000000000000000000000000724fb6d3cdbd560a805850a87e9544e461d1b0e610f5d565b80610f37577f0000000000000000000000000724fb6d3cdbd560a805850a87e9544e461d1b0e610f59565b7f00000000000000000000000056d990d832ba60deb6f45d6769c7cf4727fc86a25b9150505b610fc330610f7160608601604087016129de565b610f8160408701602088016129de565b610f9160a0880160808901612b08565b6002811115610fa257610fa2612a93565b610faf60208901896129de565b6001600160a01b0387169493929190611d52565b9150610a8582610fd660208601866129de565b610fe660408701602088016129de565b610ff66080880160608901612693565b61100660c0890160a08a01612b43565b61101660e08a0160c08b01612b83565b6110276101008b0160e08c01612b43565b6110356101008c018c612c96565b8c6101200135611dd5565b600060068161105560408501602086016129de565b6001600160a01b0316815260208101919091526040016000205460ff1661108e5760405162461bcd60e51b815260040161097490612ae0565b7f000000000000000000000000487b214a849ef6c5cf21793ead9468848f451a44611109306110c360408601602087016129de565b6110d060208701876129de565b6110e06080880160608901612b08565b60028111156110f1576110f1612a93565b6001600160a01b0386169392919060e0890135611ef0565b9150610a858261111c60208601866129de565b61112c6060870160408801612693565b61113c60a0880160808901612b43565b61114c60c0890160a08a01612b83565b61115c60e08a0160c08b01612b43565b8960e001358a6101000135611f70565b611174611cee565b6001600160a01b03808316600081815260036020908152604080832094861680845294825280832080546001600160a01b031916905583835260048252808320948352938152838220829055918152600590915220610bbb908261205c565b6111db611cee565b801561121a576001600160a01b03821660009081526007602052604090205460ff161561121a5760405162461bcd60e51b815260040161097490612d1b565b6040805180820182528215158152600160208083019182526001600160a01b0386166000908152600890915283902091518254915161ffff1990921690151561ff0019161761010091151591909102179055517f24e274cfd23919da24a57044266685f5474338837aecdcca3136b2102f78fee590610d869084908490612c0e565b6112a4611cee565b6112ae6000612071565b565b60006006816112c560408501602086016129de565b6001600160a01b0316815260208101919091526040016000205460ff166112fe5760405162461bcd60e51b815260040161097490612ae0565b600061130d60208401846129de565b6001600160a01b03166301ffc9a763780e9d6360e01b6040518263ffffffff1660e01b815260040161133f9190612c5c565b602060405180830381865afa925050508015611378575060408051601f3d908101601f1916820190925261137591810190612c75565b60015b6113a357507f000000000000000000000000523c60dbc05feeba61f28eef1f6db3770e3034d06113f4565b806113ce577f000000000000000000000000523c60dbc05feeba61f28eef1f6db3770e3034d06113f0565b7f0000000000000000000000004f65da64c4b1cad8f58fdf06a55bca73e6a840ec5b9150505b6114493061140860408601602087016129de565b61141560208701876129de565b6114256080880160608901612b08565b600281111561143657611436612a93565b6001600160a01b038616939291906120c1565b9150610a858261145c60208601866129de565b61146c6060870160408801612693565b61147c60a0880160808901612b43565b61148c60c0890160a08a01612b83565b61149c60e08a0160c08b01612b43565b6114a960e08b018b612c96565b61213a565b8381146114cd5760405162461bcd60e51b815260040161097490612d5f565b8360005b8181101561157857876001600160a01b031663f242432a33878a8a868181106114fc576114fc612bd0565b9050602002013588888781811061151557611515612bd0565b905060200201356040518563ffffffff1660e01b815260040161153b9493929190612d6f565b600060405180830381600087803b15801561155557600080fd5b505af1158015611569573d6000803e3d6000fd5b505050508060010190506114d1565b5061158484600561077b565b80611595575061159584600461077b565b156115d2577f4fd0cd7c14badac45ff0bee670a9d8dd80e87907afcf2c121e0fd4b8b4b0047f846040516115c991906127c5565b60405180910390a15b50505050505050565b6001600160a01b038116600090815260056020526040902060609061092090612251565b611607611cee565b67016345785d8a000081111561162f5760405162461bcd60e51b815260040161097490612de3565b60028190556040517f7c5d30e0df5c540841a598b27bd89807223a2e6348125bb4aa74f1a8cb9ce76890610e0b908390612569565b61166c611cee565b6001546112ae906001600160a01b03164761225e565b61168a611cee565b600154610c10906001600160a01b03848116911683612289565b6001600160a01b03831660009081526005602052604090206116c69033611d18565b6116e25760405162461bcd60e51b815260040161097490612e1f565b67016345785d8a000081111561170a5760405162461bcd60e51b815260040161097490612e63565b6001600160a01b0383811660008181526003602090815260408083203380855290835281842080546001600160a01b0319169689169690961790955583835260048252808320948352938152838220859055918152600590915290812061177090612251565b90506000805b82518110156117ec576001600160a01b038616600090815260046020526040812084519091908590849081106117ae576117ae612bd0565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054826117e29190612e89565b9150600101611776565b5067058d15e1762800008111156118155760405162461bcd60e51b815260040161097490612ee6565b7fdc2660390ef65d8c05512fd9bf8414e27dd0e0232c2c6725dda9c177f372d87a8533868685604051610d18959493929190612ef6565b611854611cee565b8015611898576001600160a01b038216600090815260086020526040902054610100900460ff16156118985760405162461bcd60e51b815260040161097490612d1b565b6001600160a01b03821660009081526007602052604090819020805460ff1916831515179055517fab2e2e8d21d5efbffb30945e9b6ee1fb43620ef65a228f871f5028bf8a6e004a90610d869084908490612c0e565b6118f6611cee565b6001600160a01b03811661191c5760405162461bcd60e51b815260040161097490612f7b565b61192581612071565b50565b6000604051733d3d3d3d363d3d37605160353639366051013d7360601b81528360601b60148201526c5af43d3d93803e603357fd5bf360981b60288201528460601b6035820152604981016049600082863c6029810151602983015114602082015160208401511416815183511416925050509392505050565b6000604051733d3d3d3d363d3d37603d6035363936603d013d7360601b81528360601b60148201526c5af43d3d93803e603357fd5bf360981b60288201528460601b6035820152604981016049600082863c6029810151602983015114602082015160208401511416815183511416925050509392505050565b6000604051733d3d3d3d363d3d37605d6035363936605d013d7360601b81528360601b60148201526c5af43d3d93803e603357fd5bf360981b60288201528460601b6035820152604981016049600082863c6029810151602983015114602082015160208401511416815183511416925050509392505050565b6000604051733d3d3d3d363d3d37607160353639366071013d7360601b81528360601b60148201526c5af43d3d93803e603357fd5bf360981b60288201528460601b6035820152604981016049600082863c6029810151602983015114602082015160208401511416815183511416925050509392505050565b60006040517f60a63d8160093d39f33d3d3d3d363d3d37607160353639366071013d7300000081528860601b601d8201526c5af43d3d93803e603357fd5bf360981b60318201528760601b603e8201528660601b60528201528560601b606682015284607a8201538360601b607b82015282608f82015260af816000f09998505050505050505050565b604051633f03961560e11b81526001600160a01b038b1690637e072c2a90611bd09033908b908b908b908b908b90600401612fae565b600060405180830381600087803b158015611bea57600080fd5b505af1158015611bfe573d6000803e3d6000fd5b50611c18925050506001600160a01b038a16338c84611c88565b604051637921219560e11b81526001600160a01b0389169063f242432a90611c4a9033908e9088908890600401612d6f565b600060405180830381600087803b158015611c6457600080fd5b505af1158015611c78573d6000803e3d6000fd5b5050505050505050505050505050565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af1915050611cd2816122e6565b610d215760405162461bcd60e51b815260040161097490613033565b6000546001600160a01b031633146112ae5760405162461bcd60e51b815260040161097490613075565b6001600160a01b038116600090815260018301602052604081205415155b9392505050565b6000611d36836001600160a01b03841661232d565b60006040517f60863d8160093d39f33d3d3d3d363d3d37605160353639366051013d7300000081528760601b601d8201526c5af43d3d93803e603357fd5bf360981b60318201528660601b603e8201528560601b60528201528460601b606682015283607a8201538260601b607b820152608f816000f098975050505050505050565b60405163fd17aef960e01b81526001600160a01b038b169063fd17aef990611e099033908b908b908b908b90600401613085565b600060405180830381600087803b158015611e2357600080fd5b505af1158015611e37573d6000803e3d6000fd5b50611e51925050506001600160a01b038a16338c84611c88565b8160005b81811015611ee257896001600160a01b03166342842e0e338e888886818110611e8057611e80612bd0565b905060200201356040518463ffffffff1660e01b8152600401611ea593929190612be6565b600060405180830381600087803b158015611ebf57600080fd5b505af1158015611ed3573d6000803e3d6000fd5b50505050806001019050611e55565b505050505050505050505050565b60006040517f60923d8160093d39f33d3d3d3d363d3d37605d6035363936605d013d7300000081528760601b601d8201526c5af43d3d93803e603357fd5bf360981b60318201528660601b603e8201528560601b60528201528460601b606682015283607a82015382607b820152609b816000f098975050505050505050565b604051633f03961560e11b81526001600160a01b03891690637e072c2a90611fa69033908a908a908a908a908a90600401612fae565b600060405180830381600087803b158015611fc057600080fd5b505af1158015611fd4573d6000803e3d6000fd5b50611fec925050506001600160a01b0389163461225e565b801561205257604051637921219560e11b81526001600160a01b0388169063f242432a906120249033908c9087908790600401612d6f565b600060405180830381600087803b15801561203e57600080fd5b505af1158015611ee2573d6000803e3d6000fd5b5050505050505050565b6000611d36836001600160a01b038416612374565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006040517f60723d8160093d39f33d3d3d3d363d3d37603d6035363936603d013d7300000081528660601b601d8201526c5af43d3d93803e603357fd5bf360981b60318201528560601b603e8201528460601b60528201528360601b606682015282607a820153607b816000f0979650505050505050565b60405163fd17aef960e01b81526001600160a01b0389169063fd17aef99061216e9033908a908a908a908a90600401613085565b600060405180830381600087803b15801561218857600080fd5b505af115801561219c573d6000803e3d6000fd5b506121b4925050506001600160a01b0389163461225e565b8060005b8181101561224557886001600160a01b03166342842e0e338c8787868181106121e3576121e3612bd0565b905060200201356040518463ffffffff1660e01b815260040161220893929190612be6565b600060405180830381600087803b15801561222257600080fd5b505af1158015612236573d6000803e3d6000fd5b505050508060010190506121b8565b50505050505050505050565b60606000611d3683612467565b600080600080600085875af1905080610bbb5760405162461bcd60e51b8152600401610974906130f1565b600060405163a9059cbb60e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506122c4816122e6565b6122e05760405162461bcd60e51b815260040161097490613127565b50505050565b60003d826122f857806000803e806000fd5b80602081146123105780156123215760009250612326565b816000803e60005115159250612326565b600192505b5050919050565b600081815260018301602052604081205461091c57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610920565b6000818152600183016020526040812054801561245d576000612398600183613137565b85549091506000906123ac90600190613137565b90508181146124115760008660000182815481106123cc576123cc612bd0565b90600052602060002001549050808760000184815481106123ef576123ef612bd0565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806124225761242261314e565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610920565b6000915050610920565b6060816000018054806020026020016040519081016040528092919081815260200182805480156124b757602002820191906000526020600020905b8154815260200190600101908083116124a3575b50505050509050919050565b60006001600160a01b038216610920565b6000610920826124c3565b6000610920826124d4565b6124f3816124df565b82525050565b6020810161092082846124ea565b612510816124c3565b811461192557600080fd5b803561092081612507565b6000806040838503121561253c5761253c600080fd5b6000612548858561251b565b92505060206125598582860161251b565b9150509250929050565b806124f3565b602081016109208284612563565b6006811061192557600080fd5b803561092081612577565b600080604083850312156125a5576125a5600080fd5b60006125b1858561251b565b925050602061255985828601612584565b8015156124f3565b6020810161092082846125c2565b600061016082840312156125ee576125ee600080fd5b50919050565b6000610160828403121561260a5761260a600080fd5b600061261684846125d8565b949350505050565b612510816124d4565b80356109208161261e565b80612510565b803561092081612632565b60008060006060848603121561265b5761265b600080fd5b60006126678686612627565b93505060206126788682870161251b565b925050604061268986828701612638565b9150509250925092565b6000602082840312156126a8576126a8600080fd5b6000612616848461251b565b60008083601f8401126126c9576126c9600080fd5b50813567ffffffffffffffff8111156126e4576126e4600080fd5b6020830191508360208202830111156126ff576126ff600080fd5b9250929050565b6000806000806060858703121561271f5761271f600080fd5b600061272b8787612627565b945050602085013567ffffffffffffffff81111561274b5761274b600080fd5b612757878288016126b4565b9350935050604061276a8782880161251b565b91505092959194509250565b801515612510565b803561092081612776565b6000806040838503121561279f5761279f600080fd5b60006127ab8585612627565b92505060206125598582860161277e565b6124f3816124c3565b6020810161092082846127bc565b600061014082840312156125ee576125ee600080fd5b6000602082840312156127fe576127fe600080fd5b813567ffffffffffffffff81111561281857612818600080fd5b612616848285016127d3565b600061012082840312156125ee576125ee600080fd5b6000610120828403121561285057612850600080fd5b60006126168484612824565b600061010082840312156125ee576125ee600080fd5b60006020828403121561288757612887600080fd5b813567ffffffffffffffff8111156128a1576128a1600080fd5b6126168482850161285c565b600080600080600080608087890312156128c9576128c9600080fd5b60006128d58989612627565b965050602087013567ffffffffffffffff8111156128f5576128f5600080fd5b61290189828a016126b4565b9550955050604061291489828a0161251b565b935050606087013567ffffffffffffffff81111561293457612934600080fd5b61294089828a016126b4565b92509250509295509295509295565b600061295b83836127bc565b505060200190565b600061296d825190565b80845260209384019383018060005b838110156129a1578151612990888261294f565b97506020830192505060010161297c565b509495945050505050565b60208082528101611d368184612963565b6000602082840312156129d2576129d2600080fd5b60006126168484612638565b6000602082840312156129f3576129f3600080fd5b60006126168484612627565b60408101612a0d82856125c2565b611d3660208301846125c2565b60008060408385031215612a3057612a30600080fd5b6000612a3c8585612627565b925050602061255985828601612638565b600080600060608486031215612a6557612a65600080fd5b6000612667868661251b565b60008060408385031215612a8757612a87600080fd5b60006127ab858561251b565b634e487b7160e01b600052602160045260246000fd5b601d81526000602082017f426f6e64696e67206375727665206e6f742077686974656c6973746564000000815291505b5060200190565b6020808252810161092081612aa9565b6003811061192557600080fd5b803561092081612af0565b600060208284031215612b1d57612b1d600080fd5b60006126168484612afd565b6001600160801b038116612510565b803561092081612b29565b600060208284031215612b5857612b58600080fd5b60006126168484612b38565b6bffffffffffffffffffffffff8116612510565b803561092081612b64565b600060208284031215612b9857612b98600080fd5b60006126168484612b78565b80516109208161261e565b600060208284031215612bc457612bc4600080fd5b60006126168484612ba4565b634e487b7160e01b600052603260045260246000fd5b60608101612bf482866127bc565b612c0160208301856127bc565b6126166040830184612563565b60408101612a0d82856124ea565b600981526000602082016830206164647265737360b81b81529150612ad9565b6020808252810161092081612c1c565b6001600160e01b031981166124f3565b602081016109208284612c4c565b805161092081612776565b600060208284031215612c8a57612c8a600080fd5b60006126168484612c6a565b6000808335601e1936859003018112612cb157612cb1600080fd5b80840192508235915067ffffffffffffffff821115612cd257612cd2600080fd5b60209283019282023603831315612ceb57612ceb600080fd5b509250929050565b601181526000602082017021b0b713ba1031b0b636103937baba32b960791b81529150612ad9565b6020808252810161092081612cf3565b601e81526000602082017f6e667420616e6420636f756e74206c656e677468206d7573742073616d65000081529150612ad9565b6020808252810161092081612d2b565b60a08101612d7d82876127bc565b612d8a60208301866127bc565b612d976040830185612563565b612da46060830184612563565b818103608083015260008152602081015b9695505050505050565b600d81526000602082016c46656520746f6f206c6172676560981b81529150612ad9565b6020808252810161092081612dbf565b60158152600060208201743ab730baba3437b934bd32b21037b832b930ba37b960591b81529150612ad9565b6020808252810161092081612df3565b601f81526000602082017f4f70657261746f722070726f746f636f6c2066656520746f6f206c617267650081529150612ad9565b6020808252810161092081612e2f565b634e487b7160e01b600052601160045260246000fd5b60008219821115612e9c57612e9c612e73565b500190565b602581526000602082017f546f74616c206f70657261746f722070726f746f636f6c2066656520746f6f208152646c6172676560d81b602082015291505b5060400190565b6020808252810161092081612ea1565b60a08101612f0482886127bc565b612f1160208301876127bc565b612f1e60408301866127bc565b612f2b6060830185612563565b612db56080830184612563565b602681526000602082017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b60208201529150612edf565b6020808252810161092081612f38565b6001600160801b0381166124f3565b6bffffffffffffffffffffffff81166124f3565b60c08101612fbc82896127bc565b612fc960208301886127bc565b612fd66040830187612f8b565b612fe36060830186612f9a565b612ff06080830185612f8b565b612ffd60a0830184612563565b979650505050505050565b60148152600060208201731514905394d1915497d19493d357d1905253115160621b81529150612ad9565b6020808252810161092081613008565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657291019081526000612ad9565b6020808252810161092081613043565b60a0810161309382886127bc565b6130a060208301876127bc565b6130ad6040830186612f8b565b6130ba6060830185612f9a565b612db56080830184612f8b565b601381526000602082017211551217d514905394d1915497d19052531151606a1b81529150612ad9565b60208082528101610920816130c7565b600f81526000602082016e1514905394d1915497d19052531151608a1b81529150612ad9565b6020808252810161092081613101565b60008282101561314957613149612e73565b500390565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220922b14f6bed1570a30b9f95b3b46cee53a4d319a6e2416f1f8c66da0486f4ed664736f6c634300080d0033