ETH Price: $2,025.28 (+4.23%)

Contract

0x3473ba28c97E8D2fdDBc6f95764BAE6429e31885
 

Overview

ETH Balance

0.045305202244740683 ETH

Eth Value

$91.76 (@ $2,025.28/ETH)

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Register Pool154861222022-09-06 20:16:261279 days ago1662495386IN
0x3473ba28...429e31885
0 ETH0.0038521330.91177431
Register Pool154826612022-09-06 7:11:111280 days ago1662448271IN
0x3473ba28...429e31885
0 ETH0.000616435.73333805
Register Pool154800102022-09-05 20:53:011280 days ago1662411181IN
0x3473ba28...429e31885
0 ETH0.001158989.42757747
Register Pool154742152022-09-04 22:25:301281 days ago1662330330IN
0x3473ba28...429e31885
0 ETH0.000634515.16133839
Register Pool154739092022-09-04 21:13:001281 days ago1662325980IN
0x3473ba28...429e31885
0 ETH0.000841137.82326551
Register Pool154738992022-09-04 21:09:591281 days ago1662325799IN
0x3473ba28...429e31885
0 ETH0.000947177.70463107
Register Pool154738672022-09-04 21:02:361281 days ago1662325356IN
0x3473ba28...429e31885
0 ETH0.0013952311.34931072
Register Pool154738652022-09-04 21:02:171281 days ago1662325337IN
0x3473ba28...429e31885
0 ETH0.0014300611.63256655
Register Pool154613602022-09-02 20:57:301283 days ago1662152250IN
0x3473ba28...429e31885
0 ETH0.0013563812.61691601
Register Pool154419882022-08-30 18:45:181286 days ago1661885118IN
0x3473ba28...429e31885
0 ETH0.0019503418.13985171
Register Pool154380612022-08-30 3:40:031287 days ago1661830803IN
0x3473ba28...429e31885
0 ETH0.0035694828.64366866
Register Pool154131892022-08-26 4:09:561291 days ago1661486996IN
0x3473ba28...429e31885
0 ETH0.000821097.63684778
Buy From Pool154131202022-08-26 3:52:461291 days ago1661485966IN
0x3473ba28...429e31885
0.14371261 ETH0.00261368.1404128
Register Pool154131052022-08-26 3:48:411291 days ago1661485721IN
0x3473ba28...429e31885
0 ETH0.000648686.03328164
Register Pool154131012022-08-26 3:47:361291 days ago1661485656IN
0x3473ba28...429e31885
0 ETH0.000564265.24815367
Register Pool154130952022-08-26 3:46:291291 days ago1661485589IN
0x3473ba28...429e31885
0 ETH0.00066516.1860336
Register Pool154130912022-08-26 3:46:161291 days ago1661485576IN
0x3473ba28...429e31885
0 ETH0.001085698.71222956

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer154761532022-09-05 6:00:031281 days ago1662357603
0x3473ba28...429e31885
0.00220894 ETH
Transfer154761532022-09-05 6:00:031281 days ago1662357603
0x3473ba28...429e31885
0.00220132 ETH
Swap Token For A...154761532022-09-05 6:00:031281 days ago1662357603
0x3473ba28...429e31885
0.11264848 ETH
Buy From Pool154761532022-09-05 6:00:031281 days ago1662357603
0x3473ba28...429e31885
0.11298744 ETH
Buy From Pool154757272022-09-05 4:20:141281 days ago1662351614
0x3473ba28...429e31885
0.11298744 ETH
Transfer154756982022-09-05 4:13:001281 days ago1662351180
0x3473ba28...429e31885
0.01 ETH
Transfer154756982022-09-05 4:13:001281 days ago1662351180
0x3473ba28...429e31885
0.0099655 ETH
Swap Token For A...154756982022-09-05 4:13:001281 days ago1662351180
0x3473ba28...429e31885
0.5099655 ETH
Buy From Pool154756982022-09-05 4:13:001281 days ago1662351180
0x3473ba28...429e31885
0.5115 ETH
Buy From Pool154756392022-09-05 3:56:301281 days ago1662350190
0x3473ba28...429e31885
0.16373115 ETH
Swap Token For A...154753442022-09-05 2:44:501281 days ago1662345890
0x3473ba28...429e31885
0.11491222 ETH
Buy From Pool154753442022-09-05 2:44:501281 days ago1662345890
0x3473ba28...429e31885
0.11525799 ETH
Transfer154752512022-09-05 2:26:191281 days ago1662344779
0x3473ba28...429e31885
0.016872 ETH
Transfer154752512022-09-05 2:26:191281 days ago1662344779
0x3473ba28...429e31885
0.01681379 ETH
Swap Token For A...154752512022-09-05 2:26:191281 days ago1662344779
0x3473ba28...429e31885
0.86041379 ETH
Buy From Pool154752512022-09-05 2:26:191281 days ago1662344779
0x3473ba28...429e31885
0.8630028 ETH
Transfer154752422022-09-05 2:24:251281 days ago1662344665
0x3473ba28...429e31885
0.00225918 ETH
Transfer154752422022-09-05 2:24:251281 days ago1662344665
0x3473ba28...429e31885
0.00225138 ETH
Swap Token For A...154752422022-09-05 2:24:251281 days ago1662344665
0x3473ba28...429e31885
0.11521038 ETH
Buy From Pool154752422022-09-05 2:24:251281 days ago1662344665
0x3473ba28...429e31885
0.11555705 ETH
Transfer154752402022-09-05 2:24:011281 days ago1662344641
0x3473ba28...429e31885
0.00225918 ETH
Transfer154752402022-09-05 2:24:011281 days ago1662344641
0x3473ba28...429e31885
0.00225138 ETH
Swap Token For A...154752402022-09-05 2:24:011281 days ago1662344641
0x3473ba28...429e31885
0.11521038 ETH
Buy From Pool154752402022-09-05 2:24:011281 days ago1662344641
0x3473ba28...429e31885
0.11555705 ETH
Transfer154752342022-09-05 2:22:491281 days ago1662344569
0x3473ba28...429e31885
0.016872 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
SudoGate

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.16;


import {IERC165} from "IERC165.sol";

import {IERC721} from "IERC721.sol";

import {IERC721Enumerable} from "IERC721Enumerable.sol";

import {ILSSVMPairFactoryLike} from "ILSSVMPairFactoryLike.sol";
import {LSSVMPair, CurveErrorCodes} from "LSSVMPair.sol";

