false
true
0

Contract Address Details

0xcae03380b98B479221FDc03E1c4fAA94137BDE6b

Contract Name
DarkClaims
Creator
0x8717cd–c747fd at 0xc705a2–620dd1
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
59 Transactions
Transfers
0 Transfers
Gas Used
14,579,578
Last Balance Update
25927325
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
DarkClaims




Optimization enabled
true
Compiler version
v0.8.24+commit.e11b9ed9




Optimization runs
200
EVM Version
paris




Verified at
2026-03-03T02:49:09.126921Z

Constructor Arguments

60e0604052600b805460ff60a01b191690553480156200001e57600080fd5b5060405162001aa638038062001aa68339810160408190526200004191620002e4565b82826012600062000053848262000402565b50600162000062838262000402565b5060ff81166080524660a0526200007862000180565b60c052505083516000039050620000a257604051632ef1310560e01b815260040160405180910390fd5b8151600003620000c557604051630cc613fb60e11b815260040160405180910390fd5b6001600160a01b038116620000ed576040516301d7ffdf60e01b815260040160405180910390fd5b60068054336001600160a01b031991821681179092556001600081815260086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f80548416909217909155600a80549092166001600160a01b038516179091556040517f0f83c400767f8368a825982fc904ac8051109f873c46b41732dee39156e1cf46908290a35050506200054c565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620001b49190620004ce565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200024457600080fd5b81516001600160401b03808211156200026157620002616200021c565b604051601f8301601f19908116603f011681019082821181831017156200028c576200028c6200021c565b8160405283815260209250866020858801011115620002aa57600080fd5b600091505b83821015620002ce5785820183015181830184015290820190620002af565b6000602085830101528094505050505092915050565b600080600060608486031215620002fa57600080fd5b83516001600160401b03808211156200031257600080fd5b620003208783880162000232565b945060208601519150808211156200033757600080fd5b50620003468682870162000232565b604086015190935090506001600160a01b03811681146200036657600080fd5b809150509250925092565b600181811c908216806200038657607f821691505b602082108103620003a757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003fd576000816000526020600020601f850160051c81016020861015620003d85750805b601f850160051c820191505b81811015620003f957828155600101620003e4565b5050505b505050565b81516001600160401b038111156200041e576200041e6200021c565b62000436816200042f845462000371565b84620003ad565b602080601f8311600181146200046e5760008415620004555750858301515b600019600386901b1c1916600185901b178555620003f9565b600085815260208120601f198616915b828110156200049f578886015182559484019460019091019084016200047e565b5085821015620004be5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808354620004de8162000371565b60018281168015620004f957600181146200050f5762000540565b60ff198416875282151583028701945062000540565b8760005260208060002060005b85811015620005375781548a8201529084019082016200051c565b50505082870194505b50929695505050505050565b60805160a05160c05161152a6200057c600039600061098f0152600061095a015260006102c6015261152a6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80635da93d7e116100f9578063a9059cbb11610097578063dd62ed3e11610071578063dd62ed3e14610404578063df9a49ab1461042f578063ef70aebf14610442578063f8e86ece1461044a57600080fd5b8063a9059cbb146103cb578063d4d7b19a146103de578063d505accf146103f157600080fd5b80637ecebe00116100d35780637ecebe001461036d5780637fcb09721461038d57806395d89b41146103a0578063a7cd52cb146103a857600080fd5b80635da93d7e1461032657806368d1a7db1461033957806370a082311461034d57600080fd5b806318a5bbdc11610166578063313ce56711610140578063313ce567146102c157806332cb6b0c146102fa5780633644e5151461030b57806340c10f191461031357600080fd5b806318a5bbdc1461027c5780631aab9a9f146102a557806323b872dd146102ae57600080fd5b8063095ea7b3116101a2578063095ea7b3146102045780630a7ee767146102275780630e64f5c81461025257806318160ddd1461026557600080fd5b8063024ce0cf146101c957806302fefbf8146101de57806306fdde03146101e6575b600080fd5b6101dc6101d73660046111f9565b61045d565b005b6101dc610512565b6101ee6107b4565b6040516101fb9190611216565b60405180910390f35b610217610212366004611265565b610842565b60405190151581526020016101fb565b600b5461023a906001600160a01b031681565b6040516001600160a01b0390911681526020016101fb565b6101dc6102603660046111f9565b6108af565b61026e60025481565b6040519081526020016101fb565b61023a61028a3660046111f9565b6008602052600090815260409020546001600160a01b031681565b61026e60095481565b6102176102bc366004611291565b610926565b6102e87f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016101fb565b61026e69d3c21bcecceda100000081565b61026e610956565b6101dc610321366004611265565b6109b1565b6101dc6103343660046111f9565b6109e9565b600b5461021790600160a01b900460ff1681565b61026e61035b3660046111f9565b60036020526000908152604090205481565b61026e61037b3660046111f9565b60056020526000908152604090205481565b60065461023a906001600160a01b031681565b6101ee610a5f565b6102176103b63660046111f9565b60076020526000908152604090205460ff1681565b6102176103d9366004611265565b610a6c565b6102176103ec3660046111f9565b610a9a565b6101dc6103ff3660046112d2565b610ad3565b61026e610412366004611349565b600460209081526000928352604080842090915290825290205481565b600a5461023a906001600160a01b031681565b6101dc610d17565b6101dc6104583660046111f9565b610d7f565b600a546001600160a01b0316331461048f5760405163128e7f4160e01b81523360048201526024015b60405180910390fd5b6001600160a01b0381166104b657604051637cef072b60e01b815260040160405180910390fd5b600a546040516001600160a01b038084169216907f0f83c400767f8368a825982fc904ac8051109f873c46b41732dee39156e1cf4690600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600b60009054906101000a90046001600160a01b03166001600160a01b0316633d3324d16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610565573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105899190611382565b6105a6576040516368506a9d60e01b815260040160405180910390fd5b600b54600160a01b900460ff16156105d157604051634c4eedb960e11b815260040160405180910390fd5b6001600090815260086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f546001600160a01b03165b6001600160a01b038116600114610681576001600160a01b03811660009081526007602052604090205460ff1615610661576001600160a01b03811660009081526003602052604090205461065e90836113ba565b91505b6001600160a01b0390811660009081526008602052604090205416610609565b50600160005260086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f546001600160a01b03165b6001600160a01b03811660011461076f576001600160a01b038116600090815260036020526040902054801580159061070a57506001600160a01b03821660009081526007602052604090205460ff16155b1561074e576001600160a01b0382166000818152600360209081526040808320839055518481529192916000805160206114d5833981519152910160405180910390a35b506001600160a01b03908116600090815260086020526040902054166106b8565b6002829055600b805460ff60a01b1916600160a01b1790556040517f2b667de6578446bef56ae94121dd7d266011077a4927d2d74a52bd46fc13e84490600090a15050565b600080546107c1906113cd565b80601f01602080910402602001604051908101604052809291908181526020018280546107ed906113cd565b801561083a5780601f1061080f5761010080835404028352916020019161083a565b820191906000526020600020905b81548152906001019060200180831161081d57829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061089d9086815260200190565b60405180910390a35060015b92915050565b600a546001600160a01b031633146108dc5760405163128e7f4160e01b8152336004820152602401610486565b600b80546001600160a01b0319166001600160a01b0383169081179091556040517f103efaa51c73aa147daa8c21e3e90c4e8dc267c279510483783638f02644be3390600090a250565b600b54600090600160a01b900460ff166109435761094383610e64565b61094e848484610f57565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461461098c57610987611037565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6006546001600160a01b031633146109db576040516282b42960e81b815260040160405180910390fd5b6109e582826110d1565b5050565b600a546001600160a01b03163314610a165760405163128e7f4160e01b8152336004820152602401610486565b6001600160a01b038116600081815260076020526040808220805460ff19169055517f458680f79aa9de0ae06344287a3bd8ec6179faa05252e9af81ae734d6b4dc6ba9190a250565b600180546107c1906113cd565b600b54600090600160a01b900460ff16610a8957610a8983610e64565b610a938383611122565b9392505050565b60006001600160a01b03821660011480610acc57506001600160a01b0382811660009081526008602052604090205416155b1592915050565b42841015610b235760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610486565b60006001610b2f610956565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610c3b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610c715750876001600160a01b0316816001600160a01b0316145b610cae5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610486565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6006546001600160a01b03163314610d41576040516282b42960e81b815260040160405180910390fd5b69d3c21bcecceda100000060025414610d6d576040516307a6d1dd60e11b815260040160405180910390fd5b600680546001600160a01b0319169055565b600a546001600160a01b03163314610dac5760405163128e7f4160e01b8152336004820152602401610486565b6001600160a01b03811660009081526007602052604090205460ff1615610df157604051633ef99be560e01b81526001600160a01b0382166004820152602401610486565b6001600160a01b038116610e18576040516317e05c2b60e01b815260040160405180910390fd5b6001600160a01b038116600081815260076020526040808220805460ff19166001179055517f28f54e0b69489ad5fd27625e6fcff58faff5da96f8a077d08bb09af25bb41d549190a250565b6001600160a01b0381161580610e8357506001600160a01b0381166001145b15610e8b5750565b6001600160a01b038181166000908152600860205260409020541615610eae5750565b60086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f80546001600160a01b038381166000818152604081208054939094166001600160a01b031993841617909355600183528354909116179091556009805491610f1b83611407565b90915550506040516001600160a01b038216907f64706ace8701df5bd070a4bebf17d164c79457579cfdbd3a6876bf531723fc3c90600090a250565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610fb357610f8e8382611420565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610fdb908490611420565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716906000805160206114d5833981519152906110249087815260200190565b60405180910390a3506001949350505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516110699190611433565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b600b54600160a01b900460ff166110eb576110eb82610e64565b6110f58282611188565b69d3c21bcecceda100000060025411156109e55760405163041c0c2360e31b815260040160405180910390fd5b33600090815260036020526040812080548391908390611143908490611420565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133906000805160206114d58339815191529061089d9086815260200190565b806002600082825461119a91906113ba565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481526000805160206114d5833981519152910160405180910390a35050565b6001600160a01b03811681146111f657600080fd5b50565b60006020828403121561120b57600080fd5b8135610a93816111e1565b60006020808352835180602085015260005b8181101561124457858101830151858201604001528201611228565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806040838503121561127857600080fd5b8235611283816111e1565b946020939093013593505050565b6000806000606084860312156112a657600080fd5b83356112b1816111e1565b925060208401356112c1816111e1565b929592945050506040919091013590565b600080600080600080600060e0888a0312156112ed57600080fd5b87356112f8816111e1565b96506020880135611308816111e1565b95506040880135945060608801359350608088013560ff8116811461132c57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561135c57600080fd5b8235611367816111e1565b91506020830135611377816111e1565b809150509250929050565b60006020828403121561139457600080fd5b81518015158114610a9357600080fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156108a9576108a96113a4565b600181811c908216806113e157607f821691505b60208210810361140157634e487b7160e01b600052602260045260246000fd5b50919050565b600060018201611419576114196113a4565b5060010190565b818103818111156108a9576108a96113a4565b60008083548160018260011c9150600183168061145157607f831692505b6020808410820361147057634e487b7160e01b86526022600452602486fd5b8180156114845760018114611499576114c6565b60ff19861689528415158502890196506114c6565b60008a81526020902060005b868110156114be5781548b8201529085019083016114a5565b505084890196505b50949897505050505050505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c752b4559374174c4757acaed4c0763df9e08d7b67c27800e9fa621c64c6999c64736f6c63430008180033987fbabc6900d88f423a112781b8eb8200eefadcba62925ce7f0a70c60ee786a0000000000000000000000000000000000000000000bd0a38f2f5f1fcadb402600000000000000000000000081156ae9a7ad6daacd28726d403617007a3de6d80000000000000000000000008717cd5a7250aed3473f92e97d933d2972c747fd0000000000000000000000008717cd5a7250aed3473f92e97d933d2972c747fd

