false
true
0

Contract Address Details

0x659a56a1ECd5a4a13633fEbb9C15f05bb9fA688F

Contract Name
ZKVerifier
Creator
0x5a5db3–1f0f74 at 0xae38a3–000d78
Balance
0 tPLS
Tokens
Fetching tokens...
Transactions
Fetching transactions...
Transfers
Fetching transfers...
Gas Used
Fetching gas used...
Last Balance Update
25348460
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
ZKVerifier




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




EVM Version




Verified at
2026-08-25T19:41:07.659683Z

Constructor Arguments

00000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ca7e7f6543fe8ff022b168f086b460542845704

Arg [0] (address) : 0x0000000000000000000000000000000000000000
Arg [1] (address) : 0x8ca7e7f6543fe8ff022b168f086b460542845704

              

contracts/ZKVerifier.sol

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

import "@openzeppelin/contracts/access/Ownable.sol";
import "./AdminZamik.sol";

interface IRWAToken {
    function mintWithProof(address to, uint256 amount, bytes32 proofHash) external;
    function mintFee(address to, uint256 amount) external;
    function assetValueUSD() external view returns (uint256);
    function totalSupply() external view returns (uint256);
    function feeRecipient() external view returns (address);
}

/**
 * @title ZKVerifier
 * @notice Verifies Groth16 ZK proofs for RWA ownership claims
 *
 * Security fixes (v2):
 *  - recipient mora biti msg.sender → prepreči frontrunning
 *  - amount je omejen na maxMintable (izračunan iz assetValueUSD) → prepreči neomejeni mint
 *  - amount > 0 check
 *  - proofHash vključuje recipient in amount
 *  - registeredCommitments počiščen po mintu
 *  - setRwaToken odstranjen (mrtva koda — konstruktor že nastavi token)
 */