contract SudoGate {
    address private SUDO_PAIR_FACTORY_ADDRESS = 0xb16c1342E617A5B6E4b631EB114483FDB289c0A4;
    address public owner; 

    uint256 public minBalanceForTransfer = 0.1 ether;
    uint256 public contributorFeePerThousand = 2;
    uint256 public protocolFeePerThousand = 1;
    uint256 public defaultSlippagePerThousand = 20;

    address payable public protocolFeeAddress;

    /* 
    to avoid transferring eth on every small fee, 
    keep track of balances in this mapping and then 
    send eth in larger batches 
    */
    mapping (address => uint256) public balances;
    uint256 public totalBalance = 0;


    // mapping from NFT addresses to array of known pools
    mapping (address => address[]) public pools;

    mapping (address => bool) public knownPool;

    // who contributed each pool
    mapping (address => address) public poolContributors;

    constructor() { 
        owner = msg.sender; 
        protocolFeeAddress = payable(msg.sender);
    }
    
    function setPairFactoryAddress(address addr) public {
        require(msg.sender == owner, "Only owner allowed to call setPairFactoryAddress");
        SUDO_PAIR_FACTORY_ADDRESS = addr;
    }

    function setProtocolFeeAddress(address payable addr) public {
        require(msg.sender == owner, "Only owner allowed to call setProtocolFeeAddress");
        protocolFeeAddress = addr;
    }
    
    function setProtocolFee(uint256 fee) public {
        /* 
            set fee (in 1/10th of a percent) which gets sent to protocol
            for every transaction
        */
        require(msg.sender == owner, "Only owner allowed to call setProtocolFee");
        protocolFeePerThousand = fee;
    }

    function setContributorFee(uint256 fee) public {
        /* 
            set fee (in 1/10th of a percent) which gets sent to whoever 
            contributed the pool address to SudoGate
        */
        require(msg.sender == owner, "Only owner allowed to call setContributorFee");
        contributorFeePerThousand = fee;
    }

    function setMinBalanceForTransfer(uint256 minVal) public {
        /* 
            set fee (in 1/10th of a percent) which gets sent to whoever 
            contributed the pool address to SudoGate
        */
        require(msg.sender == owner, "Only owner allowed to call setMinBalanceForTransfer");
        minBalanceForTransfer = minVal;
    }

    function setDefaultSlippage(uint256 slippagePerThousand) public {
        /* 
        controls the price fudge factor used to make sure we send enough ETH to sudoswap 
        even if our price computation doesn't quite agree with theirs
        */ 
        require(msg.sender == owner, "Only owner allowed to call setDefaultSlippage");
        defaultSlippagePerThousand = slippagePerThousand;
    }
    

    function totalFeesPerThousand() public view returns (uint256) {
        return protocolFeePerThousand + contributorFeePerThousand;
    }

    function registerPool(address sudoswapPool) public returns (bool) {
        require(!knownPool[sudoswapPool], "Pool already known");
        if (!ILSSVMPairFactoryLike(SUDO_PAIR_FACTORY_ADDRESS).isPair(sudoswapPool, ILSSVMPairFactoryLike.PairVariant.ENUMERABLE_ETH)) {
            require(ILSSVMPairFactoryLike(SUDO_PAIR_FACTORY_ADDRESS).isPair(sudoswapPool, ILSSVMPairFactoryLike.PairVariant.MISSING_ENUMERABLE_ETH), "Not a sudoswap ETH pool");
        }
        knownPool[sudoswapPool] = true;
        poolContributors[sudoswapPool] = msg.sender;
        address nft = address(LSSVMPair(sudoswapPool).nft());
        pools[nft].push(sudoswapPool); 
    }

    function calcFeesAndSlippage(uint256 price, uint256 slippagePerThousand) internal view returns (
            uint256 protocolFee, 
            uint256 contributorFee,
            uint256 slippage) {
        require(contributorFeePerThousand <= 1000, "contributorFeePerThousand must be between 0 and 1000");
        require(protocolFeePerThousand <= 1000, "protocolFeePerThousand must be between 0 and 1000");
        require(slippagePerThousand <= 1000, "slippagePerThousand must be between 0 and 1000");
        
        // first scale everything up by a thousand so we get a little more fixed point precision
        uint256 priceX1000 = price * 1000; 
        require(priceX1000 > price, "Overflow in rescaled price");

        // if price is 1000x bigger and fees are per-thousand 
        // then need to divide by 1M to get something proportional to original price
        uint256 denom = 10 ** 6; 

        contributorFee = priceX1000 * contributorFeePerThousand / denom;
        require(contributorFee < price, "Contributor fee should be less than price");

        protocolFee = priceX1000 * protocolFeePerThousand / denom; 
        require(protocolFee < price, "Protocol fee should be less than price");
       
        if (slippagePerThousand > 0) {
            slippage = priceX1000 * slippagePerThousand / denom;
            require (slippage < price, "Slippage cannot be greater than 100%");
        } else {
            slippage = 0;
        }
        
    }

    function calcFees(uint256 price) internal view returns (
            uint256 protocolFee, 
            uint256 contributorFee) {
        (protocolFee, contributorFee, ) = calcFeesAndSlippage(price, 0);
    } 


    function adjustBuyPrice(uint256 price, uint256 slippagePerThousand) public view returns (uint256 adjustedPrice) {
        uint256 protocolFee;
        uint256 contributorFee;
        uint256 slippage;
        (protocolFee, contributorFee, slippage) = calcFeesAndSlippage(price, slippagePerThousand);
        uint256 combinedAdjustment = protocolFee + contributorFee + slippage; 
        require(combinedAdjustment < price, "Fees + slippage cannot exceed 100%");
        adjustedPrice =  price + combinedAdjustment; 
    }
    
    function adjustSellPrice(uint256 price, uint256 slippagePerThousand) public view returns (uint256 adjustedPrice) {
        uint256 protocolFee;
        uint256 contributorFee;
        uint256 slippage;
        (protocolFee, contributorFee, slippage) = calcFeesAndSlippage(price, slippagePerThousand);
        uint256 combinedAdjustment = protocolFee + contributorFee + slippage; 
        require(combinedAdjustment < price, "Fees + slippage cannot exceed 100%");
        adjustedPrice = price - combinedAdjustment; 
    }
    

    function addFee(address recipient, uint256 fee) internal {
        balances[recipient] += fee;
        totalBalance += fee;

        uint256 currentBalance = balances[recipient];
        if (currentBalance >= minBalanceForTransfer) {
            require(address(this).balance >= currentBalance, "Not enough ETH on contract");
            require(totalBalance >= currentBalance, "Don't lose track of how much ETH we have!");
            balances[recipient] = 0;
            totalBalance -= currentBalance;
            payable(recipient).transfer(currentBalance);
        }
    }

    function buyFromPool(address pool) public payable returns (uint256 tokenID) {
        /* returns token ID of purchased NFT */
        IERC721 nft = LSSVMPair(pool).nft();
        require(nft.balanceOf(pool) > 0, "Pool has no NFTs");
        uint256[] memory tokenIDs = LSSVMPair(pool).getAllHeldIds();
        tokenID = tokenIDs[tokenIDs.length - 1];
        uint256 startingValue = msg.value; 
        uint256 maxProtocolFee;
        uint256 maxContributorFee;
        
        (maxProtocolFee, maxContributorFee) = calcFees(startingValue);
        uint256 maxAllowedSpend = startingValue - (maxContributorFee + maxProtocolFee);

        uint256 usedAmt = LSSVMPair(pool).swapTokenForAnyNFTs{value: maxAllowedSpend}(
            1, 
            maxAllowedSpend, 
            msg.sender, 
            false, 
            address(0));
        require(usedAmt < startingValue, "Can't use more ETH than was originally sent");
        require(usedAmt > 0, "There ain't no such thing as a free lunch");
        
        // compute actual fees based on what got spent by sudoswap
        uint256 contributorFee; 
        uint256 protocolFee; 
        (protocolFee, contributorFee) = calcFees(usedAmt);
        uint256 amtWithFees = usedAmt + (protocolFee + contributorFee);
        require(amtWithFees <= startingValue, "Can't spend more than we were originally sent");
        
        addFee(poolContributors[pool], contributorFee);
        addFee(protocolFeeAddress, protocolFee);
        uint256 diff = startingValue - amtWithFees;
        // send back unused ETH
        if (diff > 0) { payable(msg.sender).transfer(diff); }
    }

    function buy(address nft) public payable returns (uint256 tokenID) {
        uint256 bestPrice;
        address bestPool;
        (bestPrice, bestPool) = buyQuote(nft);
        require(bestPool != address(0), "No pool found");
        require(bestPrice != type(uint256).max, "Invalid price");
        uint256 adjustedPrice = adjustBuyPrice(bestPrice, 5);
        require(adjustedPrice <= msg.value, "Not enough ETH for price of NFT");
        tokenID = buyFromPool(bestPool);
    }

    function buyQuote(address nft) public view returns (uint256 bestPrice, address bestPool) {
        /* 
        Returns best price for an NFT and the pool to buy it from. 
        Does not include SudoGate fees, see buyQuoteWithFees
        */
        address[] storage nftPools = pools[nft];
        uint256 numPools = nftPools.length;
        require(numPools > 0, "No pools registered for given NFT");

        CurveErrorCodes.Error err;
        uint256 inputAmount;
        bestPrice = type(uint256).max;
        bestPool = address(0);

        address poolAddr;
        uint256 i = 0;
        for (; i < numPools; ++i) {
            poolAddr = nftPools[i];
            if (IERC721(nft).balanceOf(poolAddr) == 0) {
                // check if pool actually has any NFTs
                continue;
            } else {
                (err, , , inputAmount, ) = LSSVMPair(poolAddr).getBuyNFTQuote(1);
                if (err == CurveErrorCodes.Error.OK) {
                    if (inputAmount < bestPrice) {
                        bestPool = poolAddr;
                        bestPrice = inputAmount;
                    }
                }
            }
        }
        require(bestPool != address(0), "Could not find a pool to buy from");
    }


    function buyQuoteWithFees(address nft) public view returns (uint256 bestPrice, address bestPool) {
        /* 
        Returns best price for an NFT and the pool to buy it from. 
        Price is adjusted for SudoGate fees but assumes 0 slippage.
        */ 
        (bestPrice, bestPool) = buyQuote(nft);
        // add a small slippage factor 
        bestPrice = adjustBuyPrice(bestPrice, defaultSlippagePerThousand);
    }

    function sell(address nft, uint256 tokenId) public {
        uint256 bestPrice;
        address bestPool;
        (bestPrice, bestPool) = sellQuote(nft);
        
        uint256[] memory nftIds = new uint256[](1);
        nftIds[0] = tokenId;

        uint256 outputAmount = LSSVMPair(bestPool).swapNFTsForToken(
            nftIds,
            bestPrice,
            payable(address(this)),
            false,
            address(0));

        require(outputAmount > 0, "Didn't get any ETH back");
        require(outputAmount > (bestPrice / 2), "Sale price slippage greater than 50%");

        // compute actual fees based on what got sent by sudoswap
        
        uint256 contributorFee; 
        uint256 protocolFee;
        
        (protocolFee, contributorFee) = calcFees(outputAmount);
        
        addFee(poolContributors[bestPool], contributorFee);
        addFee(protocolFeeAddress, protocolFee);
        
        uint256 combinedFees = protocolFee + contributorFee;
        require(combinedFees < outputAmount, "Fees can't exceed ETH received for selling");
        
        uint256 diff = outputAmount - combinedFees;
        
        // send back ETH after fees
        if (diff > 0) { payable(msg.sender).transfer(diff); }
    }

    function sellQuote(address nft) public view returns (uint256 bestPrice, address bestPool) {
        address[] storage nftPools = pools[nft];
        uint256 numPools = nftPools.length;
        require(numPools > 0, "No pools registered for given NFT");

        CurveErrorCodes.Error err;
        uint256 outputAmount;
        bestPrice = 0;
        bestPool = address(0);

        address poolAddr;
        uint256 i = 0;
        for (; i < numPools; ++i) {
            poolAddr = nftPools[i];
            if (poolAddr.balance < bestPrice) {
                // check if pool actually has enough ETH to potentially give us a better price
                continue;
            } else {
                (err, , , outputAmount, ) = LSSVMPair(poolAddr).getSellNFTQuote(1);
                // make sure the pool has enough ETH to cover its own better offer
                if ((err == CurveErrorCodes.Error.OK) && 
                        (outputAmount > bestPrice) && 
                        (poolAddr.balance >= outputAmount)) { 
                    bestPool = poolAddr;
                    bestPrice = outputAmount;
                }
            }
        }
        require(bestPool != address(0), "Could not find a pool to buy from");
    }   

    
    function sellQuoteWithFees(address nft) public view returns (uint256 bestPrice, address bestPool) {
        /* 
        Returns best sell price for an NFT and the pool to sell it to. 
        Price is adjusted for SudoGate fees but assumes 0 slippage.
        */ 
        (bestPrice, bestPool) = sellQuote(nft);
        // include a small slippage factor  
        bestPrice = adjustSellPrice(bestPrice, defaultSlippagePerThousand);
    }

    
    // make it possible to receive ETH on this contract
    receive() external payable { }

    function rescueETH() public {
        // in case ETH gets trapped on this contract for some reason,
        // allow owner to manually withdraw it
        require(msg.sender == owner, "Only owner allowed to call rescueETH");
        require(address(this).balance >= totalBalance, "Not enough ETH on contract for balances");
        uint256 extraETH = address(this).balance - totalBalance;
        payable(owner).transfer(extraETH);
    }

    function withdraw() public {
        // let contributors withdraw ETH if they have any on the contract
        uint256 balance = balances[msg.sender];
        require(balance < address(this).balance, "Not enough ETH on contract");
        balances[msg.sender] = 0;
        totalBalance -= balance;
        payable(msg.sender).transfer(balance);
    }
}