Arg [0] (bytes32) : 60e0604052600b805460ff60a01b191690553480156200001e57600080fd5b50
Arg [1] (uint256) : 43535673359679216180303420940805419485954701655883871479081488864924886106852
Arg [2] (address) : 0x848262000402565b506001620000628382620004
Arg [3] (address) : 0x60a0526200007862000180565b60c05250508351
Arg [4] (address) : 0x51632ef1310560e01b8152600401604051809103

              

src/ERA2/DarkClaims.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {ReentrancyGuard} from "@solmate/src/utils/ReentrancyGuard.sol";
import {Owned} from "@solmate/src/auth/Owned.sol";
import {Dark} from "./Dark.sol";
import {MerkleProofLib} from "@solmate/src/utils/MerkleProofLib.sol";

/// @title DarkClaims Contract
/// @notice Contract for claiming $DARK tokens based on $DRKX mining activity using a merkle tree proof.
/// @dev Utilizes ReentrancyGuard for non-reentrant modifier and inherits from Owned for access control.
contract DarkClaims is ReentrancyGuard, Owned(msg.sender) {
    event Claimed(address user, uint256 amount, uint256 nonce);
    event UpdatedEvilAddress(address newEvilAddress);
    /// @notice Duration for each claim period.

    uint256 public constant claimDuration = 1 weeks;

    /// @notice The merkle root for verifying claims.
    bytes32 public merkleRoot;

    /// @notice The DARK token contract.
    Dark public immutable dark;

    /// @notice Address of the mystery box receiving a portion of claims.
    address public immutable mysteryBox;

    /// @notice Address of the evil address receiving a portion of claims.
    address public evilAddress;

    /// @notice timestamp when claim has begun
    uint256 public claimStartTimestamp;

    /// @notice total points of the whole antigravity
    uint256 public totalPoints;

    /// @notice Indicates whether the claim is currently active or not
    bool public isClaimActive;

    /**
     * @dev Nested mapping to track claims. The first key is an address,
     * and the second key is a uint256 identifier for the claim,
     * which maps to a boolean.
     */
    mapping(address => mapping(uint256 => bool)) public claimsLedger;

    // Custom errors
    error InvalidLengths();
    error ClaimInactive();
    error InvalidProof();
    error AlreadyClaimed();
    error ClaimNotStarted();
    error OngoingClaimPeriod();
    error EmptyMerkleRoot();
    error EmptyMysteryBoxAddress();
    error EmptyEvilAddress();
    error EmptyDarkTokenAddress();
    error ZeroTotalPoints();
    error ExceedsAllowedArraySize();

    /// @dev Constructor that sets initial state.
    /// @param _merkleRoot The merkle root for proof verification.
    /// @param _mystery The address of the mystery box.
    /// @param _evilAddress The address of the evil address.
    /// @param _trustedEntity Address of the trusted entity.
    constructor(
        bytes32 _merkleRoot,
        uint256 _totalPoints,
        address _mystery,
        address _evilAddress,
        address _trustedEntity
    ) {
        if (_merkleRoot == bytes32(0)) revert EmptyMerkleRoot();
        if (_mystery == address(0)) revert EmptyMysteryBoxAddress();
        if (_evilAddress == address(0)) revert EmptyEvilAddress();
        if (_totalPoints == 0) revert ZeroTotalPoints();

        merkleRoot = _merkleRoot;
        totalPoints = _totalPoints;
        dark = new Dark("Dark", "DARK", _trustedEntity);
        mysteryBox = _mystery;
        evilAddress = _evilAddress;
    }

    function updateClaimParams(bytes32 _merkleRoot, uint256 _totalPoints) external onlyOwner {
        if (_merkleRoot == bytes32(0)) revert EmptyMerkleRoot();
        if (_totalPoints == 0) revert ZeroTotalPoints();

        merkleRoot = _merkleRoot;
        totalPoints = _totalPoints;
    }

    function setEvilAddress(address _newEvilAddress) external onlyOwner {
        if (_newEvilAddress == address(0)) revert EmptyEvilAddress();
        evilAddress = _newEvilAddress;
        emit UpdatedEvilAddress(_newEvilAddress);
    }

    /// @notice Claim DARK tokens based on mined DRKX tokens.
    /// @param addresses Array of addresses making the claims.
    /// @param amounts Array of DRKX token amounts for each claim.
    /// @param nonces Array of nonces for each claim.
    /// @param merkleProofs Array of merkle proofs for each claim.
    function claim(
        address[] calldata addresses,
        uint256[] calldata amounts,
        uint32[] calldata nonces,
        bytes32[][] calldata merkleProofs
    ) external nonReentrant {
        uint256 length = addresses.length;
        if (length > 200) {
            revert ExceedsAllowedArraySize();
        }
        if (amounts.length != length || nonces.length != length || merkleProofs.length != length) {
            revert InvalidLengths();
        }

        if (!isClaimActive) revert ClaimInactive();

        for (uint256 i = 0; i < length; i++) {
            // Require that the user can claim with the information provided
            if (!_canClaim(addresses[i], amounts[i], nonces[i], merkleProofs[i])) revert InvalidProof();

            // Update the claims ledger counter for the user that has just minted the tokens
            claimsLedger[addresses[i]][nonces[i]] = true;

            // Calculate the amount to be minted based on $DRKX tokens mined and $DARK's max supply.
            uint256 amountToBeMinted = (dark.MAX_SUPPLY() * amounts[i]) / totalPoints;
            // Calculate the amount to be sent to the mystery address.
            uint256 userAmount = (amountToBeMinted * 10) / 100;
            uint256 mysteryAmount = (amountToBeMinted * 25) / 100;
            uint256 evilAmount = amountToBeMinted - userAmount - mysteryAmount;
            dark.mint(addresses[i], userAmount);
            dark.mint(mysteryBox, mysteryAmount);
            dark.mint(evilAddress, evilAmount);
            emit Claimed(addresses[i], userAmount, nonces[i]);
        }
    }

    /**
     * @dev Internal function to check if a claim is valid and can be processed.
     * @param user The address of the user making the claim.
     * @param amount The amount of $DRKX tokens being claimed.
     * @param nonce The block nonce for the claim.
     * @param merkleProof The merkle proof for the claim.
     * @return True if the claim is valid, false otherwise.
     */
    function _canClaim(address user, uint256 amount, uint32 nonce, bytes32[] calldata merkleProof)
        internal
        view
        returns (bool)
    {
        if (claimsLedger[user][nonce]) revert AlreadyClaimed();
        bytes32 leaf = keccak256(abi.encode(user, amount, nonce));
        return MerkleProofLib.verify(merkleProof, merkleRoot, leaf);
    }

    /// @notice Starts the claim period.
    function startClaim() public virtual onlyOwner {
        if (isClaimActive) revert ClaimNotStarted();
        isClaimActive = true;
        claimStartTimestamp = block.timestamp;
    }

    /// @notice Ends the claim period and stops minting of DARK tokens.
    function endClaim() public virtual onlyOwner {
        if (!isClaimActive || block.timestamp <= claimStartTimestamp + claimDuration) revert OngoingClaimPeriod();
        isClaimActive = false;
        dark.endMinting();
    }
}
        