contract ZKVerifier is Ownable, AdminZamik {

    // === snarkjs-generated VK constants (from rwa_proof_verifier.sol) ===
    // Scalar field size
        uint256 constant r    = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
        // Base field size
        uint256 constant q   = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
    
        // Verification Key data
        uint256 constant alphax  = 20491192805390485299153009773594534940189261866228447918068658471970481763042;
        uint256 constant alphay  = 9383485363053290200918347156157836566562967994039712273449902621266178545958;
        uint256 constant betax1  = 4252822878758300859123897981450591353533073413197771768651442665752259397132;
        uint256 constant betax2  = 6375614351688725206403948262868962793625744043794305715222011528459656738731;
        uint256 constant betay1  = 21847035105528745403288232691147584728191162732299865338377159692350059136679;
        uint256 constant betay2  = 10505242626370262277552901082094356697409835680220590971873171140371331206856;
        uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
        uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
        uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
        uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
        uint256 constant deltax1 = 7634694382555350249182314939945794752801670761871442236918755611747247981945;
        uint256 constant deltax2 = 7785580959050401778007424472707980943542624615417776150098749352587788464225;
        uint256 constant deltay1 = 19797755760015837479531733607381070868376789853134730363187779619202029563244;
        uint256 constant deltay2 = 19885317433472164527823093690594480541727870532036884219862146880419864556528;
    
        
        uint256 constant IC0x = 5313285605904455468883044812252347068829101215429313644709835484872601966339;
        uint256 constant IC0y = 2611852344649716617799171908939889777235094010478351269767823832353876722738;
        
        uint256 constant IC1x = 3721507159761245641438686913490987492444926420712387384343195655500770466953;
        uint256 constant IC1y = 10884128966892936170203469452538504289719178213118369098919656563615016733370;
        
        uint256 constant IC2x = 11919587884350751358344086380913156139705038053372491645096979466761922566199;
        uint256 constant IC2y = 11737085826314024049430266969005569805271747491015946543900350977318458074708;
        
     
        // Memory data
        uint16 constant pVk = 0;
        uint16 constant pPairing = 128;
    
        uint16 constant pLastMem = 896;
    // === end generated constants ===

    address public rwaToken;
    address public entropyOracle;

    // Asset registry: samo vnaprej registrirani assetCommitment-i lahko mintajo.
    // assetCommitment = Poseidon(privateKey, entropyNonce) = javni signal _pubSignals[0]
    mapping(uint256 => bool) public registeredCommitments; // upravičenost (nastavi lastnik)
    mapping(uint256 => bool) public commitmentUsed;        // porabljeno (vsak asset minta enkrat)

    // Pooblaščeni UORS operaterji — smejo registrirati commitmente
    mapping(address => bool) public authorizedUORS;

    // Tokenizacijska provizija: 0,5% ob mintu
    uint256 public constant MINT_FEE_BPS = 50; // 50 = 0,5%

    event ProofVerified(address indexed claimant, bytes32 proofHash);
    event RwaTokenSet(address indexed token);
    event MintFeeCollected(address indexed feeRecipient, uint256 fee);
    event AssetRegistered(uint256 indexed commitment);
    event AssetUnregistered(uint256 indexed commitment);
    event AssetMinted(uint256 indexed commitment, address indexed recipient, uint256 amount);
    event UORSAuthorized(address indexed uors);
    event UORSRevoked(address indexed uors);

    modifier onlyOwnerOrUORS() {
        require(msg.sender == owner() || authorizedUORS[msg.sender], "Not authorized");
        _;
    }

    constructor(address _rwaToken, address _entropyOracle) Ownable(msg.sender) {
        // _rwaToken sme biti address(0) pri deployu (circular dep.) — nastavi z setRwaToken()
        rwaToken = _rwaToken;
        entropyOracle = _entropyOracle;
    }

    /**
     * @notice Nastavi RWAToken naslov — samo enkrat po deployu (circular dep. fix).
     * @dev Pokliče se takoj po deploy RWAToken. Po nastavitvi ni več spremenljivo.
     */
    function setRwaToken(address _rwaToken) external onlyOwner {
        require(rwaToken == address(0), "Already set");
        require(_rwaToken != address(0), "Zero address");
        rwaToken = _rwaToken;
        emit RwaTokenSet(_rwaToken);
    }

    /**
     * @notice Registrira legitimen assetCommitment — samo lastnik (izdajatelj sredstva).
     * @dev Lastnik sredstva izračuna commitment = Poseidon(privateKey, entropyNonce)
     *      in deli SAMO commitment (ne ključa). Izdajatelj ga tu registrira.
     */
    /**
     * PODELITEV MOCI GRE SKOZI ZAMIK, ODVZEM NE.
     *
     * Nov UORS lahko registrira commitmente, ti pa so pot do kovanja zetonov.
     * Podtaknjen operater je zato med najmocnejsimi napadi, ki jih owner kljuc
     * sploh omogoca — in je hkrati napad, ki ga je mogoce VIDETI VNAPREJ.
     * Zato javna napoved + zamik.
     *
     * revokeUORS ostaja takojsen: ob razkritem kljucu operaterja ga moras vreci
     * ven zdaj, ne cez 48 ur. Nevarnost caka, zasilna zavora ne.
     */
    function napoviAuthorizeUORS(address uors) external onlyOwner {
        require(uors != address(0), "Zero address");
        _napovej(keccak256(abi.encode("authorizeUORS", uors)), "ZKVerifier.authorizeUORS");
    }

    /// @notice Pooblasti UORS operaterja za registracijo commitmentov.
    function authorizeUORS(address uors) external onlyOwner {
        require(uors != address(0), "Zero address");
        _porabi(keccak256(abi.encode("authorizeUORS", uors)), "ZKVerifier.authorizeUORS");
        authorizedUORS[uors] = true;
        emit UORSAuthorized(uors);
    }

    /// @notice Prekliče pooblastilo UORS operaterja.
    function revokeUORS(address uors) external onlyOwner {
        authorizedUORS[uors] = false;
        emit UORSRevoked(uors);
    }

    function registerCommitment(uint256 commitment) external onlyOwnerOrUORS {
        require(commitment != 0, "Zero commitment");
        require(!registeredCommitments[commitment], "Already registered");
        registeredCommitments[commitment] = true;
        emit AssetRegistered(commitment);
    }

    /// @notice Paketna registracija večih commitmentov naenkrat.
    function registerCommitments(uint256[] calldata commitments) external onlyOwnerOrUORS {
        for (uint256 i = 0; i < commitments.length; i++) {
            uint256 c = commitments[i];
            if (c != 0 && !registeredCommitments[c]) {
                registeredCommitments[c] = true;
                emit AssetRegistered(c);
            }
        }
    }

    /// @notice Prekliče registracijo (le če še ni bil porabljen).
    function unregisterCommitment(uint256 commitment) external onlyOwner {
        require(registeredCommitments[commitment], "Not registered");
        require(!commitmentUsed[commitment], "Already used");
        registeredCommitments[commitment] = false;
        emit AssetUnregistered(commitment);
    }

    /// @notice Onemogoceno: renounceOwnership() bi trajno onemogocil
    ///         (de)avtorizacijo UORS operatorjev in registracijo commitmentov.
    function renounceOwnership() public pure override {
        revert("Renounce onemogocen");
    }

    /**
     * @notice Verify ZK proof and mint RWA tokens to caller.
     * @dev recipient je vedno msg.sender — prepreči frontrunning.
     *      amount je omejen na maxMintable = assetValueUSD / 1e16
     *      (1 RWA token = $0.01 USD pri 18 decimalkah).
     *      Prilagodi delilnik glede na tvojo tokenomiko.
     */
    function verifyAndMint(
        uint[2] calldata _pA,
        uint[2][2] calldata _pB,
        uint[2] calldata _pC,
        uint[2] calldata _pubSignals,
        uint256 amount
    ) external {
        // FIX #2: recipient je vedno msg.sender — prepreči frontrunning iz mempoola
        address recipient = msg.sender;

        // FIX #1a: amount > 0
        require(amount > 0, "Zero amount");

        // FIX #1b: amount omejen na maxMintable glede na vrednost sredstva
        uint256 assetValue = IRWAToken(rwaToken).assetValueUSD();
        uint256 maxMintable = assetValue * 100; // assetValueUSD ima 18 decimalk; *100 ker 1 token = $0.01
        require(amount <= maxMintable, "Amount exceeds asset value");

        require(verifyProof(_pA, _pB, _pC, _pubSignals), "Invalid ZK proof");

        // Asset registry: dokaz mora pripadati registriranemu, še neporabljenemu sredstvu
        uint256 commitment = _pubSignals[0];
        require(registeredCommitments[commitment], "Commitment not registered");
        require(!commitmentUsed[commitment], "Asset already minted");
        commitmentUsed[commitment] = true;

        // FIX #3: počisti registracijo po mintu (clean state)
        registeredCommitments[commitment] = false;

        // FIX #4: proofHash vključuje recipient in amount — popolna auditability
        // Tokenizacijska provizija: 0,5% ob mintu → feeRecipient (platforma)
        uint256 mintFee = amount * MINT_FEE_BPS / 10_000;
        uint256 netAmount = amount - mintFee;

        bytes32 proofHash = keccak256(abi.encode(_pA, _pB, _pC, _pubSignals, recipient, amount));
        IRWAToken(rwaToken).mintWithProof(recipient, netAmount, proofHash);

        if (mintFee > 0) {
            address feeRecipient = IRWAToken(rwaToken).feeRecipient();
            IRWAToken(rwaToken).mintFee(feeRecipient, mintFee);
            emit MintFeeCollected(feeRecipient, mintFee);
        }

        emit AssetMinted(commitment, recipient, netAmount);
        emit ProofVerified(recipient, proofHash);
    }

    function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[2] calldata _pubSignals) internal view returns (bool result) {
        assembly {
            function checkField(v) {
                if iszero(lt(v, r)) {
                    mstore(0, 0)
                    revert(0, 0)
                }
            }
            
            // G1 function to multiply a G1 value(x,y) to value in an address
            function g1_mulAccC(pR, x, y, s) {
                let success
                let mIn := mload(0x40)
                mstore(mIn, x)
                mstore(add(mIn, 32), y)
                mstore(add(mIn, 64), s)

                success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)

                if iszero(success) {
                    mstore(0, 0)
                    revert(0, 0)
                }

                mstore(add(mIn, 64), mload(pR))
                mstore(add(mIn, 96), mload(add(pR, 32)))

                success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)

                if iszero(success) {
                    mstore(0, 0)
                    revert(0, 0)
                }
            }

            function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {
                let _pPairing := add(pMem, pPairing)
                let _pVk := add(pMem, pVk)

                mstore(_pVk, IC0x)
                mstore(add(_pVk, 32), IC0y)

                // Compute the linear combination vk_x
                
                g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))
                
                g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))
                

                // -A
                mstore(_pPairing, calldataload(pA))
                mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))

                // B
                mstore(add(_pPairing, 64), calldataload(pB))
                mstore(add(_pPairing, 96), calldataload(add(pB, 32)))
                mstore(add(_pPairing, 128), calldataload(add(pB, 64)))
                mstore(add(_pPairing, 160), calldataload(add(pB, 96)))

                // alpha1
                mstore(add(_pPairing, 192), alphax)
                mstore(add(_pPairing, 224), alphay)

                // beta2
                mstore(add(_pPairing, 256), betax1)
                mstore(add(_pPairing, 288), betax2)
                mstore(add(_pPairing, 320), betay1)
                mstore(add(_pPairing, 352), betay2)

                // vk_x
                mstore(add(_pPairing, 384), mload(add(pMem, pVk)))
                mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))


                // gamma2
                mstore(add(_pPairing, 448), gammax1)
                mstore(add(_pPairing, 480), gammax2)
                mstore(add(_pPairing, 512), gammay1)
                mstore(add(_pPairing, 544), gammay2)

                // C
                mstore(add(_pPairing, 576), calldataload(pC))
                mstore(add(_pPairing, 608), calldataload(add(pC, 32)))

                // delta2
                mstore(add(_pPairing, 640), deltax1)
                mstore(add(_pPairing, 672), deltax2)
                mstore(add(_pPairing, 704), deltay1)
                mstore(add(_pPairing, 736), deltay2)


                let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)

                isOk := and(success, mload(_pPairing))
            }

            let pMem := mload(0x40)
            mstore(0x40, add(pMem, pLastMem))

            // Validate that all evaluations ∈ F
            
            checkField(calldataload(add(_pubSignals, 0)))
            
            checkField(calldataload(add(_pubSignals, 32)))
            

            // Validate all evaluations
            let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)

            result := isValid
         }
     }
}
        