// SPDX-License-Identifier: MIT

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);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "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);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// SPDX-License-Identifier: MIT

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 tokenId);

    /**
     * @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);
}

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.10;

interface ILSSVMPairFactoryLike {
    enum PairVariant {
        ENUMERABLE_ETH,
        MISSING_ENUMERABLE_ETH,
        ENUMERABLE_ERC20,
        MISSING_ENUMERABLE_ERC20
    }

    function protocolFeeMultiplier() external view returns (uint256);

    function protocolFeeRecipient() external view returns (address payable);

    function callAllowed(address target) external view returns (bool);
    /*
    function routerStatus(LSSVMRouter router)
        external
        view
        returns (bool allowed, bool wasEverAllowed);
    */

    function isPair(address potentialPair, PairVariant variant)
        external
        view
        returns (bool);
}

// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.10;

import {IERC721} from "IERC721.sol";
import {ILSSVMPairFactoryLike} from "ILSSVMPairFactoryLike.sol";

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
    }
}

interface LSSVMPair {

    enum PoolType {
        TOKEN,
        NFT,
        TRADE
    }

    function factory() external pure returns (ILSSVMPairFactoryLike);
    
    function nft() external pure returns (IERC721);
    
    function poolType() external pure returns (PoolType);
    
    function getBuyNFTQuote(uint256 numNFTs) external view returns (
            CurveErrorCodes.Error error,
            uint256 newSpotPrice,
            uint256 newDelta,
            uint256 inputAmount,
            uint256 protocolFee
        );

    function getSellNFTQuote(uint256 numNFTs) external view returns (
            CurveErrorCodes.Error error,
            uint256 newSpotPrice,
            uint256 newDelta,
            uint256 outputAmount,
            uint256 protocolFee
        );