/

pragma solidity 0.8.24;

interface IJourneyPhaseManager {
    function isRaptureAlertActive() external view returns (bool);
}
          

/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {ERC20} from "@solmate/src/tokens/ERC20.sol";
import {IJourneyPhaseManager} from "@interfaces/IJourneyPhaseManager.sol";

/// @title Dark Token Contract
/// @notice Implementation of the ERC20 Dark token with a capped supply and controlled minting
/// @dev Extends the ERC20 standard
contract Dark is ERC20 {
    /// @notice Maximum token supply set to 1 million tokens
    uint256 public constant MAX_SUPPLY = 1_000_000 ether;

    /// @notice Address authorized to mint new tokens, initially set to the deploying address
    address public claimsContract;

    mapping(address => bool) public allowlist;
    mapping(address => address) public holders;
    address internal constant SENTINEL_HOLDERS = address(0x1);
    uint256 public holderCount;
    address public trustedEntity;
    IJourneyPhaseManager public journeyPhaseManager;
    bool public raptureOccurred = false;

    event AllowlistAdded(address indexed account);
    event AllowlistRemoved(address indexed account);
    event TrustedEntityUpdated(address indexed previousEntity, address indexed newEntity);
    event RaptureOccurred();
    event AddedHolder(address indexed holder);
    event JourneyPhaseManagerSet(IJourneyPhaseManager indexed journeyPhaseManager);

    /// @dev Custom errors
    error OvershotSupplyLimit();
    error Unauthorized();
    error NotYetReachedSupplyLimit();
    error AlreadyAllowlisted(address account);
    error NotTrustedEntity(address caller);
    error TrustedEntityCannotBeEmpty();
    error AllowlistedAddressCannotBeZero();
    error AlreadyRaptured();
    error CannotRaptureBeforeAlert();
    error EmptyTrustedEntity();
    error EmptyName();
    error EmptySymbol();

    modifier onlyTrustedEntity() {
        if (msg.sender != trustedEntity) {
            revert NotTrustedEntity(msg.sender);
        }
        _;
    }

    /// @notice Initializes the contract, setting the initial claims contract and token details
    /// @param _name The name of the token
    /// @param _symbol The symbol of the token
    /// @param _trustedEntity The address of the trusted entity
    constructor(string memory _name, string memory _symbol, address _trustedEntity) ERC20(_name, _symbol, 18) {
        if (bytes(_name).length == 0) revert EmptyName();
        if (bytes(_symbol).length == 0) revert EmptySymbol();
        if (_trustedEntity == address(0)) {
            revert EmptyTrustedEntity();
        }

        // (Dark, DARK, 18)
        claimsContract = msg.sender; // DarkClaims contract
        holders[SENTINEL_HOLDERS] = SENTINEL_HOLDERS;
        trustedEntity = _trustedEntity;
        emit TrustedEntityUpdated(address(0), msg.sender);
    }

    /// @dev Internal function to safely mint new tokens, ensuring the max supply isn't exceeded
    /// @param to The address that will receive the minted tokens
    /// @param amount The number of tokens to mint
    function _safeMint(address to, uint256 amount) internal {
        if (!raptureOccurred) _addHolder(to);
        _mint(to, amount);
        if (totalSupply > MAX_SUPPLY) revert OvershotSupplyLimit();
    }

    /// @notice Mints new tokens to a specified address, callable only by the claimsContract
    /// @dev Calls the internal _safeMint function for minting
    /// @param to The address to mint the tokens to
    /// @param amount The amount of tokens to mint
    function mint(address to, uint256 amount) public {
        if (msg.sender != claimsContract) revert Unauthorized();
        _safeMint(to, amount);
    }

    /// @notice Sets the JourneyPhaseManager contract address
    /// @dev Callable only by the trusted entity
    /// @param _journeyPhaseManager The address of the JourneyPhaseManager contract
    function setJourneyPhaseManager(IJourneyPhaseManager _journeyPhaseManager) public onlyTrustedEntity {
        journeyPhaseManager = _journeyPhaseManager;
        emit JourneyPhaseManagerSet(_journeyPhaseManager);
    }

    /// @notice Ends the minting process by setting the claimsContract to the zero address
    /// @dev Callable only by the claimsContract
    function endMinting() public {
        if (msg.sender != claimsContract) revert Unauthorized();
        if (totalSupply != MAX_SUPPLY) revert NotYetReachedSupplyLimit();
        claimsContract = address(0);
    }

    /// @notice Updates the trusted entity address
    /// @param newTrustedEntity The new address to set as the trusted entity
    function updateTrustedEntity(address newTrustedEntity) external onlyTrustedEntity {
        if (newTrustedEntity == address(0)) revert TrustedEntityCannotBeEmpty();
        emit TrustedEntityUpdated(trustedEntity, newTrustedEntity);
        trustedEntity = newTrustedEntity;
    }

    /// @notice Adds an address to the allowlist
    /// @param account The address to add
    function addToAllowlist(address account) external onlyTrustedEntity {
        if (allowlist[account]) {
            revert AlreadyAllowlisted(account);
        }
        if (account == address(0)) revert AllowlistedAddressCannotBeZero();
        allowlist[account] = true;
        emit AllowlistAdded(account);
    }

    /// @notice Removes an address from the allowlist
    /// @param account The address to remove
    function removeFromAllowlist(address account) external onlyTrustedEntity {
        allowlist[account] = false;
        emit AllowlistRemoved(account);
    }

    /// @notice Triggers the rapture
    function triggerRapture() external {
        // rapture after JourneyPhaseManager activates it
        if (!journeyPhaseManager.isRaptureAlertActive()) {
            revert CannotRaptureBeforeAlert();
        }
        if (raptureOccurred) revert AlreadyRaptured();

        uint256 newTotalSupply = 0;
        address currentHolder = holders[SENTINEL_HOLDERS];
        while (currentHolder != SENTINEL_HOLDERS) {
            if (allowlist[currentHolder]) {
                newTotalSupply += balanceOf[currentHolder]; // Sum whitelisted holders' balances
            }
            currentHolder = holders[currentHolder];
        }

        currentHolder = holders[SENTINEL_HOLDERS];
        while (currentHolder != SENTINEL_HOLDERS) {
            uint256 balance = balanceOf[currentHolder];
            // only burn tokens from non whitelisted holders
            if (balance > 0 && !allowlist[currentHolder]) {
                balanceOf[currentHolder] = 0;
                // not updating the total supply because the whole total supply will be updated in the end
                emit Transfer(currentHolder, address(0), balance);
            }
            currentHolder = holders[currentHolder];
        }

        totalSupply = newTotalSupply;
        raptureOccurred = true;
        emit RaptureOccurred();
    }

    /// @dev Overrides the transfer function
    /// @param to The address to transfer to
    /// @param amount The amount to transfer
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        if (!raptureOccurred) _addHolder(to);
        return super.transfer(to, amount);
    }

    /// @dev Overrides the transferFrom function
    /// @param from The address to transfer from
    /// @param to The address to transfer to
    /// @param amount The amount to transfer
    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
        if (!raptureOccurred) _addHolder(to);
        return super.transferFrom(from, to, amount);
    }

    /// @dev Adds a new holder to the holders
    /// @param holder The address of the new holder
    function _addHolder(address holder) internal {
        // holder address cannot be null, the sentinel.
        if (holder == address(0) || holder == SENTINEL_HOLDERS) return;
        // No duplicate owners allowed.
        if (holders[holder] != address(0)) return;
        holders[holder] = holders[SENTINEL_HOLDERS];
        holders[SENTINEL_HOLDERS] = holder;
        holderCount++;
        emit AddedHolder(holder);
    }

    /// @notice Checks if an address is a holder
    /// @param holder The address to check
    function isHolder(address holder) public view returns (bool) {
        return !(holder == SENTINEL_HOLDERS || holders[holder] == address(0));
    }
}
          