@openzeppelin/contracts/access/Ownable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @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 {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}
          

@openzeppelin/contracts/utils/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
          

contracts/AdminZamik.sol

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

import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title AdminZamik
 * @notice Casovni zamik na nevarne admin spremembe.
 *
 * ZAKAJ TO OBSTAJA
 * ----------------
 * Owner kljuc na tej platformi NE more krasti: ne more kovati zetonov, ne more
 * premikati tujih zetonov in ne more v escrow. Kar PA lahko, je tiho zamenjati
 * nastavitve pod nogami uporabnikov — KYC listo, placilni token, prijavljeno
 * vrednost sredstva.
 *
 * Vsi trije so napadi, ki jih je mogoce VIDETI VNAPREJ. Zato jih ne branimo z
 * multisigom (ki varuje lastnika kljuca), ampak s casovnim zamikom (ki varuje
 * UPORABNIKA): sprememba se mora najprej javno napovedati, sele po zamiku jo je
 * mogoce izvesti. Uporabnik ima ves ta cas, da spremembo vidi in izstopi.
 *
 * Namenoma NI zunanje timelock pogodbe kot lastnika. Tak vzorec doda tveganje
 * nedosegljivosti: ce lastniku kdaj ne uspe sestaviti transakcije skozi tujo
 * pogodbo, so kontrakti zamrznjeni za vedno. Tu je zamik vgrajen, lastnik pa
 * ostane navadna denarnica.
 *
 * KAJ ZAMIK NE POKRIVA (namerno)
 * ------------------------------
 *   - pause()   — zasilna zavora mora biti takojsnja, sicer ni zavora
 *   - unpause() — vrnitev v obratovanje naj bo hitra
 *   - odvzem pravice zaustavljalca — ob razkritem kljucu ga moras vreci TAKOJ
 * Nevarnost caka, zasilna zavora ne.
 */
