false
false
0

Contract Address Details

0xf0eDCe5366164f326b9F56DfeBc97Df7D3911112

Contract Name
IDO
Creator
0xc7d98c–7f3521 at 0xe93d3c–d5cb82
Balance
0 CLO
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
16289999
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
IDO




Optimization enabled
true
Compiler version
v0.8.7+commit.e28d00a7




Optimization runs
200
EVM Version
default




Verified at
2024-09-26T15:32:21.467716Z

Contract source code

// SPDX-License-Identifier: No License (None)
pragma solidity ^0.8.0;

/**
 * @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 {
    address internal _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
/*    constructor () {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);
    }
*/
    /**
     * @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() {
        require(owner() == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

/**
 * @dev Interface of the ERC223 standard as defined in the EIP.
 */
interface IERC223 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);
    
    
    function transfer(address recipient, uint256 amount, bytes calldata data) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


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

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

interface IPriceFeed {
    function getPrice(address token) external view returns(uint256);
}

contract IDO is Ownable, ReentrancyGuard {
    struct Round {
        uint256 soyToSell;  // amount of SOY sell in this round
        uint256 usdCollected;   // USD value received in this round
        uint256 hardCap;    // maximum amount of USD that can be collected by this round
        uint256 softCap;    // minimum amount of USD to collect
        uint256 start;  // timestamp when auction start
        uint256 end;    // timestamp when auction end
    }

    struct Bet {
        uint256 usdValue;       // contributed usd in this round
        uint256 soyAmount;      // amount locked SOY
        uint256 lockedUntil;    // locked until
    }

    //mapping(uint256 => mapping(address => AcceptedToken)) public totalBets; // auction => token address => AcceptedToken
    mapping(uint256 => mapping(address => Bet)) public bets;    // round ID => user address => Bet
    mapping(uint256 => Round) public auctionRound; // round ID => Round
    mapping(address => bool) public allowedToken;   // token accepted for payment
    bool public isPaused;
    address constant public SoyToken = address(0x9FaE2529863bD691B4A7171bDfCf33C7ebB10a65);
    uint256 constant public RATIO = 1017233603000000000; // 1.017233603
    address constant public priceFeed = address(0x9bFc3046ea26f8B09D3E85bd22AEc96C80D957e3);   // price feed contract
    address payable public bank;    // receiver of bets tokens
    uint256 public totalSoyToSell;  // total amount of Soy to sell
    uint256 public totalSoySold;    // total amount of sold Soy including Soy in active auction.
    uint256 public auctionRounds;   // number of auction rounds
    uint256 public currentRoundId;  // current auction round (round starts from 1)


    //uint256 public soyPerAuctionPeriod;
    uint256 public roundDuration;  // auction round duration (in seconds).
    uint256 public lockPeriod;   // period while tokens will be locked
    uint256 public lockPercentage;  // percentage of bought tokens that will be locked
    uint256 public minPricePercentage;  // percentage of previous auction price assign to min price
    uint256 public maxPricePercentage;  // maxPrice = lastRoundSoyPrice * maxPricePercentage / 100
    uint256 public lastRoundSoyPrice;       // previous auction price
    uint256 public maxExtendRounds;    // maximum number of rounds to extend tha auction
    uint256 public burntAmount;


    event RoundEnds(uint256 indexed roundID, uint256 soySold, uint256 usdCollected);
    event Rescue(address _token, uint256 _amount);
    event SetBank(address _bank);
    event UserBet(uint256 indexed roundID, address indexed user, address indexed token, uint256 usdValue, uint256 tokenAmount);
    event ChangeWallet(address oldWallet, address newWallet);

    modifier notPaused() {
        require(!isPaused, "Paused");
        _;
    }

    function initialize() external {
        require(_owner == address(0), "Already initialized");
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), msg.sender);
        lockPeriod = 365 days;   // period while tokens will be locked
        minPricePercentage = 90;  // percentage of previous auction price assign to min price
        maxExtendRounds = 3;    // maximum number of rounds to extend the auction

        /*// weekly auction
        roundDuration = 7 days;  // auction round duration (in seconds).
        maxPricePercentage = 500; // maxPrice = lastRoundSoyPrice * maxPricePercentage / 100
        lockPercentage = 70;    // 50% of Soy will be locked
        auctionRounds = 26;   // number of auction rounds
        */
        // daily auction
        roundDuration = 1 days;  // auction round duration (in seconds).
        maxPricePercentage = 160; // maxPrice = lastRoundSoyPrice * maxPricePercentage / 100
        lockPercentage = 50;    // 50% of Soy will be locked
        auctionRounds = 180;   // number of auction rounds
    }

    function setPause(bool state) external onlyOwner {
        isPaused = state;
    }

    function setBank(address payable _bank) onlyOwner external
    {
        require(_bank != address(0), "Zero address not allowed");
        bank = _bank;
        emit SetBank(_bank);
    }

    function setLastRoundSoyPrice(uint256 val) external onlyOwner {
        lastRoundSoyPrice = val;
    }

    function setMinPricePercentage(uint256 val) external onlyOwner {
        minPricePercentage = val;
    }

    function setMaxPricePercentage(uint256 val) external onlyOwner {
        maxPricePercentage = val;
    }

    function setLockPercentage(uint256 val) external onlyOwner {
        lockPercentage = val;
    }

    function setLockPeriod(uint256 val) external onlyOwner {
        lockPeriod = val;
    }

    function setRoundDuration(uint256 val) external onlyOwner {
        roundDuration = val;
    }

    function setMaxExtendRounds(uint256 val) external onlyOwner {
        maxExtendRounds = val;
    }

    function setAuctionRounds(uint256 val) external onlyOwner {
        require(val >= currentRoundId);
        auctionRounds = val;
    }

    function setAllowedToken(address token, bool state) external onlyOwner {
        require(token != address(0));
        allowedToken[token] = state;
    }

    // set amount to sell at current round
    function setRoundSellAmount(uint256 amount) external onlyOwner {
        uint256 currentAmount = auctionRound[currentRoundId].soyToSell;
        totalSoySold = totalSoySold + amount - currentAmount;
        require(totalSoyToSell >= totalSoySold, "Wrong amount");
        auctionRound[currentRoundId].soyToSell = amount;
        auctionRound[currentRoundId].hardCap = amount * lastRoundSoyPrice * maxPricePercentage / 10**20;    // 100 * 10**18
        auctionRound[currentRoundId].softCap = amount * lastRoundSoyPrice * minPricePercentage / 10**20;    // 100 * 10**18
    }

    function auctionStart(uint256 startTime, uint256 soyPrice) external onlyOwner {
        require(currentRoundId == 0, "Only start once");
        require(totalSoyToSell != 0, "No SOY to sell");
        lastRoundSoyPrice = soyPrice;
        auctionRound[0].soyToSell = 29491750873668297408771; // auctionRound[0] * RATIO / 10**18 == 30 000 SOY for first day in daily auction.
        startRound(startTime);
    }

    function claim() external {
        claimBehalf(msg.sender, 1, currentRoundId);
    }

    function claimBehalf(address user) public {
        claimBehalf(user, 1, currentRoundId);
    }

    // claim SOY tokens from numbers of auction rounds (fromRound to toRound). toRound is excluded.
    function claimBehalf(address user, uint256 fromRound, uint256 toRound) public nonReentrant {
        require(fromRound < toRound && toRound <= currentRoundId, "Incorrect rounds parameters");
        uint256 soyToClaim;
        uint256 _lockPercentage = lockPercentage;
        uint256 _lockPeriod = lockPeriod;
        for (uint256 i = fromRound; i<toRound; i++) {
            uint256 usdValue = bets[i][user].usdValue;
            if (usdValue != 0) { // user contributed in this round
                if (bets[i][user].lockedUntil == 0) { // receive token from round
                    uint256 total = auctionRound[i].soyToSell * usdValue / auctionRound[i].usdCollected;
                    uint256 locked = total * _lockPercentage / 100;
                    soyToClaim += (total - locked);
                    bets[i][user].soyAmount = locked;
                    bets[i][user].lockedUntil = auctionRound[i].end + _lockPeriod;
                    bets[i][user].usdValue = 0;
                }
            }
            // Check if can claim locked tokens 
            uint256 soyAmount = bets[i][user].soyAmount;
            if (soyAmount != 0 && bets[i][user].lockedUntil < block.timestamp) {
                uint256 initialAmount = soyAmount * 100 / _lockPercentage;
                uint256 bonus = initialAmount * 25 / 100;   // 25% bonus
                soyToClaim += (soyAmount + bonus);
                bets[i][user].soyAmount = 0;
            }
        }
        IERC223(SoyToken).transfer(user, soyToClaim);
    }

    // return amount of SOY tokens that user may claim and amount that locked
    function getTokenToClaim(address user) external view returns(uint256 soyToClaim, uint256 soyLocked) {
        uint256 toRound = currentRoundId;
        uint256 _lockPercentage = lockPercentage;
        uint256 _lockPeriod = lockPeriod;
        for (uint256 i = 1; i < toRound; i++) {
            uint256 usdValue = bets[i][user].usdValue;
            if (usdValue != 0) { // user contributed in this round
                uint256 lockedUntil = bets[i][user].lockedUntil;
                uint256 locked;
                if (lockedUntil == 0) { // receive token from round
                    uint256 total = auctionRound[i].soyToSell * usdValue / auctionRound[i].usdCollected;
                    locked = total * _lockPercentage / 100;
                    soyToClaim += (total - locked);
                    lockedUntil = auctionRound[i].end + _lockPeriod;
                }
                if (lockedUntil < block.timestamp) {
                    soyToClaim += bets[i][user].soyAmount;
                    soyToClaim += locked;   // in case of user do first claim in 1 year after auction end.
                } else {
                    soyLocked += bets[i][user].soyAmount;
                    soyLocked += locked;
                }
            } else if (bets[i][user].soyAmount != 0){
                if (bets[i][user].lockedUntil < block.timestamp) {
                    soyToClaim += bets[i][user].soyAmount;
                } else {
                    soyLocked += bets[i][user].soyAmount;
                }
            }
        }
    }

    // Returns arrays of locked SOY, unlock timestamp, SOY price (in USD with 18 decimals). Array index 0 = round 1 and so on.
    // And total amount of SOY that user may claim and amount of SOY that is locked.
    function getUserDetail(address user) external view 
    returns(uint256[] memory lockedSoy, uint256[] memory lockedDate, uint256[] memory soyPrice, uint256 soyToClaim, uint256 soyLocked) 
    {
        uint256 currentRound = currentRoundId;
        lockedSoy = new uint256[](currentRound-1);
        lockedDate = new uint256[](currentRound-1);
        soyPrice = new uint256[](currentRound-1);

        uint256 _lockPercentage = lockPercentage;
        uint256 _lockPeriod = lockPeriod;
        for (uint256 i = 1; i < currentRound; i++) {
            uint256 usdValue = bets[i][user].usdValue;
            if (usdValue != 0) { // user contributed in this round
                uint256 lockedUntil = bets[i][user].lockedUntil;
                uint256 locked;
                if (lockedUntil == 0) { // receive token from round
                    uint256 total = auctionRound[i].soyToSell * usdValue / auctionRound[i].usdCollected;
                    locked = total * _lockPercentage / 100;
                    soyToClaim += (total - locked);
                    lockedUntil = auctionRound[i].end + _lockPeriod;
                    lockedDate[i-1] = lockedUntil;
                    lockedSoy[i-1] = locked;
                    soyPrice[i-1] = auctionRound[i].usdCollected * 10**18 / auctionRound[i].soyToSell;
                }
                if (lockedUntil < block.timestamp) {
                    soyToClaim += bets[i][user].soyAmount;
                    soyToClaim += locked;   // in case of user do first claim in 1 year after auction end.
                } else {
                    soyLocked += bets[i][user].soyAmount;
                    soyLocked += locked;
                }
            } else if (bets[i][user].soyAmount != 0){
                lockedDate[i-1] = bets[i][user].lockedUntil;
                lockedSoy[i-1] = bets[i][user].soyAmount;
                soyPrice[i-1] = auctionRound[i].usdCollected * 10**18 / auctionRound[i].soyToSell;                
                if (lockedDate[i-1] < block.timestamp) {
                    soyToClaim += lockedSoy[i-1];
                } else {
                    soyLocked += lockedSoy[i-1];
                }
            }
        }
    }

    
    // returns USD value collected in the current round and total USD value collected during the auction
    function getCollectedUSD() external view returns(uint256 currentRoundUSD, uint256 totalUSD) {
        uint256 currentRound = currentRoundId;
        currentRoundUSD = auctionRound[currentRound].usdCollected;
        for (uint i=1; i<=currentRound; i++) {
            totalUSD = auctionRound[i].usdCollected;
        }
    }

    // returns USD value collected in the round
    function getCollectedUSD(uint256 round) external view returns(uint256) {
        return auctionRound[round].usdCollected;
    }

    // Bet with ERC223 token
    function tokenReceived(address _from, uint _value, bytes calldata _data) external {
        if (msg.sender == SoyToken && _from == owner()) {
            totalSoyToSell += _value;
            return;
        }
        require(allowedToken[msg.sender], "Token isn't allowed");
        userBet(_from, msg.sender, _value); // user, token, amount
    }

    receive() external payable {
        makeBet(address(1), msg.value);
    }

    // make bet to Auction
    function makeBet(address token, uint256 amount) public payable  {
        require(allowedToken[token], "Token isn't allowed");
        if (token == address(1)) {
            require(amount == msg.value, "Incorrect CLO amount");
        } else {
            require(msg.value == 0, "Only token");
            IERC223(token).transferFrom(msg.sender, address(this), amount);
        }
        userBet(msg.sender, token, amount);
    }

    function userBet(address user, address token, uint256 amount) internal notPaused nonReentrant {
        if (checkRound()) // if last round finished - return money to sender.
        {
            transferTo(token, amount, user);
            return;
        }
        uint256 roundID = currentRoundId;
        uint256 price = getPrice(token);
        Round storage round = auctionRound[roundID];
        Bet storage bet = bets[roundID][user];
        uint256 totalUSD = round.usdCollected + (amount * price / 10**18);
        if (totalUSD >= round.hardCap) {
            uint256 rest = totalUSD - round.hardCap; // rest of USD
            rest = rest * 10**18 / price; // rest in token
            if (rest > amount) rest = amount; // this condition shouldn't be true but added to be safe.
            round.usdCollected = round.hardCap;
            amount = amount - rest; // amount of token that bet in this round
            endRound(block.timestamp);
            if (rest != 0) transferTo(token, rest, user); // return rest to the user
        } else {
            round.usdCollected = totalUSD;
        }
        uint256 usdValue = amount * price / 10**18;
        bet.usdValue += usdValue;    // update user's bet
        transferTo(token, amount, bank);    // transfer token to the bank address
        emit UserBet(roundID, user, token, usdValue, amount);
    }

    function startRound(uint256 startTime) internal {
        currentRoundId++;
        require(currentRoundId <= auctionRounds, "All rounds completed");
        Round storage round = auctionRound[currentRoundId];
        round.start = startTime;
        round.end = startTime + roundDuration;
        // calculate amount of Soy to sell per round.
        uint256 soyToSell;
        if (roundDuration == 1 days) {
            soyToSell = auctionRound[currentRoundId - 1].soyToSell * RATIO / 10**18;
            if ((totalSoyToSell - totalSoySold) < soyToSell) {
                soyToSell = totalSoyToSell - totalSoySold;  // if left less Soy then we need due to calculation - sell all available Soy
            }
        } else {
            uint256 roundsLeft = auctionRounds + 1 - currentRoundId;
            soyToSell = (totalSoyToSell - totalSoySold) / roundsLeft;
        }

        round.soyToSell = soyToSell;
        totalSoySold += soyToSell;
        round.hardCap = soyToSell * lastRoundSoyPrice * maxPricePercentage / 10**20;    // 100 * 10**18
        round.softCap = soyToSell * lastRoundSoyPrice * minPricePercentage / 10**20;    // 100 * 10**18
    }

    // return true if last auction round finished
    function endRound(uint256 endTime) internal returns(bool isLastRoundEnd) {
        Round storage round = auctionRound[currentRoundId];
        lastRoundSoyPrice = round.usdCollected * 10**18 / round.soyToSell;
        emit RoundEnds(currentRoundId, round.soyToSell, round.usdCollected);
        if (currentRoundId == auctionRounds) {  // last round
            currentRoundId++;
            isLastRoundEnd = true;
        } else {
            startRound(endTime);  // start new round when previous round ends
        }
    }

    // return true if last auction round finished
    function checkRound() internal returns(bool isLastRoundEnd) {
        Round storage round = auctionRound[currentRoundId];
        require(round.start <= block.timestamp, "Auction is not started yet");
        require(currentRoundId <= auctionRounds, "Auction is finished");
        require(round.soyToSell != 0, "No SOY to sell");
        if (round.end <= block.timestamp) { // auction round finished.
            if (round.usdCollected < round.softCap) {
                // extend auction on next round duration if min threshold was not reached
                uint256 duration = (block.timestamp - round.start) / roundDuration;
                if (duration < maxExtendRounds) {
                    round.end = round.start + ((duration+1)*roundDuration);
                } else {
                    round.end = round.start + (maxExtendRounds * roundDuration);
                    isLastRoundEnd = endRound(round.end);
                }
            } else {
                isLastRoundEnd = endRound(round.end);
            }
        }
    }


    function transferTo(address token, uint256 amount, address receiver) internal {
        if (token == address(1)) {   // transfer CLO 
            payable(receiver).transfer(amount);
        } else {
            IERC223(token).transfer(receiver, amount);
        }
    }

    // get price of token from price feed contract (price in USD with 18 decimals)
    function getPrice(address token) internal view returns(uint256 price) {
        return IPriceFeed(priceFeed).getPrice(token);
    }

    function rescueTokens(address _token) onlyOwner external {
        uint256 amount;
        if (_token == SoyToken) {
            amount = totalSoyToSell-totalSoySold;
            totalSoyToSell = totalSoySold;
        } else {
            amount = IERC223(_token).balanceOf(address(this));
        }
        IERC223(_token).transfer(msg.sender, amount);
        emit Rescue(_token, amount);
    }

    function burn(uint256 amount) onlyOwner external {
        require(currentRoundId > auctionRounds, "Auction is not finished");
        uint256 amountAvailable = totalSoyToSell - totalSoySold - burntAmount;
        require(amountAvailable != 0, "No Soy to burn");
        if (amount > amountAvailable) amount = amountAvailable;
        burntAmount += amount;
        IERC223(SoyToken).transfer(address(0xdEad000000000000000000000000000000000000), amount);
    }

    function changeWallet(address newWallet) external {
        for (uint256 i = 1; i < currentRoundId; i++) {
            if (bets[i][msg.sender].usdValue != 0 || bets[i][msg.sender].soyAmount != 0){
                require(bets[i][newWallet].usdValue == 0 && bets[i][newWallet].soyAmount == 0, "newWallet already in use");
                bets[i][newWallet] = bets[i][msg.sender];
                delete bets[i][msg.sender];
            }
        }
        emit ChangeWallet(msg.sender, newWallet);
    }
}
        