/ReentrancyGuard.sol

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}
          

/MerkleProofLib.sol

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Gas optimized merkle proof verification library.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
library MerkleProofLib {
    function verify(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool isValid) {
        /// @solidity memory-safe-assembly
        assembly {
            if proof.length {
                // Left shifting by 5 is like multiplying by 32.
                let end := add(proof.offset, shl(5, proof.length))

                // Initialize offset to the offset of the proof in calldata.
                let offset := proof.offset

                // Iterate over proof elements to compute root hash.
                // prettier-ignore
                for {} 1 {} {
                    // Slot where the leaf should be put in scratch space. If
                    // leaf > calldataload(offset): slot 32, otherwise: slot 0.
                    let leafSlot := shl(5, gt(leaf, calldataload(offset)))

                    // Store elements to hash contiguously in scratch space.
                    // The xor puts calldataload(offset) in whichever slot leaf
                    // is not occupying, so 0 if leafSlot is 32, and 32 otherwise.
                    mstore(leafSlot, leaf)
                    mstore(xor(leafSlot, 32), calldataload(offset))

                    // Reuse leaf to store the hash to reduce stack operations.
                    leaf := keccak256(0, 64) // Hash both slots of scratch space.

                    offset := add(offset, 32) // Shift 1 word per cycle.

                    // prettier-ignore
                    if iszero(lt(offset, end)) { break }
                }
            }

            isValid := eq(leaf, root) // The proof is valid if the roots match.
        }
    }
}
          

/ERC20.sol

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}
          

/Owned.sol

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

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

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}
          

Compiler Settings