      /**
        @notice Sends token to the pair in exchange for any `numNFTs` NFTs
        @dev To compute the amount of token to send, call bondingCurve.getBuyInfo.
        This swap function is meant for users who are ID agnostic
        @param numNFTs The number of NFTs to purchase
        @param maxExpectedTokenInput The maximum acceptable cost from the sender. If the actual
        amount is greater than this value, the transaction will be reverted.
        @param nftRecipient The recipient of the NFTs
        @param isRouter True if calling from LSSVMRouter, false otherwise. Not used for
        ETH pairs.
        @param routerCaller If isRouter is true, ERC20 tokens will be transferred from this address. Not used for
        ETH pairs.
        @return inputAmount The amount of token used for purchase
     */
    function swapTokenForAnyNFTs(
        uint256 numNFTs,
        uint256 maxExpectedTokenInput,
        address nftRecipient,
        bool isRouter,
        address routerCaller
    ) external payable  returns (uint256 inputAmount);

     function swapNFTsForToken(
        uint256[] calldata nftIds,
        uint256 minExpectedTokenOutput,
        address payable tokenRecipient,
        bool isRouter,
        address routerCaller
    ) external returns (uint256 outputAmount);

    function getAllHeldIds() external view returns (uint256[] memory);

}

Settings
{
  "evmVersion": "istanbul",
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "libraries": {
    "SudoGate.sol": {}
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"slippagePerThousand","type":"uint256"}],"name":"adjustBuyPrice","outputs":[{"internalType":"uint256","name":"adjustedPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"uint256","name":"slippagePerThousand","type":"uint256"}],"name":"adjustSellPrice","outputs":[{"internalType":"uint256","name":"adjustedPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nft","type":"address"}],"name":"buy","outputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"}],"name":"buyFromPool","outputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"nft","type":"address"}],"name":"buyQuote","outputs":[{"internalType":"uint256","name":"bestPrice","type":"uint256"},{"internalType":"address","name":"bestPool","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nft","type":"address"}],"name":"buyQuoteWithFees","outputs":[{"internalType":"uint256","name":"bestPrice","type":"uint256"},{"internalType":"address","name":"bestPool","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributorFeePerThousand","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultSlippagePerThousand","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"knownPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBalanceForTransfer","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"poolContributors","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"pools","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeeAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFeePerThousand","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sudoswapPool","type":"address"}],"name":"registerPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rescueETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"sell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nft","type":"address"}],"name":"sellQuote","outputs":[{"internalType":"uint256","name":"bestPrice","type":"uint256"},{"internalType":"address","name":"bestPool","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nft","type":"address"}],"name":"sellQuoteWithFees","outputs":[{"internalType":"uint256","name":"bestPrice","type":"uint256"},{"internalType":"address","name":"bestPool","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setContributorFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"slippagePerThousand","type":"uint256"}],"name":"setDefaultSlippage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minVal","type":"uint256"}],"name":"setMinBalanceForTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setPairFactoryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"setProtocolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"addr","type":"address"}],"name":"setProtocolFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFeesPerThousand","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080604052600080546001600160a01b03191673b16c1342e617a5b6e4b631eb114483fdb289c0a417815567016345785d8a000060029081556003556001600455601460055560085534801561005457600080fd5b5060018054336001600160a01b03199182168117909255600680549091169091179055612290806100866000396000f3fe6080604052600436106101d15760003560e01c80638da5cb5b116100f7578063da72a26111610095578063f088d54711610064578063f088d5471461054a578063f61c205c1461055d578063fdb26ec71461057d578063febbfa871461059d57600080fd5b8063da72a261146104de578063dd013184146104f4578063dd93f59a14610514578063e6a014cb1461053457600080fd5b8063ad7a672f116100d1578063ad7a672f14610465578063ba5bddd71461047b578063cce516b71461048e578063cdfc89aa146104ae57600080fd5b80638da5cb5b146103f55780638f38a55514610415578063abd908461461043557600080fd5b80634173393b1161016f5780636b7b91121161013e5780636b7b9112146103755780636c197ff514610395578063787dce3d146103b557806379c81992146103d557600080fd5b80634173393b1461030a57806344bd1afd146103205780634818cfd4146103405780634a6750401461036057600080fd5b806327e235e3116101ab57806327e235e3146102845780632d2f2be4146102bf5780633a1f656e146102d55780633ccfd60b146102f557600080fd5b80630b209fb3146101dd57806315945f781461023057806320800a001461026d57600080fd5b366101d857005b600080fd5b3480156101e957600080fd5b506102136101f8366004611e66565b600b602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023c57600080fd5b5061025061024b366004611e66565b6105bd565b604080519283526001600160a01b03909116602083015201610227565b34801561027957600080fd5b506102826105e3565b005b34801561029057600080fd5b506102b161029f366004611e66565b60076020526000908152604090205481565b604051908152602001610227565b3480156102cb57600080fd5b506102b160055481565b3480156102e157600080fd5b506102826102f0366004611e66565b6106ff565b34801561030157600080fd5b50610282610794565b34801561031657600080fd5b506102b160025481565b34801561032c57600080fd5b5061028261033b366004611e8a565b610849565b34801561034c57600080fd5b5061028261035b366004611e8a565b6108be565b34801561036c57600080fd5b506102b1610939565b34801561038157600080fd5b50610282610390366004611e66565b610950565b3480156103a157600080fd5b506102826103b0366004611ea3565b6109e5565b3480156103c157600080fd5b506102826103d0366004611e8a565b610c76565b3480156103e157600080fd5b506102506103f0366004611e66565b610ce7565b34801561040157600080fd5b50600154610213906001600160a01b031681565b34801561042157600080fd5b50610213610430366004611ea3565b610ee5565b34801561044157600080fd5b50610455610450366004611e66565b610f1d565b6040519015158152602001610227565b34801561047157600080fd5b506102b160085481565b6102b1610489366004611e66565b611190565b34801561049a57600080fd5b50600654610213906001600160a01b031681565b3480156104ba57600080fd5b506104556104c9366004611e66565b600a6020526000908152604090205460ff1681565b3480156104ea57600080fd5b506102b160035481565b34801561050057600080fd5b5061025061050f366004611e66565b6115d4565b34801561052057600080fd5b5061025061052f366004611e66565b6115f3565b34801561054057600080fd5b506102b160045481565b6102b1610558366004611e66565b61173d565b34801561056957600080fd5b506102b1610578366004611ecf565b611848565b34801561058957600080fd5b506102b1610598366004611ecf565b6118ac565b3480156105a957600080fd5b506102826105b8366004611e8a565b611905565b6000806105c9836115f3565b60055491935091506105dc9083906118ac565b9150915091565b6001546001600160a01b0316331461064e5760405162461bcd60e51b8152602060048201526024808201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c2072657363756044820152630ca8aa8960e31b60648201526084015b60405180910390fd5b6008544710156106b05760405162461bcd60e51b815260206004820152602760248201527f4e6f7420656e6f75676820455448206f6e20636f6e747261637420666f722062604482015266616c616e63657360c81b6064820152608401610645565b6000600854476106c09190611f07565b6001546040519192506001600160a01b03169082156108fc029083906000818181858888f193505050501580156106fb573d6000803e3d6000fd5b5050565b6001546001600160a01b031633146107725760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c20736574506160448201526f6972466163746f72794164647265737360801b6064820152608401610645565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b336000908152600760205260409020544781106107f35760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820455448206f6e20636f6e74726163740000000000006044820152606401610645565b33600090815260076020526040812081905560088054839290610817908490611f07565b9091555050604051339082156108fc029083906000818181858888f193505050501580156106fb573d6000803e3d6000fd5b6001546001600160a01b031633146108b95760405162461bcd60e51b815260206004820152602d60248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c20736574446560448201526c6661756c74536c69707061676560981b6064820152608401610645565b600555565b6001546001600160a01b031633146109345760405162461bcd60e51b815260206004820152603360248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c207365744d69604482015272372130b630b731b2a337b92a3930b739b332b960691b6064820152608401610645565b600255565b600060035460045461094b9190611f20565b905090565b6001546001600160a01b031633146109c35760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c20736574507260448201526f6f746f636f6c4665654164647265737360801b6064820152608401610645565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000806109f1846115f3565b60408051600180825281830190925292945090925060009190602080830190803683370190505090508381600081518110610a2e57610a2e611f49565b602090810291909101015260405163b1d3f1c160e01b81526000906001600160a01b0384169063b1d3f1c190610a709085908890309087908190600401611f5f565b6020604051808303816000875af1158015610a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab39190611fc9565b905060008111610b055760405162461bcd60e51b815260206004820152601760248201527f4469646e27742067657420616e7920455448206261636b0000000000000000006044820152606401610645565b610b10600285611fe2565b8111610b6a5760405162461bcd60e51b8152602060048201526024808201527f53616c6520707269636520736c6970706167652067726561746572207468616e6044820152632035302560e01b6064820152608401610645565b600080610b7683611979565b6001600160a01b038088166000908152600b6020526040902054919450919250610ba1911683611992565b600654610bb7906001600160a01b031682611992565b6000610bc38383611f20565b9050838110610c275760405162461bcd60e51b815260206004820152602a60248201527f466565732063616e2774206578636565642045544820726563656976656420666044820152696f722073656c6c696e6760b01b6064820152608401610645565b6000610c338286611f07565b90508015610c6a57604051339082156108fc029083906000818181858888f19350505050158015610c68573d6000803e3d6000fd5b505b50505050505050505050565b6001546001600160a01b03163314610ce25760405162461bcd60e51b815260206004820152602960248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c2073657450726044820152686f746f636f6c46656560b81b6064820152608401610645565b600455565b6001600160a01b0381166000908152600960205260408120805482919080610d215760405162461bcd60e51b815260040161064590612004565b600019935060009250828080805b84811015610e7a57858181548110610d4957610d49611f49565b6000918252602090912001546040516370a0823160e01b81526001600160a01b03918216600482018190529350908a16906370a0823190602401602060405180830381865afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190611fc9565b15610e6a5760405163a5cb2b9160e01b8152600160048201526001600160a01b0383169063a5cb2b919060240160a060405180830381865afa158015610e0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e329190612045565b5092965091945060009150610e449050565b846002811115610e5657610e56612092565b03610e6a5787831015610e6a578196508297505b610e73816120a8565b9050610d2f565b6001600160a01b038716610eda5760405162461bcd60e51b815260206004820152602160248201527f436f756c64206e6f742066696e64206120706f6f6c20746f206275792066726f6044820152606d60f81b6064820152608401610645565b505050505050915091565b60096020528160005260406000208181548110610f0157600080fd5b6000918252602090912001546001600160a01b03169150829050565b6001600160a01b0381166000908152600a602052604081205460ff1615610f7b5760405162461bcd60e51b81526020600482015260126024820152712837b7b61030b63932b0b23c9035b737bbb760711b6044820152606401610645565b600080546040516308f25a8f60e01b81526001600160a01b03909116916308f25a8f91610fac9186916004016120c1565b602060405180830381865afa158015610fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fed91906120fc565b6110b1576000546040516308f25a8f60e01b81526001600160a01b03909116906308f25a8f906110249085906001906004016120c1565b602060405180830381865afa158015611041573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106591906120fc565b6110b15760405162461bcd60e51b815260206004820152601760248201527f4e6f742061207375646f737761702045544820706f6f6c0000000000000000006044820152606401610645565b6001600160a01b0382166000818152600a60209081526040808320805460ff19166001179055600b825280832080546001600160a01b0319163317905580516323e6650160e11b815290519293926347ccca02926004808401939192918290030181865afa158015611127573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114b919061211e565b6001600160a01b0390811660009081526009602090815260408220805460018101825590835291200180546001600160a01b0319169490911693909317909255919050565b600080826001600160a01b03166347ccca026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f5919061211e565b6040516370a0823160e01b81526001600160a01b0385811660048301529192506000918316906370a0823190602401602060405180830381865afa158015611241573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112659190611fc9565b116112a55760405162461bcd60e51b815260206004820152601060248201526f506f6f6c20686173206e6f204e46547360801b6044820152606401610645565b6000836001600160a01b0316632f4fefaf6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156112e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261130d919081019061213b565b9050806001825161131e9190611f07565b8151811061132e5761132e611f49565b60200260200101519250600034905060008061134983611979565b9092509050600061135a8383611f20565b6113649085611f07565b6040516328b8aee160e01b81526001600482015260248101829052336044820152600060648201819052608482018190529192506001600160a01b038a16906328b8aee190849060a40160206040518083038185885af11580156113cc573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906113f19190611fc9565b90508481106114565760405162461bcd60e51b815260206004820152602b60248201527f43616e277420757365206d6f726520455448207468616e20776173206f72696760448201526a1a5b985b1b1e481cd95b9d60aa1b6064820152608401610645565b600081116114b85760405162461bcd60e51b815260206004820152602960248201527f54686572652061696e2774206e6f2073756368207468696e67206173206120666044820152680e4caca40d8eadcc6d60bb1b6064820152608401610645565b6000806114c483611979565b9250905060006114d48383611f20565b6114de9085611f20565b9050878111156115465760405162461bcd60e51b815260206004820152602d60248201527f43616e2774207370656e64206d6f7265207468616e2077652077657265206f7260448201526c1a59da5b985b1b1e481cd95b9d609a1b6064820152608401610645565b6001600160a01b03808d166000908152600b602052604090205461156b911684611992565b600654611581906001600160a01b031683611992565b600061158d828a611f07565b905080156115c457604051339082156108fc029083906000818181858888f193505050501580156115c2573d6000803e3d6000fd5b505b5050505050505050505050919050565b6000806115e083610ce7565b60055491935091506105dc908390611848565b6001600160a01b038116600090815260096020526040812080548291908061162d5760405162461bcd60e51b815260040161064590612004565b60009350839250828080805b84811015610e7a5785818154811061165357611653611f49565b6000918252602090912001546001600160a01b031691508131881161172d57604051630614af2b60e11b8152600160048201526001600160a01b03831690630c295e569060240160a060405180830381865afa1580156116b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116db9190612045565b50929650919450600091506116ed9050565b8460028111156116ff576116ff612092565b14801561170b57508783115b8015611721575082826001600160a01b03163110155b1561172d578196508297505b611736816120a8565b9050611639565b600080600061174b84610ce7565b90925090506001600160a01b0381166117965760405162461bcd60e51b815260206004820152600d60248201526c139bc81c1bdbdb08199bdd5b99609a1b6044820152606401610645565b60001982036117d75760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420707269636560981b6044820152606401610645565b60006117e4836005611848565b9050348111156118365760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f7567682045544820666f72207072696365206f66204e4654006044820152606401610645565b61183f82611190565b95945050505050565b6000806000806118588686611b1d565b9194509250905060008161186c8486611f20565b6118769190611f20565b90508681106118975760405162461bcd60e51b8152600401610645906121f9565b6118a18188611f20565b979650505050505050565b6000806000806118bc8686611b1d565b919450925090506000816118d08486611f20565b6118da9190611f20565b90508681106118fb5760405162461bcd60e51b8152600401610645906121f9565b6118a18188611f07565b6001546001600160a01b031633146119745760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c20736574436f60448201526b6e7472696275746f7246656560a01b6064820152608401610645565b600355565b600080611987836000611b1d565b509094909350915050565b6001600160a01b038216600090815260076020526040812080548392906119ba908490611f20565b9250508190555080600860008282546119d39190611f20565b90915550506001600160a01b0382166000908152600760205260409020546002548110611b185780471015611a4a5760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820455448206f6e20636f6e74726163740000000000006044820152606401610645565b806008541015611aae5760405162461bcd60e51b815260206004820152602960248201527f446f6e2774206c6f736520747261636b206f6620686f77206d7563682045544860448201526820776520686176652160b81b6064820152608401610645565b6001600160a01b038316600090815260076020526040812081905560088054839290611adb908490611f07565b90915550506040516001600160a01b0384169082156108fc029083906000818181858888f19350505050158015611b16573d6000803e3d6000fd5b505b505050565b60008060006103e86003541115611b935760405162461bcd60e51b815260206004820152603460248201527f636f6e7472696275746f7246656550657254686f7573616e64206d7573742062604482015273065206265747765656e203020616e6420313030360641b6064820152608401610645565b6103e86004541115611c015760405162461bcd60e51b815260206004820152603160248201527f70726f746f636f6c46656550657254686f7573616e64206d7573742062652062604482015270065747765656e203020616e64203130303607c1b6064820152608401610645565b6103e8841115611c6a5760405162461bcd60e51b815260206004820152602e60248201527f736c69707061676550657254686f7573616e64206d757374206265206265747760448201526d065656e203020616e6420313030360941b6064820152608401610645565b6000611c78866103e861223b565b9050858111611cc95760405162461bcd60e51b815260206004820152601a60248201527f4f766572666c6f7720696e2072657363616c65642070726963650000000000006044820152606401610645565b600354620f4240908190611cdd908461223b565b611ce79190611fe2565b9350868410611d4a5760405162461bcd60e51b815260206004820152602960248201527f436f6e7472696275746f72206665652073686f756c64206265206c657373207460448201526868616e20707269636560b81b6064820152608401610645565b8060045483611d59919061223b565b611d639190611fe2565b9450868510611dc35760405162461bcd60e51b815260206004820152602660248201527f50726f746f636f6c206665652073686f756c64206265206c657373207468616e60448201526520707269636560d01b6064820152608401610645565b8515611e405780611dd4878461223b565b611dde9190611fe2565b9250868310611e3b5760405162461bcd60e51b8152602060048201526024808201527f536c6970706167652063616e6e6f742062652067726561746572207468616e206044820152633130302560e01b6064820152608401610645565b611e45565b600092505b50509250925092565b6001600160a01b0381168114611e6357600080fd5b50565b600060208284031215611e7857600080fd5b8135611e8381611e4e565b9392505050565b600060208284031215611e9c57600080fd5b5035919050565b60008060408385031215611eb657600080fd5b8235611ec181611e4e565b946020939093013593505050565b60008060408385031215611ee257600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f1a57611f1a611ef1565b92915050565b80820180821115611f1a57611f1a611ef1565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60a0808252865190820181905260009060209060c0840190828a01845b82811015611f9857815184529284019290840190600101611f7c565b50505090830196909652506001600160a01b0393841660408201529115156060830152909116608090910152919050565b600060208284031215611fdb57600080fd5b5051919050565b600082611fff57634e487b7160e01b600052601260045260246000fd5b500490565b60208082526021908201527f4e6f20706f6f6c73207265676973746572656420666f7220676976656e204e466040820152601560fa1b606082015260800190565b600080600080600060a0868803121561205d57600080fd5b85516003811061206c57600080fd5b602087015160408801516060890151608090990151929a91995097965090945092505050565b634e487b7160e01b600052602160045260246000fd5b6000600182016120ba576120ba611ef1565b5060010190565b6001600160a01b038316815260408101600483106120ef57634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b60006020828403121561210e57600080fd5b81518015158114611e8357600080fd5b60006020828403121561213057600080fd5b8151611e8381611e4e565b6000602080838503121561214e57600080fd5b825167ffffffffffffffff8082111561216657600080fd5b818501915085601f83011261217a57600080fd5b81518181111561218c5761218c611f33565b8060051b604051601f19603f830116810181811085821117156121b1576121b1611f33565b6040529182528482019250838101850191888311156121cf57600080fd5b938501935b828510156121ed578451845293850193928501926121d4565b98975050505050505050565b60208082526022908201527f46656573202b20736c6970706167652063616e6e6f7420657863656564203130604082015261302560f01b606082015260800190565b600081600019048311821515161561225557612255611ef1565b50029056fea26469706673582212201a20b86a8eec939dd32c177413eea6220379083cc45a5aff2864aefda8d1ff4a64736f6c63430008100033

Deployed Bytecode

0x6080604052600436106101d15760003560e01c80638da5cb5b116100f7578063da72a26111610095578063f088d54711610064578063f088d5471461054a578063f61c205c1461055d578063fdb26ec71461057d578063febbfa871461059d57600080fd5b8063da72a261146104de578063dd013184146104f4578063dd93f59a14610514578063e6a014cb1461053457600080fd5b8063ad7a672f116100d1578063ad7a672f14610465578063ba5bddd71461047b578063cce516b71461048e578063cdfc89aa146104ae57600080fd5b80638da5cb5b146103f55780638f38a55514610415578063abd908461461043557600080fd5b80634173393b1161016f5780636b7b91121161013e5780636b7b9112146103755780636c197ff514610395578063787dce3d146103b557806379c81992146103d557600080fd5b80634173393b1461030a57806344bd1afd146103205780634818cfd4146103405780634a6750401461036057600080fd5b806327e235e3116101ab57806327e235e3146102845780632d2f2be4146102bf5780633a1f656e146102d55780633ccfd60b146102f557600080fd5b80630b209fb3146101dd57806315945f781461023057806320800a001461026d57600080fd5b366101d857005b600080fd5b3480156101e957600080fd5b506102136101f8366004611e66565b600b602052600090815260409020546001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023c57600080fd5b5061025061024b366004611e66565b6105bd565b604080519283526001600160a01b03909116602083015201610227565b34801561027957600080fd5b506102826105e3565b005b34801561029057600080fd5b506102b161029f366004611e66565b60076020526000908152604090205481565b604051908152602001610227565b3480156102cb57600080fd5b506102b160055481565b3480156102e157600080fd5b506102826102f0366004611e66565b6106ff565b34801561030157600080fd5b50610282610794565b34801561031657600080fd5b506102b160025481565b34801561032c57600080fd5b5061028261033b366004611e8a565b610849565b34801561034c57600080fd5b5061028261035b366004611e8a565b6108be565b34801561036c57600080fd5b506102b1610939565b34801561038157600080fd5b50610282610390366004611e66565b610950565b3480156103a157600080fd5b506102826103b0366004611ea3565b6109e5565b3480156103c157600080fd5b506102826103d0366004611e8a565b610c76565b3480156103e157600080fd5b506102506103f0366004611e66565b610ce7565b34801561040157600080fd5b50600154610213906001600160a01b031681565b34801561042157600080fd5b50610213610430366004611ea3565b610ee5565b34801561044157600080fd5b50610455610450366004611e66565b610f1d565b6040519015158152602001610227565b34801561047157600080fd5b506102b160085481565b6102b1610489366004611e66565b611190565b34801561049a57600080fd5b50600654610213906001600160a01b031681565b3480156104ba57600080fd5b506104556104c9366004611e66565b600a6020526000908152604090205460ff1681565b3480156104ea57600080fd5b506102b160035481565b34801561050057600080fd5b5061025061050f366004611e66565b6115d4565b34801561052057600080fd5b5061025061052f366004611e66565b6115f3565b34801561054057600080fd5b506102b160045481565b6102b1610558366004611e66565b61173d565b34801561056957600080fd5b506102b1610578366004611ecf565b611848565b34801561058957600080fd5b506102b1610598366004611ecf565b6118ac565b3480156105a957600080fd5b506102826105b8366004611e8a565b611905565b6000806105c9836115f3565b60055491935091506105dc9083906118ac565b9150915091565b6001546001600160a01b0316331461064e5760405162461bcd60e51b8152602060048201526024808201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c2072657363756044820152630ca8aa8960e31b60648201526084015b60405180910390fd5b6008544710156106b05760405162461bcd60e51b815260206004820152602760248201527f4e6f7420656e6f75676820455448206f6e20636f6e747261637420666f722062604482015266616c616e63657360c81b6064820152608401610645565b6000600854476106c09190611f07565b6001546040519192506001600160a01b03169082156108fc029083906000818181858888f193505050501580156106fb573d6000803e3d6000fd5b5050565b6001546001600160a01b031633146107725760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c20736574506160448201526f6972466163746f72794164647265737360801b6064820152608401610645565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b336000908152600760205260409020544781106107f35760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820455448206f6e20636f6e74726163740000000000006044820152606401610645565b33600090815260076020526040812081905560088054839290610817908490611f07565b9091555050604051339082156108fc029083906000818181858888f193505050501580156106fb573d6000803e3d6000fd5b6001546001600160a01b031633146108b95760405162461bcd60e51b815260206004820152602d60248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c20736574446560448201526c6661756c74536c69707061676560981b6064820152608401610645565b600555565b6001546001600160a01b031633146109345760405162461bcd60e51b815260206004820152603360248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c207365744d69604482015272372130b630b731b2a337b92a3930b739b332b960691b6064820152608401610645565b600255565b600060035460045461094b9190611f20565b905090565b6001546001600160a01b031633146109c35760405162461bcd60e51b815260206004820152603060248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c20736574507260448201526f6f746f636f6c4665654164647265737360801b6064820152608401610645565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000806109f1846115f3565b60408051600180825281830190925292945090925060009190602080830190803683370190505090508381600081518110610a2e57610a2e611f49565b602090810291909101015260405163b1d3f1c160e01b81526000906001600160a01b0384169063b1d3f1c190610a709085908890309087908190600401611f5f565b6020604051808303816000875af1158015610a8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab39190611fc9565b905060008111610b055760405162461bcd60e51b815260206004820152601760248201527f4469646e27742067657420616e7920455448206261636b0000000000000000006044820152606401610645565b610b10600285611fe2565b8111610b6a5760405162461bcd60e51b8152602060048201526024808201527f53616c6520707269636520736c6970706167652067726561746572207468616e6044820152632035302560e01b6064820152608401610645565b600080610b7683611979565b6001600160a01b038088166000908152600b6020526040902054919450919250610ba1911683611992565b600654610bb7906001600160a01b031682611992565b6000610bc38383611f20565b9050838110610c275760405162461bcd60e51b815260206004820152602a60248201527f466565732063616e2774206578636565642045544820726563656976656420666044820152696f722073656c6c696e6760b01b6064820152608401610645565b6000610c338286611f07565b90508015610c6a57604051339082156108fc029083906000818181858888f19350505050158015610c68573d6000803e3d6000fd5b505b50505050505050505050565b6001546001600160a01b03163314610ce25760405162461bcd60e51b815260206004820152602960248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c2073657450726044820152686f746f636f6c46656560b81b6064820152608401610645565b600455565b6001600160a01b0381166000908152600960205260408120805482919080610d215760405162461bcd60e51b815260040161064590612004565b600019935060009250828080805b84811015610e7a57858181548110610d4957610d49611f49565b6000918252602090912001546040516370a0823160e01b81526001600160a01b03918216600482018190529350908a16906370a0823190602401602060405180830381865afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190611fc9565b15610e6a5760405163a5cb2b9160e01b8152600160048201526001600160a01b0383169063a5cb2b919060240160a060405180830381865afa158015610e0e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e329190612045565b5092965091945060009150610e449050565b846002811115610e5657610e56612092565b03610e6a5787831015610e6a578196508297505b610e73816120a8565b9050610d2f565b6001600160a01b038716610eda5760405162461bcd60e51b815260206004820152602160248201527f436f756c64206e6f742066696e64206120706f6f6c20746f206275792066726f6044820152606d60f81b6064820152608401610645565b505050505050915091565b60096020528160005260406000208181548110610f0157600080fd5b6000918252602090912001546001600160a01b03169150829050565b6001600160a01b0381166000908152600a602052604081205460ff1615610f7b5760405162461bcd60e51b81526020600482015260126024820152712837b7b61030b63932b0b23c9035b737bbb760711b6044820152606401610645565b600080546040516308f25a8f60e01b81526001600160a01b03909116916308f25a8f91610fac9186916004016120c1565b602060405180830381865afa158015610fc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fed91906120fc565b6110b1576000546040516308f25a8f60e01b81526001600160a01b03909116906308f25a8f906110249085906001906004016120c1565b602060405180830381865afa158015611041573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106591906120fc565b6110b15760405162461bcd60e51b815260206004820152601760248201527f4e6f742061207375646f737761702045544820706f6f6c0000000000000000006044820152606401610645565b6001600160a01b0382166000818152600a60209081526040808320805460ff19166001179055600b825280832080546001600160a01b0319163317905580516323e6650160e11b815290519293926347ccca02926004808401939192918290030181865afa158015611127573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114b919061211e565b6001600160a01b0390811660009081526009602090815260408220805460018101825590835291200180546001600160a01b0319169490911693909317909255919050565b600080826001600160a01b03166347ccca026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111f5919061211e565b6040516370a0823160e01b81526001600160a01b0385811660048301529192506000918316906370a0823190602401602060405180830381865afa158015611241573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112659190611fc9565b116112a55760405162461bcd60e51b815260206004820152601060248201526f506f6f6c20686173206e6f204e46547360801b6044820152606401610645565b6000836001600160a01b0316632f4fefaf6040518163ffffffff1660e01b8152600401600060405180830381865afa1580156112e5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261130d919081019061213b565b9050806001825161131e9190611f07565b8151811061132e5761132e611f49565b60200260200101519250600034905060008061134983611979565b9092509050600061135a8383611f20565b6113649085611f07565b6040516328b8aee160e01b81526001600482015260248101829052336044820152600060648201819052608482018190529192506001600160a01b038a16906328b8aee190849060a40160206040518083038185885af11580156113cc573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906113f19190611fc9565b90508481106114565760405162461bcd60e51b815260206004820152602b60248201527f43616e277420757365206d6f726520455448207468616e20776173206f72696760448201526a1a5b985b1b1e481cd95b9d60aa1b6064820152608401610645565b600081116114b85760405162461bcd60e51b815260206004820152602960248201527f54686572652061696e2774206e6f2073756368207468696e67206173206120666044820152680e4caca40d8eadcc6d60bb1b6064820152608401610645565b6000806114c483611979565b9250905060006114d48383611f20565b6114de9085611f20565b9050878111156115465760405162461bcd60e51b815260206004820152602d60248201527f43616e2774207370656e64206d6f7265207468616e2077652077657265206f7260448201526c1a59da5b985b1b1e481cd95b9d609a1b6064820152608401610645565b6001600160a01b03808d166000908152600b602052604090205461156b911684611992565b600654611581906001600160a01b031683611992565b600061158d828a611f07565b905080156115c457604051339082156108fc029083906000818181858888f193505050501580156115c2573d6000803e3d6000fd5b505b5050505050505050505050919050565b6000806115e083610ce7565b60055491935091506105dc908390611848565b6001600160a01b038116600090815260096020526040812080548291908061162d5760405162461bcd60e51b815260040161064590612004565b60009350839250828080805b84811015610e7a5785818154811061165357611653611f49565b6000918252602090912001546001600160a01b031691508131881161172d57604051630614af2b60e11b8152600160048201526001600160a01b03831690630c295e569060240160a060405180830381865afa1580156116b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116db9190612045565b50929650919450600091506116ed9050565b8460028111156116ff576116ff612092565b14801561170b57508783115b8015611721575082826001600160a01b03163110155b1561172d578196508297505b611736816120a8565b9050611639565b600080600061174b84610ce7565b90925090506001600160a01b0381166117965760405162461bcd60e51b815260206004820152600d60248201526c139bc81c1bdbdb08199bdd5b99609a1b6044820152606401610645565b60001982036117d75760405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420707269636560981b6044820152606401610645565b60006117e4836005611848565b9050348111156118365760405162461bcd60e51b815260206004820152601f60248201527f4e6f7420656e6f7567682045544820666f72207072696365206f66204e4654006044820152606401610645565b61183f82611190565b95945050505050565b6000806000806118588686611b1d565b9194509250905060008161186c8486611f20565b6118769190611f20565b90508681106118975760405162461bcd60e51b8152600401610645906121f9565b6118a18188611f20565b979650505050505050565b6000806000806118bc8686611b1d565b919450925090506000816118d08486611f20565b6118da9190611f20565b90508681106118fb5760405162461bcd60e51b8152600401610645906121f9565b6118a18188611f07565b6001546001600160a01b031633146119745760405162461bcd60e51b815260206004820152602c60248201527f4f6e6c79206f776e657220616c6c6f77656420746f2063616c6c20736574436f60448201526b6e7472696275746f7246656560a01b6064820152608401610645565b600355565b600080611987836000611b1d565b509094909350915050565b6001600160a01b038216600090815260076020526040812080548392906119ba908490611f20565b9250508190555080600860008282546119d39190611f20565b90915550506001600160a01b0382166000908152600760205260409020546002548110611b185780471015611a4a5760405162461bcd60e51b815260206004820152601a60248201527f4e6f7420656e6f75676820455448206f6e20636f6e74726163740000000000006044820152606401610645565b806008541015611aae5760405162461bcd60e51b815260206004820152602960248201527f446f6e2774206c6f736520747261636b206f6620686f77206d7563682045544860448201526820776520686176652160b81b6064820152608401610645565b6001600160a01b038316600090815260076020526040812081905560088054839290611adb908490611f07565b90915550506040516001600160a01b0384169082156108fc029083906000818181858888f19350505050158015611b16573d6000803e3d6000fd5b505b505050565b60008060006103e86003541115611b935760405162461bcd60e51b815260206004820152603460248201527f636f6e7472696275746f7246656550657254686f7573616e64206d7573742062604482015273065206265747765656e203020616e6420313030360641b6064820152608401610645565b6103e86004541115611c015760405162461bcd60e51b815260206004820152603160248201527f70726f746f636f6c46656550657254686f7573616e64206d7573742062652062604482015270065747765656e203020616e64203130303607c1b6064820152608401610645565b6103e8841115611c6a5760405162461bcd60e51b815260206004820152602e60248201527f736c69707061676550657254686f7573616e64206d757374206265206265747760448201526d065656e203020616e6420313030360941b6064820152608401610645565b6000611c78866103e861223b565b9050858111611cc95760405162461bcd60e51b815260206004820152601a60248201527f4f766572666c6f7720696e2072657363616c65642070726963650000000000006044820152606401610645565b600354620f4240908190611cdd908461223b565b611ce79190611fe2565b9350868410611d4a5760405162461bcd60e51b815260206004820152602960248201527f436f6e7472696275746f72206665652073686f756c64206265206c657373207460448201526868616e20707269636560b81b6064820152608401610645565b8060045483611d59919061223b565b611d639190611fe2565b9450868510611dc35760405162461bcd60e51b815260206004820152602660248201527f50726f746f636f6c206665652073686f756c64206265206c657373207468616e60448201526520707269636560d01b6064820152608401610645565b8515611e405780611dd4878461223b565b611dde9190611fe2565b9250868310611e3b5760405162461bcd60e51b8152602060048201526024808201527f536c6970706167652063616e6e6f742062652067726561746572207468616e206044820152633130302560e01b6064820152608401610645565b611e45565b600092505b50509250925092565b6001600160a01b0381168114611e6357600080fd5b50565b600060208284031215611e7857600080fd5b8135611e8381611e4e565b9392505050565b600060208284031215611e9c57600080fd5b5035919050565b60008060408385031215611eb657600080fd5b8235611ec181611e4e565b946020939093013593505050565b60008060408385031215611ee257600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b81810381811115611f1a57611f1a611ef1565b92915050565b80820180821115611f1a57611f1a611ef1565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60a0808252865190820181905260009060209060c0840190828a01845b82811015611f9857815184529284019290840190600101611f7c565b50505090830196909652506001600160a01b0393841660408201529115156060830152909116608090910152919050565b600060208284031215611fdb57600080fd5b5051919050565b600082611fff57634e487b7160e01b600052601260045260246000fd5b500490565b60208082526021908201527f4e6f20706f6f6c73207265676973746572656420666f7220676976656e204e466040820152601560fa1b606082015260800190565b600080600080600060a0868803121561205d57600080fd5b85516003811061206c57600080fd5b602087015160408801516060890151608090990151929a91995097965090945092505050565b634e487b7160e01b600052602160045260246000fd5b6000600182016120ba576120ba611ef1565b5060010190565b6001600160a01b038316815260408101600483106120ef57634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b60006020828403121561210e57600080fd5b81518015158114611e8357600080fd5b60006020828403121561213057600080fd5b8151611e8381611e4e565b6000602080838503121561214e57600080fd5b825167ffffffffffffffff8082111561216657600080fd5b818501915085601f83011261217a57600080fd5b81518181111561218c5761218c611f33565b8060051b604051601f19603f830116810181811085821117156121b1576121b1611f33565b6040529182528482019250838101850191888311156121cf57600080fd5b938501935b828510156121ed578451845293850193928501926121d4565b98975050505050505050565b60208082526022908201527f46656573202b20736c6970706167652063616e6e6f7420657863656564203130604082015261302560f01b606082015260800190565b600081600019048311821515161561225557612255611ef1565b50029056fea26469706673582212201a20b86a8eec939dd32c177413eea6220379083cc45a5aff2864aefda8d1ff4a64736f6c63430008100033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.