Contract ABI

[{"type":"event","name":"ChangeWallet","inputs":[{"type":"address","name":"oldWallet","internalType":"address","indexed":false},{"type":"address","name":"newWallet","internalType":"address","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":"Rescue","inputs":[{"type":"address","name":"_token","internalType":"address","indexed":false},{"type":"uint256","name":"_amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RoundEnds","inputs":[{"type":"uint256","name":"roundID","internalType":"uint256","indexed":true},{"type":"uint256","name":"soySold","internalType":"uint256","indexed":false},{"type":"uint256","name":"usdCollected","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SetBank","inputs":[{"type":"address","name":"_bank","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"UserBet","inputs":[{"type":"uint256","name":"roundID","internalType":"uint256","indexed":true},{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"usdValue","internalType":"uint256","indexed":false},{"type":"uint256","name":"tokenAmount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"RATIO","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"SoyToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"allowedToken","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"soyToSell","internalType":"uint256"},{"type":"uint256","name":"usdCollected","internalType":"uint256"},{"type":"uint256","name":"hardCap","internalType":"uint256"},{"type":"uint256","name":"softCap","internalType":"uint256"},{"type":"uint256","name":"start","internalType":"uint256"},{"type":"uint256","name":"end","internalType":"uint256"}],"name":"auctionRound","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"auctionRounds","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"auctionStart","inputs":[{"type":"uint256","name":"startTime","internalType":"uint256"},{"type":"uint256","name":"soyPrice","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"bank","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"usdValue","internalType":"uint256"},{"type":"uint256","name":"soyAmount","internalType":"uint256"},{"type":"uint256","name":"lockedUntil","internalType":"uint256"}],"name":"bets","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"burn","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"burntAmount","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeWallet","inputs":[{"type":"address","name":"newWallet","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claim","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimBehalf","inputs":[{"type":"address","name":"user","internalType":"address"},{"type":"uint256","name":"fromRound","internalType":"uint256"},{"type":"uint256","name":"toRound","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimBehalf","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentRoundId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCollectedUSD","inputs":[{"type":"uint256","name":"round","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"currentRoundUSD","internalType":"uint256"},{"type":"uint256","name":"totalUSD","internalType":"uint256"}],"name":"getCollectedUSD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"soyToClaim","internalType":"uint256"},{"type":"uint256","name":"soyLocked","internalType":"uint256"}],"name":"getTokenToClaim","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"lockedSoy","internalType":"uint256[]"},{"type":"uint256[]","name":"lockedDate","internalType":"uint256[]"},{"type":"uint256[]","name":"soyPrice","internalType":"uint256[]"},{"type":"uint256","name":"soyToClaim","internalType":"uint256"},{"type":"uint256","name":"soyLocked","internalType":"uint256"}],"name":"getUserDetail","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isPaused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastRoundSoyPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lockPercentage","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lockPeriod","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"makeBet","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxExtendRounds","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxPricePercentage","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minPricePercentage","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"priceFeed","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueTokens","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"roundDuration","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAllowedToken","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"bool","name":"state","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAuctionRounds","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBank","inputs":[{"type":"address","name":"_bank","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLastRoundSoyPrice","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLockPercentage","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLockPeriod","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxExtendRounds","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxPricePercentage","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinPricePercentage","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPause","inputs":[{"type":"bool","name":"state","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRoundDuration","inputs":[{"type":"uint256","name":"val","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRoundSellAmount","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"tokenReceived","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"},{"type":"bytes","name":"_data","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSoySold","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSoyToSell","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

Verify & Publish
0x608060405234801561001057600080fd5b5060018055612fff806100246000396000f3fe6080604052600436106102965760003560e01c8063741bef1a1161015a5780639cbe5efd116100c1578063c59cb9f41161007a578063c59cb9f414610853578063debb114314610873578063f2fde38b14610889578063f644b3bb146108a9578063f7cb789a14610907578063fe1cdb231461091d57600080fd5b80639cbe5efd146107495780639f3713b71461075f578063a85f4e8114610775578063ab286934146107f9578063b187bd2614610819578063bedb86fb1461083357600080fd5b8063889014961161011357806388901496146106965780638943ec02146106b65780638aaa2284146106d65780638c7a529f146106f65780638da5cb5b1461070b57806398b9a2dc1461072957600080fd5b8063741bef1a146105b4578063756742f8146105dc57806376cdb03b1461061c578063779972da146106415780637cd42842146106615780638129fc1c1461068157600080fd5b80633b50261f116101fe5780634ef6aa71116101b75780634ef6aa71146104ec5780635113aea91461052c57806351bddee81461054c57806359e741d2146105625780635f26e73e1461057e578063601ce32d1461059e57600080fd5b80633b50261f1461043d5780633fd8b02f1461045057806342966c6814610466578063443e5204146104865780634a48c84b146104a65780634e71d92d146104d757600080fd5b806320f634b51161025057806320f634b5146103625780632155e43e14610397578063226125a8146103b75780632fc10aaf146103d7578063356442b91461040757806336c92c3f1461041d57600080fd5b8062ae3bf8146102ad578063073caa3c146102cd57806307f003c3146102ed578063090d23b91461031657806311a9dd3b146103365780631cd275511461034c57600080fd5b366102a8576102a6600134610933565b005b600080fd5b3480156102b957600080fd5b506102a66102c8366004612c21565b610ac5565b3480156102d957600080fd5b506102a66102e8366004612d33565b610c83565b3480156102f957600080fd5b5061030360115481565b6040519081526020015b60405180910390f35b34801561032257600080fd5b506102a6610331366004612c21565b61105c565b34801561034257600080fd5b50610303600d5481565b34801561035857600080fd5b5061030360065481565b34801561036e57600080fd5b5061038261037d366004612c21565b611148565b6040805192835260208301919091520161030d565b3480156103a357600080fd5b506102a66103b2366004612da2565b6113a0565b3480156103c357600080fd5b506102a66103d2366004612da2565b6113de565b3480156103e357600080fd5b506103036103f2366004612da2565b60009081526003602052604090206001015490565b34801561041357600080fd5b50610303600c5481565b34801561042957600080fd5b506102a6610438366004612da2565b61141c565b6102a661044b366004612c7e565b610933565b34801561045c57600080fd5b50610303600b5481565b34801561047257600080fd5b506102a6610481366004612da2565b61145a565b34801561049257600080fd5b506102a66104a1366004612da2565b6115fd565b3480156104b257600080fd5b506104c66104c1366004612c21565b61163b565b60405161030d959493929190612e56565b3480156104e357600080fd5b506102a6611b91565b3480156104f857600080fd5b50610514739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b6040516001600160a01b03909116815260200161030d565b34801561053857600080fd5b506102a6610547366004612da2565b611ba1565b34801561055857600080fd5b50610303600e5481565b34801561056e57600080fd5b50610303670e1df0928867de0081565b34801561058a57600080fd5b506102a6610599366004612da2565b611cee565b3480156105aa57600080fd5b50610303600f5481565b3480156105c057600080fd5b50610514739bfc3046ea26f8b09d3e85bd22aec96c80d957e381565b3480156105e857600080fd5b5061060c6105f7366004612c21565b60046020526000908152604090205460ff1681565b604051901515815260200161030d565b34801561062857600080fd5b506005546105149061010090046001600160a01b031681565b34801561064d57600080fd5b506102a661065c366004612da2565b611d3b565b34801561066d57600080fd5b506102a661067c366004612da2565b611d79565b34801561068d57600080fd5b506102a6611db7565b3480156106a257600080fd5b506102a66106b1366004612c21565b611e6f565b3480156106c257600080fd5b506102a66106d1366004612caa565b611e80565b3480156106e257600080fd5b506102a66106f1366004612c45565b611f38565b34801561070257600080fd5b50610382611faf565b34801561071757600080fd5b506000546001600160a01b0316610514565b34801561073557600080fd5b506102a6610744366004612c21565b611ffc565b34801561075557600080fd5b5061030360095481565b34801561076b57600080fd5b5061030360075481565b34801561078157600080fd5b506107cc610790366004612da2565b60036020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154905086565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161030d565b34801561080557600080fd5b506102a6610814366004612df9565b612193565b34801561082557600080fd5b5060055461060c9060ff1681565b34801561083f57600080fd5b506102a661084e366004612d68565b612292565b34801561085f57600080fd5b506102a661086e366004612da2565b6122de565b34801561087f57600080fd5b5061030360085481565b34801561089557600080fd5b506102a66108a4366004612c21565b61231c565b3480156108b557600080fd5b506108ec6108c4366004612dd4565b6002602081815260009384526040808520909152918352912080546001820154919092015483565b6040805193845260208401929092529082015260600161030d565b34801561091357600080fd5b50610303600a5481565b34801561092957600080fd5b5061030360105481565b6001600160a01b03821660009081526004602052604090205460ff166109965760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881a5cdb89dd08185b1b1bddd959606a1b60448201526064015b60405180910390fd5b6001600160a01b038216600114156109f3573481146109ee5760405162461bcd60e51b8152602060048201526014602482015273125b98dbdc9c9958dd0810d313c8185b5bdd5b9d60621b604482015260640161098d565b610ab6565b3415610a2e5760405162461bcd60e51b815260206004820152600a60248201526927b7363c903a37b5b2b760b11b604482015260640161098d565b6040516323b872dd60e01b8152336004820152306024820152604481018290526001600160a01b038316906323b872dd90606401602060405180830381600087803b158015610a7c57600080fd5b505af1158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab49190612d85565b505b610ac1338383612415565b5050565b33610ad86000546001600160a01b031690565b6001600160a01b031614610afe5760405162461bcd60e51b815260040161098d90612ea4565b60006001600160a01b038216739fae2529863bd691b4a7171bdfcf33c7ebb10a651415610b4257600754600654610b359190612f32565b6007546006559050610bbc565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b158015610b8157600080fd5b505afa158015610b95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb99190612dbb565b90505b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb90604401602060405180830381600087803b158015610c0457600080fd5b505af1158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3c9190612d85565b50604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af2910160405180910390a15050565b60026001541415610cd65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161098d565b60026001558082108015610cec57506009548111155b610d385760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f756e647320706172616d65746572730000000000604482015260640161098d565b600c54600b5460009190845b84811015610fba5760008181526002602090815260408083206001600160a01b038b1684529091529020548015610ebb5760008281526002602081815260408084206001600160a01b038d1685529091529091200154610ebb57600082815260036020526040812060018101549054610dbe908490612f13565b610dc89190612ef1565b905060006064610dd88784612f13565b610de29190612ef1565b9050610dee8183612f32565b610df89088612ed9565b60008581526002602090815260408083206001600160a01b038f16845282528083206001018590558783526003909152902060050154909750610e3c908690612ed9565b6002600086815260200190815260200160002060008c6001600160a01b03166001600160a01b031681526020019081526020016000206002018190555060006002600086815260200190815260200160002060008c6001600160a01b03166001600160a01b031681526020019081526020016000206000018190555050505b60008281526002602090815260408083206001600160a01b038c1684529091529020600101548015801590610f13575060008381526002602081815260408084206001600160a01b038e168552909152909120015442115b15610fa557600085610f26836064612f13565b610f309190612ef1565b905060006064610f41836019612f13565b610f4b9190612ef1565b9050610f578184612ed9565b610f619089612ed9565b975060006002600087815260200190815260200160002060008d6001600160a01b03166001600160a01b031681526020019081526020016000206001018190555050505b50508080610fb290612f49565b915050610d44565b5060405163a9059cbb60e01b81526001600160a01b038716600482015260248101849052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b15801561101757600080fd5b505af115801561102b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104f9190612d85565b5050600180555050505050565b3361106f6000546001600160a01b031690565b6001600160a01b0316146110955760405162461bcd60e51b815260040161098d90612ea4565b6001600160a01b0381166110eb5760405162461bcd60e51b815260206004820152601860248201527f5a65726f2061646472657373206e6f7420616c6c6f7765640000000000000000604482015260640161098d565b60058054610100600160a81b0319166101006001600160a01b038416908102919091179091556040519081527f10f5824683d64a0712038f2244e046b174a1cc57fbb8556bfda5ffb261244067906020015b60405180910390a150565b600954600c54600b546000928392909160015b838110156113975760008181526002602090815260408083206001600160a01b038b16845290915290205480156112c35760008281526002602081815260408084206001600160a01b038d168552909152822001549081611232576000848152600360205260408120600181015490546111d6908690612f13565b6111e09190612ef1565b905060646111ee8883612f13565b6111f89190612ef1565b91506112048282612f32565b61120e908b612ed9565b600086815260036020526040902060050154909a5061122e908790612ed9565b9250505b4282101561127d5760008481526002602090815260408083206001600160a01b038e16845290915290206001015461126a908a612ed9565b9850611276818a612ed9565b98506112bc565b60008481526002602090815260408083206001600160a01b038e1684529091529020600101546112ad9089612ed9565b97506112b98189612ed9565b97505b5050611384565b60008281526002602090815260408083206001600160a01b038c168452909152902060010154156113845760008281526002602081815260408084206001600160a01b038d16855290915290912001544211156113515760008281526002602090815260408083206001600160a01b038c16845290915290206001015461134a9088612ed9565b9650611384565b60008281526002602090815260408083206001600160a01b038c1684529091529020600101546113819087612ed9565b95505b508061138f81612f49565b91505061115b565b50505050915091565b336113b36000546001600160a01b031690565b6001600160a01b0316146113d95760405162461bcd60e51b815260040161098d90612ea4565b600e55565b336113f16000546001600160a01b031690565b6001600160a01b0316146114175760405162461bcd60e51b815260040161098d90612ea4565b600c55565b3361142f6000546001600160a01b031690565b6001600160a01b0316146114555760405162461bcd60e51b815260040161098d90612ea4565b600a55565b3361146d6000546001600160a01b031690565b6001600160a01b0316146114935760405162461bcd60e51b815260040161098d90612ea4565b600854600954116114e65760405162461bcd60e51b815260206004820152601760248201527f41756374696f6e206973206e6f742066696e6973686564000000000000000000604482015260640161098d565b60006011546007546006546114fb9190612f32565b6115059190612f32565b9050806115455760405162461bcd60e51b815260206004820152600e60248201526d27379029b7bc903a3790313ab93760911b604482015260640161098d565b80821115611551578091505b81601160008282546115639190612ed9565b909155505060405163a9059cbb60e01b815261dead60901b600482015260248101839052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b1580156115c057600080fd5b505af11580156115d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f89190612d85565b505050565b336116106000546001600160a01b031690565b6001600160a01b0316146116365760405162461bcd60e51b815260040161098d90612ea4565b600f55565b6060806060600080600060095490506001816116579190612f32565b67ffffffffffffffff81111561166f5761166f612f90565b604051908082528060200260200182016040528015611698578160200160208202803683370190505b5095506116a6600182612f32565b67ffffffffffffffff8111156116be576116be612f90565b6040519080825280602002602001820160405280156116e7578160200160208202803683370190505b5094506116f5600182612f32565b67ffffffffffffffff81111561170d5761170d612f90565b604051908082528060200260200182016040528015611736578160200160208202803683370190505b50600c54600b549195509060015b83811015611b845760008181526002602090815260408083206001600160a01b038e16845290915290205480156119a35760006002600084815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020600201549050600081600014156118e8576000848152600360205260408120600181015490546117de908690612f13565b6117e89190612ef1565b905060646117f68883612f13565b6118009190612ef1565b915061180c8282612f32565b611816908b612ed9565b600086815260036020526040902060050154909a50611836908790612ed9565b9250828c611845600188612f32565b8151811061185557611855612f7a565b6020908102919091010152818d61186d600188612f32565b8151811061187d5761187d612f7a565b602090810291909101810191909152600086815260039091526040902080546001909101546118b490670de0b6b3a7640000612f13565b6118be9190612ef1565b8b6118ca600188612f32565b815181106118da576118da612f7a565b602002602001018181525050505b42821015611948576002600085815260200190815260200160002060008e6001600160a01b03166001600160a01b0316815260200190815260200160002060010154896119359190612ed9565b9850611941818a612ed9565b985061199c565b6002600085815260200190815260200160002060008e6001600160a01b03166001600160a01b03168152602001908152602001600020600101548861198d9190612ed9565b97506119998189612ed9565b97505b5050611b71565b60008281526002602090815260408083206001600160a01b038f16845290915290206001015415611b71576002600083815260200190815260200160002060008c6001600160a01b03166001600160a01b031681526020019081526020016000206002015489600184611a169190612f32565b81518110611a2657611a26612f7a565b60209081029190910181019190915260008381526002825260408082206001600160a01b038f16835290925220600190810154908b90611a669085612f32565b81518110611a7657611a76612f7a565b60209081029190910181019190915260008381526003909152604090208054600190910154611aad90670de0b6b3a7640000612f13565b611ab79190612ef1565b88611ac3600185612f32565b81518110611ad357611ad3612f7a565b60209081029190910101524289611aeb600185612f32565b81518110611afb57611afb612f7a565b60200260200101511015611b3f5789611b15600184612f32565b81518110611b2557611b25612f7a565b602002602001015187611b389190612ed9565b9650611b71565b89611b4b600184612f32565b81518110611b5b57611b5b612f7a565b602002602001015186611b6e9190612ed9565b95505b5080611b7c81612f49565b915050611744565b5050505091939590929450565b611b9f336001600954610c83565b565b33611bb46000546001600160a01b031690565b6001600160a01b031614611bda5760405162461bcd60e51b815260040161098d90612ea4565b6009546000908152600360205260409020546007548190611bfc908490612ed9565b611c069190612f32565b60078190556006541015611c4b5760405162461bcd60e51b815260206004820152600c60248201526b15dc9bdb99c8185b5bdd5b9d60a21b604482015260640161098d565b6009546000908152600360205260409020829055600e54600f5468056bc75e2d631000009190611c7b9085612f13565b611c859190612f13565b611c8f9190612ef1565b600954600090815260036020526040902060020155600d54600f5468056bc75e2d631000009190611cc09085612f13565b611cca9190612f13565b611cd49190612ef1565b600954600090815260036020819052604090912001555050565b33611d016000546001600160a01b031690565b6001600160a01b031614611d275760405162461bcd60e51b815260040161098d90612ea4565b600954811015611d3657600080fd5b600855565b33611d4e6000546001600160a01b031690565b6001600160a01b031614611d745760405162461bcd60e51b815260040161098d90612ea4565b600b55565b33611d8c6000546001600160a01b031690565b6001600160a01b031614611db25760405162461bcd60e51b815260040161098d90612ea4565b601055565b6000546001600160a01b031615611e065760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015260640161098d565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36301e13380600b55605a600d55600360105562015180600a5560a0600e556032600c5560b4600855565b611e7d816001600954610c83565b50565b33739fae2529863bd691b4a7171bdfcf33c7ebb10a65148015611eb057506000546001600160a01b038581169116145b15611ed2578260066000828254611ec79190612ed9565b90915550611f329050565b3360009081526004602052604090205460ff16611f275760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881a5cdb89dd08185b1b1bddd959606a1b604482015260640161098d565b611f32843385612415565b50505050565b33611f4b6000546001600160a01b031690565b6001600160a01b031614611f715760405162461bcd60e51b815260040161098d90612ea4565b6001600160a01b038216611f8457600080fd5b6001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b600954600081815260036020526040812060019081015492905b818111611ff657600081815260036020526040902060010154925080611fee81612f49565b915050611fc9565b50509091565b60015b60095481101561215457600081815260026020908152604080832033845290915290205415158061204b5750600081815260026020908152604080832033845290915290206001015415155b156121425760008181526002602090815260408083206001600160a01b03861684529091529020541580156120a3575060008181526002602090815260408083206001600160a01b0386168452909152902060010154155b6120ef5760405162461bcd60e51b815260206004820152601860248201527f6e657757616c6c657420616c726561647920696e207573650000000000000000604482015260640161098d565b60008181526002602081815260408084203380865292528084206001600160a01b038716855290842081548155600180830180549183019190915582850180549290950191909155918452839055829055555b8061214c81612f49565b915050611fff565b50604080513381526001600160a01b03831660208201527f4c409b80b002adab58e3f2e6d48b2024dbcdcbbe2c164dcb834316a073bb3b45910161113d565b336121a66000546001600160a01b031690565b6001600160a01b0316146121cc5760405162461bcd60e51b815260040161098d90612ea4565b6009541561220e5760405162461bcd60e51b815260206004820152600f60248201526e4f6e6c79207374617274206f6e636560881b604482015260640161098d565b60065461224e5760405162461bcd60e51b815260206004820152600e60248201526d139bc814d3d6481d1bc81cd95b1b60921b604482015260640161098d565b600f81905560008052600360205269063ec042bd9bc2fbc1037f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff55610ac182612677565b336122a56000546001600160a01b031690565b6001600160a01b0316146122cb5760405162461bcd60e51b815260040161098d90612ea4565b6005805460ff1916911515919091179055565b336122f16000546001600160a01b031690565b6001600160a01b0316146123175760405162461bcd60e51b815260040161098d90612ea4565b600d55565b3361232f6000546001600160a01b031690565b6001600160a01b0316146123555760405162461bcd60e51b815260040161098d90612ea4565b6001600160a01b0381166123ba5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161098d565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60055460ff16156124515760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015260640161098d565b600260015414156124a45760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161098d565b60026001556124b161285b565b156124c6576124c1828285612a0a565b61266e565b60095460006124d484612ad4565b6000838152600360209081526040808320600283528184206001600160a01b038b16855290925282209293509190670de0b6b3a76400006125158588612f13565b61251f9190612ef1565b836001015461252e9190612ed9565b9050826002015481106125b057600083600201548261254d9190612f32565b90508461256282670de0b6b3a7640000612f13565b61256c9190612ef1565b9050868111156125795750855b6002840154600185015561258d8188612f32565b965061259842612b68565b5080156125aa576125aa88828b612a0a565b506125b8565b600183018190555b6000670de0b6b3a76400006125cd8689612f13565b6125d79190612ef1565b9050808360000160008282546125ed9190612ed9565b9091555050600554612610908990899061010090046001600160a01b0316612a0a565b876001600160a01b0316896001600160a01b0316877f6474f1bb997bda2619fcace4051842a3232e75c34ea64c058221f1718e2aa990848b60405161265f929190918252602082015260400190565b60405180910390a45050505050505b50506001805550565b6009805490600061268783612f49565b919050555060085460095411156126d75760405162461bcd60e51b8152602060048201526014602482015273105b1b081c9bdd5b991cc818dbdb5c1b195d195960621b604482015260640161098d565b600954600090815260036020526040902060048101829055600a546126fc9083612ed9565b6005820155600a5460009062015180141561278d57670de0b6b3a7640000670e1df0928867de006003600060016009546127369190612f32565b8152602001908152602001600020600001546127529190612f13565b61275c9190612ef1565b90508060075460065461276f9190612f32565b1015612788576007546006546127859190612f32565b90505b6127cc565b600060095460085460016127a19190612ed9565b6127ab9190612f32565b9050806007546006546127be9190612f32565b6127c89190612ef1565b9150505b808255600780548291906000906127e4908490612ed9565b9091555050600e54600f5468056bc75e2d6310000091906128059084612f13565b61280f9190612f13565b6128199190612ef1565b6002830155600d54600f5468056bc75e2d63100000919061283a9084612f13565b6128449190612f13565b61284e9190612ef1565b8260030181905550505050565b600954600090815260036020526040812060048101544210156128c05760405162461bcd60e51b815260206004820152601a60248201527f41756374696f6e206973206e6f74207374617274656420796574000000000000604482015260640161098d565b600854600954111561290a5760405162461bcd60e51b8152602060048201526013602482015272105d58dd1a5bdb881a5cc8199a5b9a5cda1959606a1b604482015260640161098d565b80546129495760405162461bcd60e51b815260206004820152600e60248201526d139bc814d3d6481d1bc81cd95b1b60921b604482015260640161098d565b42816005015411612a06578060030154816001015410156129f6576000600a548260040154426129799190612f32565b6129839190612ef1565b90506010548110156129c057600a5461299d826001612ed9565b6129a79190612f13565b82600401546129b69190612ed9565b6005830155505090565b600a546010546129d09190612f13565b82600401546129df9190612ed9565b600583018190556129ef90612b68565b9250505090565b612a038160050154612b68565b91505b5090565b6001600160a01b03831660011415612a52576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611f32573d6000803e3d6000fd5b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284169063a9059cbb90604401602060405180830381600087803b158015612a9c57600080fd5b505af1158015612ab0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f329190612d85565b6040516341976e0960e01b81526001600160a01b0382166004820152600090739bfc3046ea26f8b09d3e85bd22aec96c80d957e3906341976e099060240160206040518083038186803b158015612b2a57600080fd5b505afa158015612b3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b629190612dbb565b92915050565b600954600090815260036020526040812080546001820154612b9290670de0b6b3a7640000612f13565b612b9c9190612ef1565b600f55600954815460018301546040517fda434ed10dd96aabd2bd460ecb942c9ff048dc71c68baf0a5e94e8ddbeb603b892612be092908252602082015260400190565b60405180910390a26008546009541415612c125760098054906000612c0483612f49565b919050555060019150612c1b565b612c1b83612677565b50919050565b600060208284031215612c3357600080fd5b8135612c3e81612fa6565b9392505050565b60008060408385031215612c5857600080fd5b8235612c6381612fa6565b91506020830135612c7381612fbb565b809150509250929050565b60008060408385031215612c9157600080fd5b8235612c9c81612fa6565b946020939093013593505050565b60008060008060608587031215612cc057600080fd5b8435612ccb81612fa6565b935060208501359250604085013567ffffffffffffffff80821115612cef57600080fd5b818701915087601f830112612d0357600080fd5b813581811115612d1257600080fd5b886020828501011115612d2457600080fd5b95989497505060200194505050565b600080600060608486031215612d4857600080fd5b8335612d5381612fa6565b95602085013595506040909401359392505050565b600060208284031215612d7a57600080fd5b8135612c3e81612fbb565b600060208284031215612d9757600080fd5b8151612c3e81612fbb565b600060208284031215612db457600080fd5b5035919050565b600060208284031215612dcd57600080fd5b5051919050565b60008060408385031215612de757600080fd5b823591506020830135612c7381612fa6565b60008060408385031215612e0c57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015612e4b57815187529582019590820190600101612e2f565b509495945050505050565b60a081526000612e6960a0830188612e1b565b8281036020840152612e7b8188612e1b565b90508281036040840152612e8f8187612e1b565b60608401959095525050608001529392505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115612eec57612eec612f64565b500190565b600082612f0e57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612f2d57612f2d612f64565b500290565b600082821015612f4457612f44612f64565b500390565b6000600019821415612f5d57612f5d612f64565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611e7d57600080fd5b8015158114611e7d57600080fdfea2646970667358221220f91276892366588821d92edf4a856529d8805f1a578f8d9afe030911bd0b009c64736f6c63430008070033

Deployed ByteCode

0x6080604052600436106102965760003560e01c8063741bef1a1161015a5780639cbe5efd116100c1578063c59cb9f41161007a578063c59cb9f414610853578063debb114314610873578063f2fde38b14610889578063f644b3bb146108a9578063f7cb789a14610907578063fe1cdb231461091d57600080fd5b80639cbe5efd146107495780639f3713b71461075f578063a85f4e8114610775578063ab286934146107f9578063b187bd2614610819578063bedb86fb1461083357600080fd5b8063889014961161011357806388901496146106965780638943ec02146106b65780638aaa2284146106d65780638c7a529f146106f65780638da5cb5b1461070b57806398b9a2dc1461072957600080fd5b8063741bef1a146105b4578063756742f8146105dc57806376cdb03b1461061c578063779972da146106415780637cd42842146106615780638129fc1c1461068157600080fd5b80633b50261f116101fe5780634ef6aa71116101b75780634ef6aa71146104ec5780635113aea91461052c57806351bddee81461054c57806359e741d2146105625780635f26e73e1461057e578063601ce32d1461059e57600080fd5b80633b50261f1461043d5780633fd8b02f1461045057806342966c6814610466578063443e5204146104865780634a48c84b146104a65780634e71d92d146104d757600080fd5b806320f634b51161025057806320f634b5146103625780632155e43e14610397578063226125a8146103b75780632fc10aaf146103d7578063356442b91461040757806336c92c3f1461041d57600080fd5b8062ae3bf8146102ad578063073caa3c146102cd57806307f003c3146102ed578063090d23b91461031657806311a9dd3b146103365780631cd275511461034c57600080fd5b366102a8576102a6600134610933565b005b600080fd5b3480156102b957600080fd5b506102a66102c8366004612c21565b610ac5565b3480156102d957600080fd5b506102a66102e8366004612d33565b610c83565b3480156102f957600080fd5b5061030360115481565b6040519081526020015b60405180910390f35b34801561032257600080fd5b506102a6610331366004612c21565b61105c565b34801561034257600080fd5b50610303600d5481565b34801561035857600080fd5b5061030360065481565b34801561036e57600080fd5b5061038261037d366004612c21565b611148565b6040805192835260208301919091520161030d565b3480156103a357600080fd5b506102a66103b2366004612da2565b6113a0565b3480156103c357600080fd5b506102a66103d2366004612da2565b6113de565b3480156103e357600080fd5b506103036103f2366004612da2565b60009081526003602052604090206001015490565b34801561041357600080fd5b50610303600c5481565b34801561042957600080fd5b506102a6610438366004612da2565b61141c565b6102a661044b366004612c7e565b610933565b34801561045c57600080fd5b50610303600b5481565b34801561047257600080fd5b506102a6610481366004612da2565b61145a565b34801561049257600080fd5b506102a66104a1366004612da2565b6115fd565b3480156104b257600080fd5b506104c66104c1366004612c21565b61163b565b60405161030d959493929190612e56565b3480156104e357600080fd5b506102a6611b91565b3480156104f857600080fd5b50610514739fae2529863bd691b4a7171bdfcf33c7ebb10a6581565b6040516001600160a01b03909116815260200161030d565b34801561053857600080fd5b506102a6610547366004612da2565b611ba1565b34801561055857600080fd5b50610303600e5481565b34801561056e57600080fd5b50610303670e1df0928867de0081565b34801561058a57600080fd5b506102a6610599366004612da2565b611cee565b3480156105aa57600080fd5b50610303600f5481565b3480156105c057600080fd5b50610514739bfc3046ea26f8b09d3e85bd22aec96c80d957e381565b3480156105e857600080fd5b5061060c6105f7366004612c21565b60046020526000908152604090205460ff1681565b604051901515815260200161030d565b34801561062857600080fd5b506005546105149061010090046001600160a01b031681565b34801561064d57600080fd5b506102a661065c366004612da2565b611d3b565b34801561066d57600080fd5b506102a661067c366004612da2565b611d79565b34801561068d57600080fd5b506102a6611db7565b3480156106a257600080fd5b506102a66106b1366004612c21565b611e6f565b3480156106c257600080fd5b506102a66106d1366004612caa565b611e80565b3480156106e257600080fd5b506102a66106f1366004612c45565b611f38565b34801561070257600080fd5b50610382611faf565b34801561071757600080fd5b506000546001600160a01b0316610514565b34801561073557600080fd5b506102a6610744366004612c21565b611ffc565b34801561075557600080fd5b5061030360095481565b34801561076b57600080fd5b5061030360075481565b34801561078157600080fd5b506107cc610790366004612da2565b60036020528060005260406000206000915090508060000154908060010154908060020154908060030154908060040154908060050154905086565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161030d565b34801561080557600080fd5b506102a6610814366004612df9565b612193565b34801561082557600080fd5b5060055461060c9060ff1681565b34801561083f57600080fd5b506102a661084e366004612d68565b612292565b34801561085f57600080fd5b506102a661086e366004612da2565b6122de565b34801561087f57600080fd5b5061030360085481565b34801561089557600080fd5b506102a66108a4366004612c21565b61231c565b3480156108b557600080fd5b506108ec6108c4366004612dd4565b6002602081815260009384526040808520909152918352912080546001820154919092015483565b6040805193845260208401929092529082015260600161030d565b34801561091357600080fd5b50610303600a5481565b34801561092957600080fd5b5061030360105481565b6001600160a01b03821660009081526004602052604090205460ff166109965760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881a5cdb89dd08185b1b1bddd959606a1b60448201526064015b60405180910390fd5b6001600160a01b038216600114156109f3573481146109ee5760405162461bcd60e51b8152602060048201526014602482015273125b98dbdc9c9958dd0810d313c8185b5bdd5b9d60621b604482015260640161098d565b610ab6565b3415610a2e5760405162461bcd60e51b815260206004820152600a60248201526927b7363c903a37b5b2b760b11b604482015260640161098d565b6040516323b872dd60e01b8152336004820152306024820152604481018290526001600160a01b038316906323b872dd90606401602060405180830381600087803b158015610a7c57600080fd5b505af1158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab49190612d85565b505b610ac1338383612415565b5050565b33610ad86000546001600160a01b031690565b6001600160a01b031614610afe5760405162461bcd60e51b815260040161098d90612ea4565b60006001600160a01b038216739fae2529863bd691b4a7171bdfcf33c7ebb10a651415610b4257600754600654610b359190612f32565b6007546006559050610bbc565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b158015610b8157600080fd5b505afa158015610b95573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bb99190612dbb565b90505b60405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb90604401602060405180830381600087803b158015610c0457600080fd5b505af1158015610c18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3c9190612d85565b50604080516001600160a01b0384168152602081018390527f542fa6bfee3b4746210fbdd1d83f9e49b65adde3639f8d8f165dd18347938af2910160405180910390a15050565b60026001541415610cd65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161098d565b60026001558082108015610cec57506009548111155b610d385760405162461bcd60e51b815260206004820152601b60248201527f496e636f727265637420726f756e647320706172616d65746572730000000000604482015260640161098d565b600c54600b5460009190845b84811015610fba5760008181526002602090815260408083206001600160a01b038b1684529091529020548015610ebb5760008281526002602081815260408084206001600160a01b038d1685529091529091200154610ebb57600082815260036020526040812060018101549054610dbe908490612f13565b610dc89190612ef1565b905060006064610dd88784612f13565b610de29190612ef1565b9050610dee8183612f32565b610df89088612ed9565b60008581526002602090815260408083206001600160a01b038f16845282528083206001018590558783526003909152902060050154909750610e3c908690612ed9565b6002600086815260200190815260200160002060008c6001600160a01b03166001600160a01b031681526020019081526020016000206002018190555060006002600086815260200190815260200160002060008c6001600160a01b03166001600160a01b031681526020019081526020016000206000018190555050505b60008281526002602090815260408083206001600160a01b038c1684529091529020600101548015801590610f13575060008381526002602081815260408084206001600160a01b038e168552909152909120015442115b15610fa557600085610f26836064612f13565b610f309190612ef1565b905060006064610f41836019612f13565b610f4b9190612ef1565b9050610f578184612ed9565b610f619089612ed9565b975060006002600087815260200190815260200160002060008d6001600160a01b03166001600160a01b031681526020019081526020016000206001018190555050505b50508080610fb290612f49565b915050610d44565b5060405163a9059cbb60e01b81526001600160a01b038716600482015260248101849052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b15801561101757600080fd5b505af115801561102b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104f9190612d85565b5050600180555050505050565b3361106f6000546001600160a01b031690565b6001600160a01b0316146110955760405162461bcd60e51b815260040161098d90612ea4565b6001600160a01b0381166110eb5760405162461bcd60e51b815260206004820152601860248201527f5a65726f2061646472657373206e6f7420616c6c6f7765640000000000000000604482015260640161098d565b60058054610100600160a81b0319166101006001600160a01b038416908102919091179091556040519081527f10f5824683d64a0712038f2244e046b174a1cc57fbb8556bfda5ffb261244067906020015b60405180910390a150565b600954600c54600b546000928392909160015b838110156113975760008181526002602090815260408083206001600160a01b038b16845290915290205480156112c35760008281526002602081815260408084206001600160a01b038d168552909152822001549081611232576000848152600360205260408120600181015490546111d6908690612f13565b6111e09190612ef1565b905060646111ee8883612f13565b6111f89190612ef1565b91506112048282612f32565b61120e908b612ed9565b600086815260036020526040902060050154909a5061122e908790612ed9565b9250505b4282101561127d5760008481526002602090815260408083206001600160a01b038e16845290915290206001015461126a908a612ed9565b9850611276818a612ed9565b98506112bc565b60008481526002602090815260408083206001600160a01b038e1684529091529020600101546112ad9089612ed9565b97506112b98189612ed9565b97505b5050611384565b60008281526002602090815260408083206001600160a01b038c168452909152902060010154156113845760008281526002602081815260408084206001600160a01b038d16855290915290912001544211156113515760008281526002602090815260408083206001600160a01b038c16845290915290206001015461134a9088612ed9565b9650611384565b60008281526002602090815260408083206001600160a01b038c1684529091529020600101546113819087612ed9565b95505b508061138f81612f49565b91505061115b565b50505050915091565b336113b36000546001600160a01b031690565b6001600160a01b0316146113d95760405162461bcd60e51b815260040161098d90612ea4565b600e55565b336113f16000546001600160a01b031690565b6001600160a01b0316146114175760405162461bcd60e51b815260040161098d90612ea4565b600c55565b3361142f6000546001600160a01b031690565b6001600160a01b0316146114555760405162461bcd60e51b815260040161098d90612ea4565b600a55565b3361146d6000546001600160a01b031690565b6001600160a01b0316146114935760405162461bcd60e51b815260040161098d90612ea4565b600854600954116114e65760405162461bcd60e51b815260206004820152601760248201527f41756374696f6e206973206e6f742066696e6973686564000000000000000000604482015260640161098d565b60006011546007546006546114fb9190612f32565b6115059190612f32565b9050806115455760405162461bcd60e51b815260206004820152600e60248201526d27379029b7bc903a3790313ab93760911b604482015260640161098d565b80821115611551578091505b81601160008282546115639190612ed9565b909155505060405163a9059cbb60e01b815261dead60901b600482015260248101839052739fae2529863bd691b4a7171bdfcf33c7ebb10a659063a9059cbb90604401602060405180830381600087803b1580156115c057600080fd5b505af11580156115d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f89190612d85565b505050565b336116106000546001600160a01b031690565b6001600160a01b0316146116365760405162461bcd60e51b815260040161098d90612ea4565b600f55565b6060806060600080600060095490506001816116579190612f32565b67ffffffffffffffff81111561166f5761166f612f90565b604051908082528060200260200182016040528015611698578160200160208202803683370190505b5095506116a6600182612f32565b67ffffffffffffffff8111156116be576116be612f90565b6040519080825280602002602001820160405280156116e7578160200160208202803683370190505b5094506116f5600182612f32565b67ffffffffffffffff81111561170d5761170d612f90565b604051908082528060200260200182016040528015611736578160200160208202803683370190505b50600c54600b549195509060015b83811015611b845760008181526002602090815260408083206001600160a01b038e16845290915290205480156119a35760006002600084815260200190815260200160002060008d6001600160a01b03166001600160a01b03168152602001908152602001600020600201549050600081600014156118e8576000848152600360205260408120600181015490546117de908690612f13565b6117e89190612ef1565b905060646117f68883612f13565b6118009190612ef1565b915061180c8282612f32565b611816908b612ed9565b600086815260036020526040902060050154909a50611836908790612ed9565b9250828c611845600188612f32565b8151811061185557611855612f7a565b6020908102919091010152818d61186d600188612f32565b8151811061187d5761187d612f7a565b602090810291909101810191909152600086815260039091526040902080546001909101546118b490670de0b6b3a7640000612f13565b6118be9190612ef1565b8b6118ca600188612f32565b815181106118da576118da612f7a565b602002602001018181525050505b42821015611948576002600085815260200190815260200160002060008e6001600160a01b03166001600160a01b0316815260200190815260200160002060010154896119359190612ed9565b9850611941818a612ed9565b985061199c565b6002600085815260200190815260200160002060008e6001600160a01b03166001600160a01b03168152602001908152602001600020600101548861198d9190612ed9565b97506119998189612ed9565b97505b5050611b71565b60008281526002602090815260408083206001600160a01b038f16845290915290206001015415611b71576002600083815260200190815260200160002060008c6001600160a01b03166001600160a01b031681526020019081526020016000206002015489600184611a169190612f32565b81518110611a2657611a26612f7a565b60209081029190910181019190915260008381526002825260408082206001600160a01b038f16835290925220600190810154908b90611a669085612f32565b81518110611a7657611a76612f7a565b60209081029190910181019190915260008381526003909152604090208054600190910154611aad90670de0b6b3a7640000612f13565b611ab79190612ef1565b88611ac3600185612f32565b81518110611ad357611ad3612f7a565b60209081029190910101524289611aeb600185612f32565b81518110611afb57611afb612f7a565b60200260200101511015611b3f5789611b15600184612f32565b81518110611b2557611b25612f7a565b602002602001015187611b389190612ed9565b9650611b71565b89611b4b600184612f32565b81518110611b5b57611b5b612f7a565b602002602001015186611b6e9190612ed9565b95505b5080611b7c81612f49565b915050611744565b5050505091939590929450565b611b9f336001600954610c83565b565b33611bb46000546001600160a01b031690565b6001600160a01b031614611bda5760405162461bcd60e51b815260040161098d90612ea4565b6009546000908152600360205260409020546007548190611bfc908490612ed9565b611c069190612f32565b60078190556006541015611c4b5760405162461bcd60e51b815260206004820152600c60248201526b15dc9bdb99c8185b5bdd5b9d60a21b604482015260640161098d565b6009546000908152600360205260409020829055600e54600f5468056bc75e2d631000009190611c7b9085612f13565b611c859190612f13565b611c8f9190612ef1565b600954600090815260036020526040902060020155600d54600f5468056bc75e2d631000009190611cc09085612f13565b611cca9190612f13565b611cd49190612ef1565b600954600090815260036020819052604090912001555050565b33611d016000546001600160a01b031690565b6001600160a01b031614611d275760405162461bcd60e51b815260040161098d90612ea4565b600954811015611d3657600080fd5b600855565b33611d4e6000546001600160a01b031690565b6001600160a01b031614611d745760405162461bcd60e51b815260040161098d90612ea4565b600b55565b33611d8c6000546001600160a01b031690565b6001600160a01b031614611db25760405162461bcd60e51b815260040161098d90612ea4565b601055565b6000546001600160a01b031615611e065760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015260640161098d565b600080546001600160a01b0319163390811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a36301e13380600b55605a600d55600360105562015180600a5560a0600e556032600c5560b4600855565b611e7d816001600954610c83565b50565b33739fae2529863bd691b4a7171bdfcf33c7ebb10a65148015611eb057506000546001600160a01b038581169116145b15611ed2578260066000828254611ec79190612ed9565b90915550611f329050565b3360009081526004602052604090205460ff16611f275760405162461bcd60e51b8152602060048201526013602482015272151bdad95b881a5cdb89dd08185b1b1bddd959606a1b604482015260640161098d565b611f32843385612415565b50505050565b33611f4b6000546001600160a01b031690565b6001600160a01b031614611f715760405162461bcd60e51b815260040161098d90612ea4565b6001600160a01b038216611f8457600080fd5b6001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b600954600081815260036020526040812060019081015492905b818111611ff657600081815260036020526040902060010154925080611fee81612f49565b915050611fc9565b50509091565b60015b60095481101561215457600081815260026020908152604080832033845290915290205415158061204b5750600081815260026020908152604080832033845290915290206001015415155b156121425760008181526002602090815260408083206001600160a01b03861684529091529020541580156120a3575060008181526002602090815260408083206001600160a01b0386168452909152902060010154155b6120ef5760405162461bcd60e51b815260206004820152601860248201527f6e657757616c6c657420616c726561647920696e207573650000000000000000604482015260640161098d565b60008181526002602081815260408084203380865292528084206001600160a01b038716855290842081548155600180830180549183019190915582850180549290950191909155918452839055829055555b8061214c81612f49565b915050611fff565b50604080513381526001600160a01b03831660208201527f4c409b80b002adab58e3f2e6d48b2024dbcdcbbe2c164dcb834316a073bb3b45910161113d565b336121a66000546001600160a01b031690565b6001600160a01b0316146121cc5760405162461bcd60e51b815260040161098d90612ea4565b6009541561220e5760405162461bcd60e51b815260206004820152600f60248201526e4f6e6c79207374617274206f6e636560881b604482015260640161098d565b60065461224e5760405162461bcd60e51b815260206004820152600e60248201526d139bc814d3d6481d1bc81cd95b1b60921b604482015260640161098d565b600f81905560008052600360205269063ec042bd9bc2fbc1037f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff55610ac182612677565b336122a56000546001600160a01b031690565b6001600160a01b0316146122cb5760405162461bcd60e51b815260040161098d90612ea4565b6005805460ff1916911515919091179055565b336122f16000546001600160a01b031690565b6001600160a01b0316146123175760405162461bcd60e51b815260040161098d90612ea4565b600d55565b3361232f6000546001600160a01b031690565b6001600160a01b0316146123555760405162461bcd60e51b815260040161098d90612ea4565b6001600160a01b0381166123ba5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161098d565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60055460ff16156124515760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b604482015260640161098d565b600260015414156124a45760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161098d565b60026001556124b161285b565b156124c6576124c1828285612a0a565b61266e565b60095460006124d484612ad4565b6000838152600360209081526040808320600283528184206001600160a01b038b16855290925282209293509190670de0b6b3a76400006125158588612f13565b61251f9190612ef1565b836001015461252e9190612ed9565b9050826002015481106125b057600083600201548261254d9190612f32565b90508461256282670de0b6b3a7640000612f13565b61256c9190612ef1565b9050868111156125795750855b6002840154600185015561258d8188612f32565b965061259842612b68565b5080156125aa576125aa88828b612a0a565b506125b8565b600183018190555b6000670de0b6b3a76400006125cd8689612f13565b6125d79190612ef1565b9050808360000160008282546125ed9190612ed9565b9091555050600554612610908990899061010090046001600160a01b0316612a0a565b876001600160a01b0316896001600160a01b0316877f6474f1bb997bda2619fcace4051842a3232e75c34ea64c058221f1718e2aa990848b60405161265f929190918252602082015260400190565b60405180910390a45050505050505b50506001805550565b6009805490600061268783612f49565b919050555060085460095411156126d75760405162461bcd60e51b8152602060048201526014602482015273105b1b081c9bdd5b991cc818dbdb5c1b195d195960621b604482015260640161098d565b600954600090815260036020526040902060048101829055600a546126fc9083612ed9565b6005820155600a5460009062015180141561278d57670de0b6b3a7640000670e1df0928867de006003600060016009546127369190612f32565b8152602001908152602001600020600001546127529190612f13565b61275c9190612ef1565b90508060075460065461276f9190612f32565b1015612788576007546006546127859190612f32565b90505b6127cc565b600060095460085460016127a19190612ed9565b6127ab9190612f32565b9050806007546006546127be9190612f32565b6127c89190612ef1565b9150505b808255600780548291906000906127e4908490612ed9565b9091555050600e54600f5468056bc75e2d6310000091906128059084612f13565b61280f9190612f13565b6128199190612ef1565b6002830155600d54600f5468056bc75e2d63100000919061283a9084612f13565b6128449190612f13565b61284e9190612ef1565b8260030181905550505050565b600954600090815260036020526040812060048101544210156128c05760405162461bcd60e51b815260206004820152601a60248201527f41756374696f6e206973206e6f74207374617274656420796574000000000000604482015260640161098d565b600854600954111561290a5760405162461bcd60e51b8152602060048201526013602482015272105d58dd1a5bdb881a5cc8199a5b9a5cda1959606a1b604482015260640161098d565b80546129495760405162461bcd60e51b815260206004820152600e60248201526d139bc814d3d6481d1bc81cd95b1b60921b604482015260640161098d565b42816005015411612a06578060030154816001015410156129f6576000600a548260040154426129799190612f32565b6129839190612ef1565b90506010548110156129c057600a5461299d826001612ed9565b6129a79190612f13565b82600401546129b69190612ed9565b6005830155505090565b600a546010546129d09190612f13565b82600401546129df9190612ed9565b600583018190556129ef90612b68565b9250505090565b612a038160050154612b68565b91505b5090565b6001600160a01b03831660011415612a52576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015611f32573d6000803e3d6000fd5b60405163a9059cbb60e01b81526001600160a01b0382811660048301526024820184905284169063a9059cbb90604401602060405180830381600087803b158015612a9c57600080fd5b505af1158015612ab0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f329190612d85565b6040516341976e0960e01b81526001600160a01b0382166004820152600090739bfc3046ea26f8b09d3e85bd22aec96c80d957e3906341976e099060240160206040518083038186803b158015612b2a57600080fd5b505afa158015612b3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b629190612dbb565b92915050565b600954600090815260036020526040812080546001820154612b9290670de0b6b3a7640000612f13565b612b9c9190612ef1565b600f55600954815460018301546040517fda434ed10dd96aabd2bd460ecb942c9ff048dc71c68baf0a5e94e8ddbeb603b892612be092908252602082015260400190565b60405180910390a26008546009541415612c125760098054906000612c0483612f49565b919050555060019150612c1b565b612c1b83612677565b50919050565b600060208284031215612c3357600080fd5b8135612c3e81612fa6565b9392505050565b60008060408385031215612c5857600080fd5b8235612c6381612fa6565b91506020830135612c7381612fbb565b809150509250929050565b60008060408385031215612c9157600080fd5b8235612c9c81612fa6565b946020939093013593505050565b60008060008060608587031215612cc057600080fd5b8435612ccb81612fa6565b935060208501359250604085013567ffffffffffffffff80821115612cef57600080fd5b818701915087601f830112612d0357600080fd5b813581811115612d1257600080fd5b886020828501011115612d2457600080fd5b95989497505060200194505050565b600080600060608486031215612d4857600080fd5b8335612d5381612fa6565b95602085013595506040909401359392505050565b600060208284031215612d7a57600080fd5b8135612c3e81612fbb565b600060208284031215612d9757600080fd5b8151612c3e81612fbb565b600060208284031215612db457600080fd5b5035919050565b600060208284031215612dcd57600080fd5b5051919050565b60008060408385031215612de757600080fd5b823591506020830135612c7381612fa6565b60008060408385031215612e0c57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015612e4b57815187529582019590820190600101612e2f565b509495945050505050565b60a081526000612e6960a0830188612e1b565b8281036020840152612e7b8188612e1b565b90508281036040840152612e8f8187612e1b565b60608401959095525050608001529392505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60008219821115612eec57612eec612f64565b500190565b600082612f0e57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612f2d57612f2d612f64565b500290565b600082821015612f4457612f44612f64565b500390565b6000600019821415612f5d57612f5d612f64565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611e7d57600080fd5b8015158114611e7d57600080fdfea2646970667358221220f91276892366588821d92edf4a856529d8805f1a578f8d9afe030911bd0b009c64736f6c63430008070033