{"remappings":[":@chainlink/=lib/chainlink/",":@era1/=src/ERA1/",":@era2/=src/ERA2/",":@era3/=src/ERA3/",":@erc721a-upgradeable/contracts/=lib/ERC721A-Upgradeable/contracts/",":@erc721a/contracts/=lib/ERC721A/contracts/",":@interfaces/=src/interfaces/",":@mocks/=src/mocks/",":@murky/=lib/murky/",":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",":@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",":@safe/smart-wallet/=lib/safe-smart-account/",":@solady/=lib/solady/",":@solmate/=lib/solmate/",":@uniswap/v2-periphery/=lib/v2-periphery/",":ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",":ERC721A/=lib/ERC721A/contracts/",":chainlink/=lib/chainlink/",":ds-test/=lib/forge-std/lib/ds-test/src/",":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",":erc721a/=lib/erc721a/contracts/",":forge-std/=lib/forge-std/src/",":murky/=lib/murky/",":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",":openzeppelin-contracts/=lib/openzeppelin-contracts/",":openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/",":safe-smart-account/=lib/safe-smart-account/",":solady/=lib/solady/",":solmate/=lib/solmate/src/",":v2-periphery/=lib/v2-periphery/contracts/"],"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"paris","compilationTarget":{"src/ERA2/DarkClaims.sol":"DarkClaims"}}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"bytes32","name":"_merkleRoot","internalType":"bytes32"},{"type":"uint256","name":"_totalPoints","internalType":"uint256"},{"type":"address","name":"_mystery","internalType":"address"},{"type":"address","name":"_evilAddress","internalType":"address"},{"type":"address","name":"_trustedEntity","internalType":"address"}]},{"type":"error","name":"AlreadyClaimed","inputs":[]},{"type":"error","name":"ClaimInactive","inputs":[]},{"type":"error","name":"ClaimNotStarted","inputs":[]},{"type":"error","name":"EmptyDarkTokenAddress","inputs":[]},{"type":"error","name":"EmptyEvilAddress","inputs":[]},{"type":"error","name":"EmptyMerkleRoot","inputs":[]},{"type":"error","name":"EmptyMysteryBoxAddress","inputs":[]},{"type":"error","name":"ExceedsAllowedArraySize","inputs":[]},{"type":"error","name":"InvalidLengths","inputs":[]},{"type":"error","name":"InvalidProof","inputs":[]},{"type":"error","name":"OngoingClaimPeriod","inputs":[]},{"type":"error","name":"ZeroTotalPoints","inputs":[]},{"type":"event","name":"Claimed","inputs":[{"type":"address","name":"user","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"nonce","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"UpdatedEvilAddress","inputs":[{"type":"address","name":"newEvilAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claim","inputs":[{"type":"address[]","name":"addresses","internalType":"address[]"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"},{"type":"uint32[]","name":"nonces","internalType":"uint32[]"},{"type":"bytes32[][]","name":"merkleProofs","internalType":"bytes32[][]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimDuration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"claimStartTimestamp","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"claimsLedger","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract Dark"}],"name":"dark","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"endClaim","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"evilAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isClaimActive","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"merkleRoot","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"mysteryBox","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setEvilAddress","inputs":[{"type":"address","name":"_newEvilAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"startClaim","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalPoints","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateClaimParams","inputs":[{"type":"bytes32","name":"_merkleRoot","internalType":"bytes32"},{"type":"uint256","name":"_totalPoints","internalType":"uint256"}]}]
              

Contract Creation Code

0x60c060405260016000553480156200001657600080fd5b5060405162002c4938038062002c498339810160408190526200003991620001e9565b600180546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350846200009b576040516385ac2b9960e01b815260040160405180910390fd5b6001600160a01b038316620000c3576040516343d64a9960e11b815260040160405180910390fd5b6001600160a01b038216620000eb576040516357cb072360e11b815260040160405180910390fd5b836000036200010d576040516329a5ddcd60e11b815260040160405180910390fd5b6002859055600584905560405181906200012790620001be565b60608082526004908201819052634461726b60e01b608083015260a060208301819052820152634441524b60e01b60c08201526001600160a01b03909116604082015260e001604051809103906000f0801580156200018a573d6000803e3d6000fd5b506001600160a01b0390811660805292831660a05250600380546001600160a01b0319169190921617905550620002479050565b611aa680620011a383390190565b80516001600160a01b0381168114620001e457600080fd5b919050565b600080600080600060a086880312156200020257600080fd5b85519450602086015193506200021b60408701620001cc565b92506200022b60608701620001cc565b91506200023b60808701620001cc565b90509295509295909350565b60805160a051610f0c620002976000396000818161021901526106dd0152600081816101cd0152818161052d015281816106140152818161070c01528181610791015261093e0152610f0c6000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80639abdcb2211610097578063d6275f3d11610066578063d6275f3d1461023b578063dfc5d02f1461024e578063ecbfc07714610257578063f2fde38b1461025f57600080fd5b80639abdcb22146101ef578063ab1a4d9414610202578063b2c62d461461020c578063c38b761c1461021457600080fd5b8063567142be116100d3578063567142be1461019f5780637fc27803146101a85780638da5cb5b146101b55780638f0e0e51146101c857600080fd5b806305effe31146101055780632480d3d2146101485780632eb4a7ab1461015d5780633f27126514610174575b600080fd5b610133610113366004610c18565b600760209081526000928352604080842090915290825290205460ff1681565b60405190151581526020015b60405180910390f35b61015b610156366004610c42565b610272565b005b61016660025481565b60405190815260200161013f565b600354610187906001600160a01b031681565b6040516001600160a01b03909116815260200161013f565b61016660055481565b6006546101339060ff1681565b600154610187906001600160a01b031681565b6101877f000000000000000000000000000000000000000000000000000000000000000081565b61015b6101fd366004610cb0565b6102ef565b61016662093a8081565b61015b6108b0565b6101877f000000000000000000000000000000000000000000000000000000000000000081565b61015b610249366004610d74565b61099f565b61016660045481565b61015b610a44565b61015b61026d366004610d74565b610aa5565b6001546001600160a01b031633146102a55760405162461bcd60e51b815260040161029c90610d96565b60405180910390fd5b816102c3576040516385ac2b9960e01b815260040160405180910390fd5b806000036102e4576040516329a5ddcd60e11b815260040160405180910390fd5b600291909155600555565b60005460011461032e5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161029c565b60026000558660c881111561035657604051631258900d60e21b815260040160405180910390fd5b85811415806103655750838114155b806103705750818114155b1561038e57604051631df89e8b60e01b815260040160405180910390fd5b60065460ff166103b15760405163c84651bb60e01b815260040160405180910390fd5b60005b8181101561089f5761044f8a8a838181106103d1576103d1610dbc565b90506020020160208101906103e69190610d74565b8989848181106103f8576103f8610dbc565b9050602002013588888581811061041157610411610dbc565b90506020020160208101906104269190610dd2565b87878681811061043857610438610dbc565b905060200281019061044a9190610df8565b610b1b565b61046c576040516309bde33960e01b815260040160405180910390fd5b6001600760008c8c8581811061048457610484610dbc565b90506020020160208101906104999190610d74565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008888858181106104cd576104cd610dbc565b90506020020160208101906104e29190610dd2565b63ffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600060055489898481811061052457610524610dbc565b905060200201357f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332cb6b0c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ad9190610e42565b6105b79190610e71565b6105c19190610e8e565b9050600060646105d283600a610e71565b6105dc9190610e8e565b9050600060646105ed846019610e71565b6105f79190610e8e565b90506000816106068486610eb0565b6106109190610eb0565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166340c10f198f8f8881811061065357610653610dbc565b90506020020160208101906106689190610d74565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101869052604401600060405180830381600087803b1580156106b057600080fd5b505af11580156106c4573d6000803e3d6000fd5b50506040516340c10f1960e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018690527f00000000000000000000000000000000000000000000000000000000000000001692506340c10f199150604401600060405180830381600087803b15801561075257600080fd5b505af1158015610766573d6000803e3d6000fd5b50506003546040516340c10f1960e01b81526001600160a01b039182166004820152602481018590527f000000000000000000000000000000000000000000000000000000000000000090911692506340c10f199150604401600060405180830381600087803b1580156107d957600080fd5b505af11580156107ed573d6000803e3d6000fd5b505050507f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a8e8e8781811061082457610824610dbc565b90506020020160208101906108399190610d74565b848c8c8981811061084c5761084c610dbc565b90506020020160208101906108619190610dd2565b604080516001600160a01b039094168452602084019290925263ffffffff169082015260600160405180910390a15050600190920191506103b49050565b505060016000555050505050505050565b6001546001600160a01b031633146108da5760405162461bcd60e51b815260040161029c90610d96565b60065460ff1615806108fc575062093a806004546108f89190610ec3565b4211155b1561091a57604051631700817360e11b815260040160405180910390fd5b6006805460ff191690556040805163ef70aebf60e01b815290516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163ef70aebf91600480830192600092919082900301818387803b15801561098557600080fd5b505af1158015610999573d6000803e3d6000fd5b50505050565b6001546001600160a01b031633146109c95760405162461bcd60e51b815260040161029c90610d96565b6001600160a01b0381166109f0576040516357cb072360e11b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd77d63cd7b27dcbfb56f757ec6cb5b7480be2f408127dcc5844f7c4461cac6d9060200160405180910390a150565b6001546001600160a01b03163314610a6e5760405162461bcd60e51b815260040161029c90610d96565b60065460ff1615610a9257604051635874e70f60e11b815260040160405180910390fd5b6006805460ff1916600117905542600455565b6001546001600160a01b03163314610acf5760405162461bcd60e51b815260040161029c90610d96565b600180546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6001600160a01b038516600090815260076020908152604080832063ffffffff8716845290915281205460ff1615610b6657604051630c8d9eab60e31b815260040160405180910390fd5b604080516001600160a01b038816602082015290810186905263ffffffff85166060820152600090608001604051602081830303815290604052805190602001209050610bb7848460025484610bc2565b979650505050505050565b60008315610bf4578360051b8501855b803580851160051b94855260209485185260406000209301818110610bd25750505b501492915050565b80356001600160a01b0381168114610c1357600080fd5b919050565b60008060408385031215610c2b57600080fd5b610c3483610bfc565b946020939093013593505050565b60008060408385031215610c5557600080fd5b50508035926020909101359150565b60008083601f840112610c7657600080fd5b50813567ffffffffffffffff811115610c8e57600080fd5b6020830191508360208260051b8501011115610ca957600080fd5b9250929050565b6000806000806000806000806080898b031215610ccc57600080fd5b883567ffffffffffffffff80821115610ce457600080fd5b610cf08c838d01610c64565b909a50985060208b0135915080821115610d0957600080fd5b610d158c838d01610c64565b909850965060408b0135915080821115610d2e57600080fd5b610d3a8c838d01610c64565b909650945060608b0135915080821115610d5357600080fd5b50610d608b828c01610c64565b999c989b5096995094979396929594505050565b600060208284031215610d8657600080fd5b610d8f82610bfc565b9392505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610de457600080fd5b813563ffffffff81168114610d8f57600080fd5b6000808335601e19843603018112610e0f57600080fd5b83018035915067ffffffffffffffff821115610e2a57600080fd5b6020019150600581901b3603821315610ca957600080fd5b600060208284031215610e5457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e8857610e88610e5b565b92915050565b600082610eab57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610e8857610e88610e5b565b80820180821115610e8857610e88610e5b56fea26469706673582212201b45aeeadd7d43f2bcae06de43e65f5acc313c2d4ba804fc6cca2a3e8ea7590964736f6c6343000818003360e0604052600b805460ff60a01b191690553480156200001e57600080fd5b5060405162001aa638038062001aa68339810160408190526200004191620002e4565b82826012600062000053848262000402565b50600162000062838262000402565b5060ff81166080524660a0526200007862000180565b60c052505083516000039050620000a257604051632ef1310560e01b815260040160405180910390fd5b8151600003620000c557604051630cc613fb60e11b815260040160405180910390fd5b6001600160a01b038116620000ed576040516301d7ffdf60e01b815260040160405180910390fd5b60068054336001600160a01b031991821681179092556001600081815260086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f80548416909217909155600a80549092166001600160a01b038516179091556040517f0f83c400767f8368a825982fc904ac8051109f873c46b41732dee39156e1cf46908290a35050506200054c565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620001b49190620004ce565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200024457600080fd5b81516001600160401b03808211156200026157620002616200021c565b604051601f8301601f19908116603f011681019082821181831017156200028c576200028c6200021c565b8160405283815260209250866020858801011115620002aa57600080fd5b600091505b83821015620002ce5785820183015181830184015290820190620002af565b6000602085830101528094505050505092915050565b600080600060608486031215620002fa57600080fd5b83516001600160401b03808211156200031257600080fd5b620003208783880162000232565b945060208601519150808211156200033757600080fd5b50620003468682870162000232565b604086015190935090506001600160a01b03811681146200036657600080fd5b809150509250925092565b600181811c908216806200038657607f821691505b602082108103620003a757634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620003fd576000816000526020600020601f850160051c81016020861015620003d85750805b601f850160051c820191505b81811015620003f957828155600101620003e4565b5050505b505050565b81516001600160401b038111156200041e576200041e6200021c565b62000436816200042f845462000371565b84620003ad565b602080601f8311600181146200046e5760008415620004555750858301515b600019600386901b1c1916600185901b178555620003f9565b600085815260208120601f198616915b828110156200049f578886015182559484019460019091019084016200047e565b5085821015620004be5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808354620004de8162000371565b60018281168015620004f957600181146200050f5762000540565b60ff198416875282151583028701945062000540565b8760005260208060002060005b85811015620005375781548a8201529084019082016200051c565b50505082870194505b50929695505050505050565b60805160a05160c05161152a6200057c600039600061098f0152600061095a015260006102c6015261152a6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80635da93d7e116100f9578063a9059cbb11610097578063dd62ed3e11610071578063dd62ed3e14610404578063df9a49ab1461042f578063ef70aebf14610442578063f8e86ece1461044a57600080fd5b8063a9059cbb146103cb578063d4d7b19a146103de578063d505accf146103f157600080fd5b80637ecebe00116100d35780637ecebe001461036d5780637fcb09721461038d57806395d89b41146103a0578063a7cd52cb146103a857600080fd5b80635da93d7e1461032657806368d1a7db1461033957806370a082311461034d57600080fd5b806318a5bbdc11610166578063313ce56711610140578063313ce567146102c157806332cb6b0c146102fa5780633644e5151461030b57806340c10f191461031357600080fd5b806318a5bbdc1461027c5780631aab9a9f146102a557806323b872dd146102ae57600080fd5b8063095ea7b3116101a2578063095ea7b3146102045780630a7ee767146102275780630e64f5c81461025257806318160ddd1461026557600080fd5b8063024ce0cf146101c957806302fefbf8146101de57806306fdde03146101e6575b600080fd5b6101dc6101d73660046111f9565b61045d565b005b6101dc610512565b6101ee6107b4565b6040516101fb9190611216565b60405180910390f35b610217610212366004611265565b610842565b60405190151581526020016101fb565b600b5461023a906001600160a01b031681565b6040516001600160a01b0390911681526020016101fb565b6101dc6102603660046111f9565b6108af565b61026e60025481565b6040519081526020016101fb565b61023a61028a3660046111f9565b6008602052600090815260409020546001600160a01b031681565b61026e60095481565b6102176102bc366004611291565b610926565b6102e87f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016101fb565b61026e69d3c21bcecceda100000081565b61026e610956565b6101dc610321366004611265565b6109b1565b6101dc6103343660046111f9565b6109e9565b600b5461021790600160a01b900460ff1681565b61026e61035b3660046111f9565b60036020526000908152604090205481565b61026e61037b3660046111f9565b60056020526000908152604090205481565b60065461023a906001600160a01b031681565b6101ee610a5f565b6102176103b63660046111f9565b60076020526000908152604090205460ff1681565b6102176103d9366004611265565b610a6c565b6102176103ec3660046111f9565b610a9a565b6101dc6103ff3660046112d2565b610ad3565b61026e610412366004611349565b600460209081526000928352604080842090915290825290205481565b600a5461023a906001600160a01b031681565b6101dc610d17565b6101dc6104583660046111f9565b610d7f565b600a546001600160a01b0316331461048f5760405163128e7f4160e01b81523360048201526024015b60405180910390fd5b6001600160a01b0381166104b657604051637cef072b60e01b815260040160405180910390fd5b600a546040516001600160a01b038084169216907f0f83c400767f8368a825982fc904ac8051109f873c46b41732dee39156e1cf4690600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600b60009054906101000a90046001600160a01b03166001600160a01b0316633d3324d16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610565573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105899190611382565b6105a6576040516368506a9d60e01b815260040160405180910390fd5b600b54600160a01b900460ff16156105d157604051634c4eedb960e11b815260040160405180910390fd5b6001600090815260086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f546001600160a01b03165b6001600160a01b038116600114610681576001600160a01b03811660009081526007602052604090205460ff1615610661576001600160a01b03811660009081526003602052604090205461065e90836113ba565b91505b6001600160a01b0390811660009081526008602052604090205416610609565b50600160005260086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f546001600160a01b03165b6001600160a01b03811660011461076f576001600160a01b038116600090815260036020526040902054801580159061070a57506001600160a01b03821660009081526007602052604090205460ff16155b1561074e576001600160a01b0382166000818152600360209081526040808320839055518481529192916000805160206114d5833981519152910160405180910390a35b506001600160a01b03908116600090815260086020526040902054166106b8565b6002829055600b805460ff60a01b1916600160a01b1790556040517f2b667de6578446bef56ae94121dd7d266011077a4927d2d74a52bd46fc13e84490600090a15050565b600080546107c1906113cd565b80601f01602080910402602001604051908101604052809291908181526020018280546107ed906113cd565b801561083a5780601f1061080f5761010080835404028352916020019161083a565b820191906000526020600020905b81548152906001019060200180831161081d57829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061089d9086815260200190565b60405180910390a35060015b92915050565b600a546001600160a01b031633146108dc5760405163128e7f4160e01b8152336004820152602401610486565b600b80546001600160a01b0319166001600160a01b0383169081179091556040517f103efaa51c73aa147daa8c21e3e90c4e8dc267c279510483783638f02644be3390600090a250565b600b54600090600160a01b900460ff166109435761094383610e64565b61094e848484610f57565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461461098c57610987611037565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b6006546001600160a01b031633146109db576040516282b42960e81b815260040160405180910390fd5b6109e582826110d1565b5050565b600a546001600160a01b03163314610a165760405163128e7f4160e01b8152336004820152602401610486565b6001600160a01b038116600081815260076020526040808220805460ff19169055517f458680f79aa9de0ae06344287a3bd8ec6179faa05252e9af81ae734d6b4dc6ba9190a250565b600180546107c1906113cd565b600b54600090600160a01b900460ff16610a8957610a8983610e64565b610a938383611122565b9392505050565b60006001600160a01b03821660011480610acc57506001600160a01b0382811660009081526008602052604090205416155b1592915050565b42841015610b235760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610486565b60006001610b2f610956565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015610c3b573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610c715750876001600160a01b0316816001600160a01b0316145b610cae5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610486565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6006546001600160a01b03163314610d41576040516282b42960e81b815260040160405180910390fd5b69d3c21bcecceda100000060025414610d6d576040516307a6d1dd60e11b815260040160405180910390fd5b600680546001600160a01b0319169055565b600a546001600160a01b03163314610dac5760405163128e7f4160e01b8152336004820152602401610486565b6001600160a01b03811660009081526007602052604090205460ff1615610df157604051633ef99be560e01b81526001600160a01b0382166004820152602401610486565b6001600160a01b038116610e18576040516317e05c2b60e01b815260040160405180910390fd5b6001600160a01b038116600081815260076020526040808220805460ff19166001179055517f28f54e0b69489ad5fd27625e6fcff58faff5da96f8a077d08bb09af25bb41d549190a250565b6001600160a01b0381161580610e8357506001600160a01b0381166001145b15610e8b5750565b6001600160a01b038181166000908152600860205260409020541615610eae5750565b60086020527fad67d757c34507f157cacfa2e3153e9f260a2244f30428821be7be64587ac55f80546001600160a01b038381166000818152604081208054939094166001600160a01b031993841617909355600183528354909116179091556009805491610f1b83611407565b90915550506040516001600160a01b038216907f64706ace8701df5bd070a4bebf17d164c79457579cfdbd3a6876bf531723fc3c90600090a250565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610fb357610f8e8382611420565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610fdb908490611420565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716906000805160206114d5833981519152906110249087815260200190565b60405180910390a3506001949350505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516110699190611433565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b600b54600160a01b900460ff166110eb576110eb82610e64565b6110f58282611188565b69d3c21bcecceda100000060025411156109e55760405163041c0c2360e31b815260040160405180910390fd5b33600090815260036020526040812080548391908390611143908490611420565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133906000805160206114d58339815191529061089d9086815260200190565b806002600082825461119a91906113ba565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481526000805160206114d5833981519152910160405180910390a35050565b6001600160a01b03811681146111f657600080fd5b50565b60006020828403121561120b57600080fd5b8135610a93816111e1565b60006020808352835180602085015260005b8181101561124457858101830151858201604001528201611228565b506000604082860101526040601f19601f8301168501019250505092915050565b6000806040838503121561127857600080fd5b8235611283816111e1565b946020939093013593505050565b6000806000606084860312156112a657600080fd5b83356112b1816111e1565b925060208401356112c1816111e1565b929592945050506040919091013590565b600080600080600080600060e0888a0312156112ed57600080fd5b87356112f8816111e1565b96506020880135611308816111e1565b95506040880135945060608801359350608088013560ff8116811461132c57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561135c57600080fd5b8235611367816111e1565b91506020830135611377816111e1565b809150509250929050565b60006020828403121561139457600080fd5b81518015158114610a9357600080fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156108a9576108a96113a4565b600181811c908216806113e157607f821691505b60208210810361140157634e487b7160e01b600052602260045260246000fd5b50919050565b600060018201611419576114196113a4565b5060010190565b818103818111156108a9576108a96113a4565b60008083548160018260011c9150600183168061145157607f831692505b6020808410820361147057634e487b7160e01b86526022600452602486fd5b8180156114845760018114611499576114c6565b60ff19861689528415158502890196506114c6565b60008a81526020902060005b868110156114be5781548b8201529085019083016114a5565b505084890196505b50949897505050505050505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c752b4559374174c4757acaed4c0763df9e08d7b67c27800e9fa621c64c6999c64736f6c63430008180033987fbabc6900d88f423a112781b8eb8200eefadcba62925ce7f0a70c60ee786a0000000000000000000000000000000000000000000bd0a38f2f5f1fcadb402600000000000000000000000081156ae9a7ad6daacd28726d403617007a3de6d80000000000000000000000008717cd5a7250aed3473f92e97d933d2972c747fd0000000000000000000000008717cd5a7250aed3473f92e97d933d2972c747fd

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101005760003560e01c80639abdcb2211610097578063d6275f3d11610066578063d6275f3d1461023b578063dfc5d02f1461024e578063ecbfc07714610257578063f2fde38b1461025f57600080fd5b80639abdcb22146101ef578063ab1a4d9414610202578063b2c62d461461020c578063c38b761c1461021457600080fd5b8063567142be116100d3578063567142be1461019f5780637fc27803146101a85780638da5cb5b146101b55780638f0e0e51146101c857600080fd5b806305effe31146101055780632480d3d2146101485780632eb4a7ab1461015d5780633f27126514610174575b600080fd5b610133610113366004610c18565b600760209081526000928352604080842090915290825290205460ff1681565b60405190151581526020015b60405180910390f35b61015b610156366004610c42565b610272565b005b61016660025481565b60405190815260200161013f565b600354610187906001600160a01b031681565b6040516001600160a01b03909116815260200161013f565b61016660055481565b6006546101339060ff1681565b600154610187906001600160a01b031681565b6101877f0000000000000000000000001578f4de7fcb3ac9e8925ac690228edca3bbc7c581565b61015b6101fd366004610cb0565b6102ef565b61016662093a8081565b61015b6108b0565b6101877f00000000000000000000000081156ae9a7ad6daacd28726d403617007a3de6d881565b61015b610249366004610d74565b61099f565b61016660045481565b61015b610a44565b61015b61026d366004610d74565b610aa5565b6001546001600160a01b031633146102a55760405162461bcd60e51b815260040161029c90610d96565b60405180910390fd5b816102c3576040516385ac2b9960e01b815260040160405180910390fd5b806000036102e4576040516329a5ddcd60e11b815260040160405180910390fd5b600291909155600555565b60005460011461032e5760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b604482015260640161029c565b60026000558660c881111561035657604051631258900d60e21b815260040160405180910390fd5b85811415806103655750838114155b806103705750818114155b1561038e57604051631df89e8b60e01b815260040160405180910390fd5b60065460ff166103b15760405163c84651bb60e01b815260040160405180910390fd5b60005b8181101561089f5761044f8a8a838181106103d1576103d1610dbc565b90506020020160208101906103e69190610d74565b8989848181106103f8576103f8610dbc565b9050602002013588888581811061041157610411610dbc565b90506020020160208101906104269190610dd2565b87878681811061043857610438610dbc565b905060200281019061044a9190610df8565b610b1b565b61046c576040516309bde33960e01b815260040160405180910390fd5b6001600760008c8c8581811061048457610484610dbc565b90506020020160208101906104999190610d74565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008888858181106104cd576104cd610dbc565b90506020020160208101906104e29190610dd2565b63ffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550600060055489898481811061052457610524610dbc565b905060200201357f0000000000000000000000001578f4de7fcb3ac9e8925ac690228edca3bbc7c56001600160a01b03166332cb6b0c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610589573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ad9190610e42565b6105b79190610e71565b6105c19190610e8e565b9050600060646105d283600a610e71565b6105dc9190610e8e565b9050600060646105ed846019610e71565b6105f79190610e8e565b90506000816106068486610eb0565b6106109190610eb0565b90507f0000000000000000000000001578f4de7fcb3ac9e8925ac690228edca3bbc7c56001600160a01b03166340c10f198f8f8881811061065357610653610dbc565b90506020020160208101906106689190610d74565b6040516001600160e01b031960e084901b1681526001600160a01b03909116600482015260248101869052604401600060405180830381600087803b1580156106b057600080fd5b505af11580156106c4573d6000803e3d6000fd5b50506040516340c10f1960e01b81526001600160a01b037f00000000000000000000000081156ae9a7ad6daacd28726d403617007a3de6d881166004830152602482018690527f0000000000000000000000001578f4de7fcb3ac9e8925ac690228edca3bbc7c51692506340c10f199150604401600060405180830381600087803b15801561075257600080fd5b505af1158015610766573d6000803e3d6000fd5b50506003546040516340c10f1960e01b81526001600160a01b039182166004820152602481018590527f0000000000000000000000001578f4de7fcb3ac9e8925ac690228edca3bbc7c590911692506340c10f199150604401600060405180830381600087803b1580156107d957600080fd5b505af11580156107ed573d6000803e3d6000fd5b505050507f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a8e8e8781811061082457610824610dbc565b90506020020160208101906108399190610d74565b848c8c8981811061084c5761084c610dbc565b90506020020160208101906108619190610dd2565b604080516001600160a01b039094168452602084019290925263ffffffff169082015260600160405180910390a15050600190920191506103b49050565b505060016000555050505050505050565b6001546001600160a01b031633146108da5760405162461bcd60e51b815260040161029c90610d96565b60065460ff1615806108fc575062093a806004546108f89190610ec3565b4211155b1561091a57604051631700817360e11b815260040160405180910390fd5b6006805460ff191690556040805163ef70aebf60e01b815290516001600160a01b037f0000000000000000000000001578f4de7fcb3ac9e8925ac690228edca3bbc7c5169163ef70aebf91600480830192600092919082900301818387803b15801561098557600080fd5b505af1158015610999573d6000803e3d6000fd5b50505050565b6001546001600160a01b031633146109c95760405162461bcd60e51b815260040161029c90610d96565b6001600160a01b0381166109f0576040516357cb072360e11b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b0383169081179091556040519081527ffd77d63cd7b27dcbfb56f757ec6cb5b7480be2f408127dcc5844f7c4461cac6d9060200160405180910390a150565b6001546001600160a01b03163314610a6e5760405162461bcd60e51b815260040161029c90610d96565b60065460ff1615610a9257604051635874e70f60e11b815260040160405180910390fd5b6006805460ff1916600117905542600455565b6001546001600160a01b03163314610acf5760405162461bcd60e51b815260040161029c90610d96565b600180546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6001600160a01b038516600090815260076020908152604080832063ffffffff8716845290915281205460ff1615610b6657604051630c8d9eab60e31b815260040160405180910390fd5b604080516001600160a01b038816602082015290810186905263ffffffff85166060820152600090608001604051602081830303815290604052805190602001209050610bb7848460025484610bc2565b979650505050505050565b60008315610bf4578360051b8501855b803580851160051b94855260209485185260406000209301818110610bd25750505b501492915050565b80356001600160a01b0381168114610c1357600080fd5b919050565b60008060408385031215610c2b57600080fd5b610c3483610bfc565b946020939093013593505050565b60008060408385031215610c5557600080fd5b50508035926020909101359150565b60008083601f840112610c7657600080fd5b50813567ffffffffffffffff811115610c8e57600080fd5b6020830191508360208260051b8501011115610ca957600080fd5b9250929050565b6000806000806000806000806080898b031215610ccc57600080fd5b883567ffffffffffffffff80821115610ce457600080fd5b610cf08c838d01610c64565b909a50985060208b0135915080821115610d0957600080fd5b610d158c838d01610c64565b909850965060408b0135915080821115610d2e57600080fd5b610d3a8c838d01610c64565b909650945060608b0135915080821115610d5357600080fd5b50610d608b828c01610c64565b999c989b5096995094979396929594505050565b600060208284031215610d8657600080fd5b610d8f82610bfc565b9392505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610de457600080fd5b813563ffffffff81168114610d8f57600080fd5b6000808335601e19843603018112610e0f57600080fd5b83018035915067ffffffffffffffff821115610e2a57600080fd5b6020019150600581901b3603821315610ca957600080fd5b600060208284031215610e5457600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610e8857610e88610e5b565b92915050565b600082610eab57634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610e8857610e88610e5b565b80820180821115610e8857610e88610e5b56fea26469706673582212201b45aeeadd7d43f2bcae06de43e65f5acc313c2d4ba804fc6cca2a3e8ea7590964736f6c63430008180033