abstract contract AdminZamik is Ownable {
    /// @notice Rok, v katerem je napoved uporabna. Po njem potece.
    /// @dev Brez tega bi stara napoved lezala na verigi kot nabita puska:
    ///      napoves nekaj neopaznega danes, izvedes cez pol leta, ko nihce vec
    ///      ne gleda. Napoved, ki ni bila izvedena v roku, je treba ponoviti.
    uint256 public constant ROK = 7 days;

    /// @notice id napovedi → cas, od katerega je izvedljiva (0 = ni napovedi)
    mapping(bytes32 => uint256) public izvedljivoOd;

    event SpremembaNapovedana(bytes32 indexed id, string kaj, uint256 izvedljivoOd, uint256 potece);
    event SpremembaIzvedena(bytes32 indexed id, string kaj);
    event SpremembaPreklicana(bytes32 indexed id, string kaj);

    /// @notice Koliko casa mora sprememba cakati.
    ///
    /// ⚠️⚠️ TRENUTNO 10 MINUT — RAZVOJNA VREDNOST ZA TESTNET (943).
    ///      Nastavljeno 24. 8. 2026 po Juretovi odlocitvi. Projekt se razvija
    ///      izkljucno na testnetu; mainnet je na pavzi.
    ///
    ///      PRED KAKRSNIMKOLI DEPLOYEM NA MAINNET (369) VRNI NA 48 ur.
    ///      Deset minut zamika na mainnetu pomeni, da napadalec z admin
    ///      kljucem izvede spremembo, preden jo utegnes opaziti — zamik je
    ///      takrat videti prisoten, a je brez ucinka.
    ///
    /// @dev virtual ostaja, da lahko posamezna pogodba vrednost se povozi
    ///      (MarketplaceTestnet to pocne).
    function zamik() public view virtual returns (uint256) {
        return 10 minutes;
    }

    // ── Notranje ────────────────────────────────────────────────────────────

    /// @dev id MORA vsebovati tocne parametre spremembe, sicer bi lahko
    ///      napovedal nedolzno vrednost in izvedel skodljivo.
    function _napovej(bytes32 id, string memory kaj) internal {
        require(izvedljivoOd[id] == 0, "Ze napovedano");
        uint256 od = block.timestamp + zamik();
        izvedljivoOd[id] = od;
        emit SpremembaNapovedana(id, kaj, od, od + ROK);
    }

    function _porabi(bytes32 id, string memory kaj) internal {
        uint256 od = izvedljivoOd[id];
        require(od != 0, "Ni napovedano");
        require(block.timestamp >= od, "Zamik se ni potekel");
        require(block.timestamp <= od + ROK, "Napoved je potekla");
        delete izvedljivoOd[id];
        emit SpremembaIzvedena(id, kaj);
    }

    // ── Javno ───────────────────────────────────────────────────────────────

    /// @notice Preklic napovedane spremembe. Takojsen — premisliti se mora biti
    ///         mogoce hitreje, kot se izvede.
    function prekliciSpremembo(bytes32 id, string calldata kaj) external onlyOwner {
        require(izvedljivoOd[id] != 0, "Ni napovedano");
        delete izvedljivoOd[id];
        emit SpremembaPreklicana(id, kaj);
    }

    /// @notice Stanje napovedi — da ga stran in nadzorni sistem lahko prikazeta.
    function stanjeNapovedi(bytes32 id)
        external
        view
        returns (bool napovedana, uint256 od, uint256 potece, bool izvedljivaZdaj)
    {
        uint256 t = izvedljivoOd[id];
        if (t == 0) return (false, 0, 0, false);
        return (true, t, t + ROK, block.timestamp >= t && block.timestamp <= t + ROK);
    }
}
          

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"paris"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_rwaToken","internalType":"address"},{"type":"address","name":"_entropyOracle","internalType":"address"}]},{"type":"error","name":"OwnableInvalidOwner","inputs":[{"type":"address","name":"owner","internalType":"address"}]},{"type":"error","name":"OwnableUnauthorizedAccount","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"event","name":"AssetMinted","inputs":[{"type":"uint256","name":"commitment","internalType":"uint256","indexed":true},{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AssetRegistered","inputs":[{"type":"uint256","name":"commitment","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"AssetUnregistered","inputs":[{"type":"uint256","name":"commitment","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"MintFeeCollected","inputs":[{"type":"address","name":"feeRecipient","internalType":"address","indexed":true},{"type":"uint256","name":"fee","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ProofVerified","inputs":[{"type":"address","name":"claimant","internalType":"address","indexed":true},{"type":"bytes32","name":"proofHash","internalType":"bytes32","indexed":false}],"anonymous":false},{"type":"event","name":"RwaTokenSet","inputs":[{"type":"address","name":"token","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"SpremembaIzvedena","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"string","name":"kaj","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"SpremembaNapovedana","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"string","name":"kaj","internalType":"string","indexed":false},{"type":"uint256","name":"izvedljivoOd","internalType":"uint256","indexed":false},{"type":"uint256","name":"potece","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SpremembaPreklicana","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"string","name":"kaj","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"UORSAuthorized","inputs":[{"type":"address","name":"uors","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"UORSRevoked","inputs":[{"type":"address","name":"uors","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MINT_FEE_BPS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"ROK","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"authorizeUORS","inputs":[{"type":"address","name":"uors","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"authorizedUORS","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"commitmentUsed","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"entropyOracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"izvedljivoOd","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"napoviAuthorizeUORS","inputs":[{"type":"address","name":"uors","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"prekliciSpremembo","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32"},{"type":"string","name":"kaj","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerCommitment","inputs":[{"type":"uint256","name":"commitment","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerCommitments","inputs":[{"type":"uint256[]","name":"commitments","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"registeredCommitments","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeUORS","inputs":[{"type":"address","name":"uors","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rwaToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRwaToken","inputs":[{"type":"address","name":"_rwaToken","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"napovedana","internalType":"bool"},{"type":"uint256","name":"od","internalType":"uint256"},{"type":"uint256","name":"potece","internalType":"uint256"},{"type":"bool","name":"izvedljivaZdaj","internalType":"bool"}],"name":"stanjeNapovedi","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unregisterCommitment","inputs":[{"type":"uint256","name":"commitment","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"verifyAndMint","inputs":[{"type":"uint256[2]","name":"_pA","internalType":"uint256[2]"},{"type":"uint256[2][2]","name":"_pB","internalType":"uint256[2][2]"},{"type":"uint256[2]","name":"_pC","internalType":"uint256[2]"},{"type":"uint256[2]","name":"_pubSignals","internalType":"uint256[2]"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"zamik","inputs":[]}]
              

Contract Creation Code

0x60806040523480156200001157600080fd5b5060405162001bb938038062001bb9833981016040819052620000349162000106565b33806200005b57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b620000668162000099565b50600280546001600160a01b039384166001600160a01b031991821617909155600380549290931691161790556200013e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200010157600080fd5b919050565b600080604083850312156200011a57600080fd5b6200012583620000e9565b91506200013560208401620000e9565b90509250929050565b611a6b806200014e6000396000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c806376e382c8116100b8578063c714d0f71161007c578063c714d0f714610308578063d48693d114610310578063e5236f8614610318578063e826f69a1461032b578063eaaca8f514610335578063f2fde38b1461034857600080fd5b806376e382c814610287578063776528cd1461029a5780637af89ef5146102d1578063847561f8146102e45780638da5cb5b146102f757600080fd5b8063235a0b9b1161010a578063235a0b9b1461020057806328ce0d8614610223578063392e741814610236578063685ff87814610249578063704c17961461025c578063715018a61461027f57600080fd5b806305e105b9146101475780630854eef51461017f5780630c5bf351146101ad5780630e78931d146101d85780631f092d34146101eb575b600080fd5b61016a610155366004611645565b60056020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61019f61018d366004611645565b60016020526000908152604090205481565b604051908152602001610176565b6002546101c0906001600160a01b031681565b6040516001600160a01b039091168152602001610176565b6003546101c0906001600160a01b031681565b6101fe6101f9366004611675565b61035b565b005b61016a61020e366004611645565b60046020526000908152604090205460ff1681565b6101fe610231366004611645565b61081b565b6101fe6102443660046116f3565b610900565b6101fe610257366004611717565b6109bf565b61016a61026a3660046116f3565b60066020526000908152604090205460ff1681565b6101fe610ac0565b6101fe61029536600461178c565b610afe565b6102ad6102a8366004611645565b610ba5565b60408051941515855260208501939093529183015215156060820152608001610176565b6101fe6102df3660046116f3565b610c12565b6101fe6102f23660046116f3565b610c63565b6000546001600160a01b03166101c0565b61019f603281565b61025861019f565b6101fe6103263660046116f3565b610d3d565b61019f62093a8081565b6101fe610343366004611645565b610dce565b6101fe6103563660046116f3565b610f0c565b338161039c5760405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8185b5bdd5b9d60aa1b60448201526064015b60405180910390fd5b600254604080516366f1101560e11b815290516000926001600160a01b03169163cde2202a9160048083019260209291908290030181865afa1580156103e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040a9190611808565b90506000610419826064611837565b90508084111561046b5760405162461bcd60e51b815260206004820152601a60248201527f416d6f756e7420657863656564732061737365742076616c75650000000000006044820152606401610393565b61047788888888610f47565b6104b65760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2102d2590383937b7b360811b6044820152606401610393565b843560008181526004602052604090205460ff166105165760405162461bcd60e51b815260206004820152601960248201527f436f6d6d69746d656e74206e6f742072656769737465726564000000000000006044820152606401610393565b60008181526005602052604090205460ff161561056c5760405162461bcd60e51b8152602060048201526014602482015273105cdcd95d08185b1c9958591e481b5a5b9d195960621b6044820152606401610393565b6000818152600560209081526040808320805460ff1990811660011790915560049092528220805490911690556127106105a7603288611837565b6105b19190611864565b905060006105bf8288611886565b905060008b8b8b8b8a8c6040516020016105de96959493929190611899565b60408051808303601f19018152908290528051602090910120600254636a3b5c4d60e01b83526001600160a01b038a8116600485015260248401869052604484018390529193501690636a3b5c4d90606401600060405180830381600087803b15801561064a57600080fd5b505af115801561065e573d6000803e3d6000fd5b505050506000831115610786576002546040805163011a412160e61b815290516000926001600160a01b03169163469048409160048083019260209291908290030181865afa1580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d991906118fa565b600254604051638cc9d10760e01b81526001600160a01b03808416600483015260248201889052929350911690638cc9d10790604401600060405180830381600087803b15801561072957600080fd5b505af115801561073d573d6000803e3d6000fd5b50505050806001600160a01b03167fd2b7c9cdd8f0b876462485c766dac30078e9ef6f76ce1e57ca92c7bd553bcf1f8560405161077c91815260200190565b60405180910390a2505b866001600160a01b0316847f825345861315f1f596fdc2b9bec2cb36452a81888724d69abb25b39f6341f0ca846040516107c291815260200190565b60405180910390a3866001600160a01b03167f0565033f3973b38ac07b3b39f05c0bcfa1449a22d6fd347fdc63c7a8370e106a8260405161080591815260200190565b60405180910390a2505050505050505050505050565b6108236113f0565b60008181526004602052604090205460ff166108725760405162461bcd60e51b815260206004820152600e60248201526d139bdd081c9959da5cdd195c995960921b6044820152606401610393565b60008181526005602052604090205460ff16156108c05760405162461bcd60e51b815260206004820152600c60248201526b105b1c9958591e481d5cd95960a21b6044820152606401610393565b600081815260046020526040808220805460ff191690555182917f99088e6d10d683bcaedea1a362ff6ebb8ab7d7c38f4e8c852e68161ae4cde7d391a250565b6109086113f0565b6002546001600160a01b03161561094f5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b6044820152606401610393565b6001600160a01b0381166109755760405162461bcd60e51b815260040161039390611917565b600280546001600160a01b0319166001600160a01b0383169081179091556040517f1df2df20aeec6a569676befc19253674e64c2448304f170b1cf9934cd390f49a90600090a250565b6000546001600160a01b03163314806109e757503360009081526006602052604090205460ff165b610a245760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b6044820152606401610393565b60005b81811015610abb576000838383818110610a4357610a4361184e565b90506020020135905080600014158015610a6c575060008181526004602052604090205460ff16155b15610ab257600081815260046020526040808220805460ff191660011790555182917fcc7b4929606ce963ba54b6a998f106f7748e78c03dc7f08fd77aeb28230eb2d391a25b50600101610a27565b505050565b60405162461bcd60e51b81526020600482015260136024820152722932b737bab731b29037b732b6b7b3b7b1b2b760691b6044820152606401610393565b610b066113f0565b6000838152600160205260408120549003610b535760405162461bcd60e51b815260206004820152600d60248201526c4e69206e61706f766564616e6f60981b6044820152606401610393565b600083815260016020526040808220919091555183907f72003eda7c2c39777210bccbf69141a92bbe56d746914a16f5ee3aaf5e6f7a8390610b98908590859061193d565b60405180910390a2505050565b600081815260016020526040812054819081908190808203610bd557600080600080945094509450945050610c0b565b600181610be562093a808261196c565b834210158015610c015750610bfd62093a808561196c565b4211155b9450945094509450505b9193509193565b610c1a6113f0565b6001600160a01b038116600081815260066020526040808220805460ff19169055517fd84b626bc6cd1f6d62d5e197f48869d2a5ef1a750b360ad929c3de63c88bdfe49190a250565b610c6b6113f0565b6001600160a01b038116610c915760405162461bcd60e51b815260040161039390611917565b610cf181604051602001610ca5919061197f565b60405160208183030381529060405280519060200120604051806040016040528060188152602001775a4b56657269666965722e617574686f72697a65554f525360401b81525061141f565b6001600160a01b038116600081815260066020526040808220805460ff19166001179055517fb334427bfaed9992168ed99fda266e2d7cf5c2ea1a37a1f76e82fd1e307edf7f9190a250565b610d456113f0565b6001600160a01b038116610d6b5760405162461bcd60e51b815260040161039390611917565b610dcb81604051602001610d7f919061197f565b60405160208183030381529060405280519060200120604051806040016040528060188152602001775a4b56657269666965722e617574686f72697a65554f525360401b815250611548565b50565b6000546001600160a01b0316331480610df657503360009081526006602052604090205460ff165b610e335760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b6044820152606401610393565b80600003610e755760405162461bcd60e51b815260206004820152600f60248201526e16995c9bc818dbdb5b5a5d1b595b9d608a1b6044820152606401610393565b60008181526004602052604090205460ff1615610ec95760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e481c9959da5cdd195c995960721b6044820152606401610393565b600081815260046020526040808220805460ff191660011790555182917fcc7b4929606ce963ba54b6a998f106f7748e78c03dc7f08fd77aeb28230eb2d391a250565b610f146113f0565b6001600160a01b038116610f3e57604051631e4fbdf760e01b815260006004820152602401610393565b610dcb816115f5565b60006113b4565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018110610dcb5760008052600080fd5b600060405183815284602082015285604082015260408160608360076107d05a03fa915081610fb05760008052600080fd5b825160408201526020830151606082015260408360808360066107d05a03fa91505080610fe05760008052600080fd5b5050505050565b7f0bbf368c7f6fa7f6559bf65da45c33b505a21ff7fb0874c3bd0e2e7baa1b170385527f05c6418bd08aff1241cc2850606a69d8b73a6d9875e25df448f52ae21907c43260208601526000608086018661108487357f181032dd16b7eea417d83a9181ab6887bae84d538a8731a6f3003db177c0caba7f083a4c6477d7d1a1feb5f0ba3ddcd764a617b31c182138d6e756100407c25c8984610f7e565b6110d460208801357f19f2f485618fdb703d11b2fbc13e61ce7371c4f94e99c148b2d2d8e3f1d9a6547f1a5a3f66f163e8eb3a5351b30773f2cf6126755e91973e02ab7bd68d7752583784610f7e565b50823581527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760208401357f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4703066020820152833560408201526020840135606082015260408401356080820152606084013560a08201527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e260c08201527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660e08201527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101008201527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101208201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101408201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8610160820152600087015161018082015260206000018701516101a08201527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220820152843561024082015260208501356102608201527f10e115799fb9e210b69c6459d325cb70991b1a5f7b23166b9cb1079a84ec05796102808201527f11367b8fccc2b903fc7b4fa13cccc3bd581b6ae5bb74403ff1449df18caeb0616102a08201527f2bc521f6593c958f19d068ab6c9d871471993c59807984ff5540d2ae59f7ad6c6102c08201527f2bf6b0d953792ab8a4e7926e629078462da9a25f808b3d5c13c56b035c14b3f06102e08201526020816103008360086107d05a03fa9051169695505050505050565b60405161038081016040526113cc6000840135610f4e565b6113d96020840135610f4e565b6113e6818486888a610fe7565b9695505050505050565b6000546001600160a01b0316331461141d5760405163118cdaa760e01b8152336004820152602401610393565b565b6000828152600160205260408120549081900361146e5760405162461bcd60e51b815260206004820152600d60248201526c4e69206e61706f766564616e6f60981b6044820152606401610393565b804210156114b45760405162461bcd60e51b815260206004820152601360248201527216985b5a5ac81cd9481b9a481c1bdd195ad95b606a1b6044820152606401610393565b6114c162093a808261196c565b4211156115055760405162461bcd60e51b81526020600482015260126024820152714e61706f766564206a6520706f74656b6c6160701b6044820152606401610393565b600083815260016020526040808220919091555183907ffac4537038ebc9eaa00d86a88a6c2e268012d306f6442966aab36014a195432390610b989085906119fd565b600082815260016020526040902054156115945760405162461bcd60e51b815260206004820152600d60248201526c5a65206e61706f766564616e6f60981b6044820152606401610393565b60006115a26102584261196c565b60008481526001602052604090208190559050827f63a0d065f46e07e30a4f246d28eb53f839982100439173db92dbd5700ab37c1583836115e662093a808261196c565b604051610b9893929190611a10565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561165757600080fd5b5035919050565b806040810183101561166f57600080fd5b92915050565b6000806000806000610160868803121561168e57600080fd5b611698878761165e565b945060c08601878111156116ab57600080fd5b6040870194506116bb888261165e565b9350506116cc87610100880161165e565b94979396509194610140013592915050565b6001600160a01b0381168114610dcb57600080fd5b60006020828403121561170557600080fd5b8135611710816116de565b9392505050565b6000806020838503121561172a57600080fd5b823567ffffffffffffffff8082111561174257600080fd5b818501915085601f83011261175657600080fd5b81358181111561176557600080fd5b8660208260051b850101111561177a57600080fd5b60209290920196919550909350505050565b6000806000604084860312156117a157600080fd5b83359250602084013567ffffffffffffffff808211156117c057600080fd5b818601915086601f8301126117d457600080fd5b8135818111156117e357600080fd5b8760208285010111156117f557600080fd5b6020830194508093505050509250925092565b60006020828403121561181a57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761166f5761166f611821565b634e487b7160e01b600052603260045260246000fd5b60008261188157634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561166f5761166f611821565b61018081016040808984378083018860005b60028110156118c8578382843791830191908301906001016118ab565b505050808760c08501378086610100850137506001600160a01b03939093166101408201526101600152949350505050565b60006020828403121561190c57600080fd5b8151611710816116de565b6020808252600c908201526b5a65726f206164647265737360a01b604082015260600190565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b8082018082111561166f5761166f611821565b6040808252600d908201526c617574686f72697a65554f525360981b60608201526001600160a01b0391909116602082015260800190565b6000815180845260005b818110156119dd576020818501810151868301820152016119c1565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061171060208301846119b7565b606081526000611a2360608301866119b7565b6020830194909452506040015291905056fea26469706673582212207eae391b69264afbf2b5fb009aee8e6ab759ab4c57a1c06d6212740e3f2b4b9264736f6c6343000818003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000008ca7e7f6543fe8ff022b168f086b460542845704

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101425760003560e01c806376e382c8116100b8578063c714d0f71161007c578063c714d0f714610308578063d48693d114610310578063e5236f8614610318578063e826f69a1461032b578063eaaca8f514610335578063f2fde38b1461034857600080fd5b806376e382c814610287578063776528cd1461029a5780637af89ef5146102d1578063847561f8146102e45780638da5cb5b146102f757600080fd5b8063235a0b9b1161010a578063235a0b9b1461020057806328ce0d8614610223578063392e741814610236578063685ff87814610249578063704c17961461025c578063715018a61461027f57600080fd5b806305e105b9146101475780630854eef51461017f5780630c5bf351146101ad5780630e78931d146101d85780631f092d34146101eb575b600080fd5b61016a610155366004611645565b60056020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b61019f61018d366004611645565b60016020526000908152604090205481565b604051908152602001610176565b6002546101c0906001600160a01b031681565b6040516001600160a01b039091168152602001610176565b6003546101c0906001600160a01b031681565b6101fe6101f9366004611675565b61035b565b005b61016a61020e366004611645565b60046020526000908152604090205460ff1681565b6101fe610231366004611645565b61081b565b6101fe6102443660046116f3565b610900565b6101fe610257366004611717565b6109bf565b61016a61026a3660046116f3565b60066020526000908152604090205460ff1681565b6101fe610ac0565b6101fe61029536600461178c565b610afe565b6102ad6102a8366004611645565b610ba5565b60408051941515855260208501939093529183015215156060820152608001610176565b6101fe6102df3660046116f3565b610c12565b6101fe6102f23660046116f3565b610c63565b6000546001600160a01b03166101c0565b61019f603281565b61025861019f565b6101fe6103263660046116f3565b610d3d565b61019f62093a8081565b6101fe610343366004611645565b610dce565b6101fe6103563660046116f3565b610f0c565b338161039c5760405162461bcd60e51b815260206004820152600b60248201526a16995c9bc8185b5bdd5b9d60aa1b60448201526064015b60405180910390fd5b600254604080516366f1101560e11b815290516000926001600160a01b03169163cde2202a9160048083019260209291908290030181865afa1580156103e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040a9190611808565b90506000610419826064611837565b90508084111561046b5760405162461bcd60e51b815260206004820152601a60248201527f416d6f756e7420657863656564732061737365742076616c75650000000000006044820152606401610393565b61047788888888610f47565b6104b65760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2102d2590383937b7b360811b6044820152606401610393565b843560008181526004602052604090205460ff166105165760405162461bcd60e51b815260206004820152601960248201527f436f6d6d69746d656e74206e6f742072656769737465726564000000000000006044820152606401610393565b60008181526005602052604090205460ff161561056c5760405162461bcd60e51b8152602060048201526014602482015273105cdcd95d08185b1c9958591e481b5a5b9d195960621b6044820152606401610393565b6000818152600560209081526040808320805460ff1990811660011790915560049092528220805490911690556127106105a7603288611837565b6105b19190611864565b905060006105bf8288611886565b905060008b8b8b8b8a8c6040516020016105de96959493929190611899565b60408051808303601f19018152908290528051602090910120600254636a3b5c4d60e01b83526001600160a01b038a8116600485015260248401869052604484018390529193501690636a3b5c4d90606401600060405180830381600087803b15801561064a57600080fd5b505af115801561065e573d6000803e3d6000fd5b505050506000831115610786576002546040805163011a412160e61b815290516000926001600160a01b03169163469048409160048083019260209291908290030181865afa1580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d991906118fa565b600254604051638cc9d10760e01b81526001600160a01b03808416600483015260248201889052929350911690638cc9d10790604401600060405180830381600087803b15801561072957600080fd5b505af115801561073d573d6000803e3d6000fd5b50505050806001600160a01b03167fd2b7c9cdd8f0b876462485c766dac30078e9ef6f76ce1e57ca92c7bd553bcf1f8560405161077c91815260200190565b60405180910390a2505b866001600160a01b0316847f825345861315f1f596fdc2b9bec2cb36452a81888724d69abb25b39f6341f0ca846040516107c291815260200190565b60405180910390a3866001600160a01b03167f0565033f3973b38ac07b3b39f05c0bcfa1449a22d6fd347fdc63c7a8370e106a8260405161080591815260200190565b60405180910390a2505050505050505050505050565b6108236113f0565b60008181526004602052604090205460ff166108725760405162461bcd60e51b815260206004820152600e60248201526d139bdd081c9959da5cdd195c995960921b6044820152606401610393565b60008181526005602052604090205460ff16156108c05760405162461bcd60e51b815260206004820152600c60248201526b105b1c9958591e481d5cd95960a21b6044820152606401610393565b600081815260046020526040808220805460ff191690555182917f99088e6d10d683bcaedea1a362ff6ebb8ab7d7c38f4e8c852e68161ae4cde7d391a250565b6109086113f0565b6002546001600160a01b03161561094f5760405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b6044820152606401610393565b6001600160a01b0381166109755760405162461bcd60e51b815260040161039390611917565b600280546001600160a01b0319166001600160a01b0383169081179091556040517f1df2df20aeec6a569676befc19253674e64c2448304f170b1cf9934cd390f49a90600090a250565b6000546001600160a01b03163314806109e757503360009081526006602052604090205460ff165b610a245760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b6044820152606401610393565b60005b81811015610abb576000838383818110610a4357610a4361184e565b90506020020135905080600014158015610a6c575060008181526004602052604090205460ff16155b15610ab257600081815260046020526040808220805460ff191660011790555182917fcc7b4929606ce963ba54b6a998f106f7748e78c03dc7f08fd77aeb28230eb2d391a25b50600101610a27565b505050565b60405162461bcd60e51b81526020600482015260136024820152722932b737bab731b29037b732b6b7b3b7b1b2b760691b6044820152606401610393565b610b066113f0565b6000838152600160205260408120549003610b535760405162461bcd60e51b815260206004820152600d60248201526c4e69206e61706f766564616e6f60981b6044820152606401610393565b600083815260016020526040808220919091555183907f72003eda7c2c39777210bccbf69141a92bbe56d746914a16f5ee3aaf5e6f7a8390610b98908590859061193d565b60405180910390a2505050565b600081815260016020526040812054819081908190808203610bd557600080600080945094509450945050610c0b565b600181610be562093a808261196c565b834210158015610c015750610bfd62093a808561196c565b4211155b9450945094509450505b9193509193565b610c1a6113f0565b6001600160a01b038116600081815260066020526040808220805460ff19169055517fd84b626bc6cd1f6d62d5e197f48869d2a5ef1a750b360ad929c3de63c88bdfe49190a250565b610c6b6113f0565b6001600160a01b038116610c915760405162461bcd60e51b815260040161039390611917565b610cf181604051602001610ca5919061197f565b60405160208183030381529060405280519060200120604051806040016040528060188152602001775a4b56657269666965722e617574686f72697a65554f525360401b81525061141f565b6001600160a01b038116600081815260066020526040808220805460ff19166001179055517fb334427bfaed9992168ed99fda266e2d7cf5c2ea1a37a1f76e82fd1e307edf7f9190a250565b610d456113f0565b6001600160a01b038116610d6b5760405162461bcd60e51b815260040161039390611917565b610dcb81604051602001610d7f919061197f565b60405160208183030381529060405280519060200120604051806040016040528060188152602001775a4b56657269666965722e617574686f72697a65554f525360401b815250611548565b50565b6000546001600160a01b0316331480610df657503360009081526006602052604090205460ff165b610e335760405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b6044820152606401610393565b80600003610e755760405162461bcd60e51b815260206004820152600f60248201526e16995c9bc818dbdb5b5a5d1b595b9d608a1b6044820152606401610393565b60008181526004602052604090205460ff1615610ec95760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e481c9959da5cdd195c995960721b6044820152606401610393565b600081815260046020526040808220805460ff191660011790555182917fcc7b4929606ce963ba54b6a998f106f7748e78c03dc7f08fd77aeb28230eb2d391a250565b610f146113f0565b6001600160a01b038116610f3e57604051631e4fbdf760e01b815260006004820152602401610393565b610dcb816115f5565b60006113b4565b7f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000018110610dcb5760008052600080fd5b600060405183815284602082015285604082015260408160608360076107d05a03fa915081610fb05760008052600080fd5b825160408201526020830151606082015260408360808360066107d05a03fa91505080610fe05760008052600080fd5b5050505050565b7f0bbf368c7f6fa7f6559bf65da45c33b505a21ff7fb0874c3bd0e2e7baa1b170385527f05c6418bd08aff1241cc2850606a69d8b73a6d9875e25df448f52ae21907c43260208601526000608086018661108487357f181032dd16b7eea417d83a9181ab6887bae84d538a8731a6f3003db177c0caba7f083a4c6477d7d1a1feb5f0ba3ddcd764a617b31c182138d6e756100407c25c8984610f7e565b6110d460208801357f19f2f485618fdb703d11b2fbc13e61ce7371c4f94e99c148b2d2d8e3f1d9a6547f1a5a3f66f163e8eb3a5351b30773f2cf6126755e91973e02ab7bd68d7752583784610f7e565b50823581527f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4760208401357f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4703066020820152833560408201526020840135606082015260408401356080820152606084013560a08201527f2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e260c08201527f14bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d192660e08201527f0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c6101008201527f0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab6101208201527f304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a76101408201527f1739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8610160820152600087015161018082015260206000018701516101a08201527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101c08201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101e08201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6102008201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa610220820152843561024082015260208501356102608201527f10e115799fb9e210b69c6459d325cb70991b1a5f7b23166b9cb1079a84ec05796102808201527f11367b8fccc2b903fc7b4fa13cccc3bd581b6ae5bb74403ff1449df18caeb0616102a08201527f2bc521f6593c958f19d068ab6c9d871471993c59807984ff5540d2ae59f7ad6c6102c08201527f2bf6b0d953792ab8a4e7926e629078462da9a25f808b3d5c13c56b035c14b3f06102e08201526020816103008360086107d05a03fa9051169695505050505050565b60405161038081016040526113cc6000840135610f4e565b6113d96020840135610f4e565b6113e6818486888a610fe7565b9695505050505050565b6000546001600160a01b0316331461141d5760405163118cdaa760e01b8152336004820152602401610393565b565b6000828152600160205260408120549081900361146e5760405162461bcd60e51b815260206004820152600d60248201526c4e69206e61706f766564616e6f60981b6044820152606401610393565b804210156114b45760405162461bcd60e51b815260206004820152601360248201527216985b5a5ac81cd9481b9a481c1bdd195ad95b606a1b6044820152606401610393565b6114c162093a808261196c565b4211156115055760405162461bcd60e51b81526020600482015260126024820152714e61706f766564206a6520706f74656b6c6160701b6044820152606401610393565b600083815260016020526040808220919091555183907ffac4537038ebc9eaa00d86a88a6c2e268012d306f6442966aab36014a195432390610b989085906119fd565b600082815260016020526040902054156115945760405162461bcd60e51b815260206004820152600d60248201526c5a65206e61706f766564616e6f60981b6044820152606401610393565b60006115a26102584261196c565b60008481526001602052604090208190559050827f63a0d065f46e07e30a4f246d28eb53f839982100439173db92dbd5700ab37c1583836115e662093a808261196c565b604051610b9893929190611a10565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561165757600080fd5b5035919050565b806040810183101561166f57600080fd5b92915050565b6000806000806000610160868803121561168e57600080fd5b611698878761165e565b945060c08601878111156116ab57600080fd5b6040870194506116bb888261165e565b9350506116cc87610100880161165e565b94979396509194610140013592915050565b6001600160a01b0381168114610dcb57600080fd5b60006020828403121561170557600080fd5b8135611710816116de565b9392505050565b6000806020838503121561172a57600080fd5b823567ffffffffffffffff8082111561174257600080fd5b818501915085601f83011261175657600080fd5b81358181111561176557600080fd5b8660208260051b850101111561177a57600080fd5b60209290920196919550909350505050565b6000806000604084860312156117a157600080fd5b83359250602084013567ffffffffffffffff808211156117c057600080fd5b818601915086601f8301126117d457600080fd5b8135818111156117e357600080fd5b8760208285010111156117f557600080fd5b6020830194508093505050509250925092565b60006020828403121561181a57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761166f5761166f611821565b634e487b7160e01b600052603260045260246000fd5b60008261188157634e487b7160e01b600052601260045260246000fd5b500490565b8181038181111561166f5761166f611821565b61018081016040808984378083018860005b60028110156118c8578382843791830191908301906001016118ab565b505050808760c08501378086610100850137506001600160a01b03939093166101408201526101600152949350505050565b60006020828403121561190c57600080fd5b8151611710816116de565b6020808252600c908201526b5a65726f206164647265737360a01b604082015260600190565b60208152816020820152818360408301376000818301604090810191909152601f909201601f19160101919050565b8082018082111561166f5761166f611821565b6040808252600d908201526c617574686f72697a65554f525360981b60608201526001600160a01b0391909116602082015260800190565b6000815180845260005b818110156119dd576020818501810151868301820152016119c1565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061171060208301846119b7565b606081526000611a2360608301866119b7565b6020830194909452506040015291905056fea26469706673582212207eae391b69264afbf2b5fb009aee8e6ab759ab4c57a1c06d6212740e3f2b4b9264736f6c63430008180033