{
  "language": "Solidity",
  "sources": {
    "contracts/TierThresholdVerifier.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0\n/*\n    Copyright 2021 0KIMS association.\n\n    This file is generated with [snarkJS](https://github.com/iden3/snarkjs).\n\n    snarkJS is a free software: you can redistribute it and/or modify it\n    under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    snarkJS is distributed in the hope that it will be useful, but WITHOUT\n    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n    or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n    License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with snarkJS. If not, see <https://www.gnu.org/licenses/>.\n*/\n\npragma solidity >=0.7.0 <0.9.0;\n\ncontract Groth16Verifier {\n    // Scalar field size\n    uint256 constant r    = 21888242871839275222246405745257275088548364400416034343698204186575808495617;\n    // Base field size\n    uint256 constant q   = 21888242871839275222246405745257275088696311157297823662689037894645226208583;\n\n    // Verification Key data\n    uint256 constant alphax  = 3243497994152723645556558813518936381141210989414423725054307226767178613010;\n    uint256 constant alphay  = 12567541326061520123866985303557038882920991504645534830340891235839609515702;\n    uint256 constant betax1  = 13523348111945959255520157184150586469301902624568783551543751126495915891585;\n    uint256 constant betax2  = 947946175281386566149615900115630433438850786195586047399440899303719261416;\n    uint256 constant betay1  = 10586833840466903782202837520156432684529478869674987773412186412791198919738;\n    uint256 constant betay2  = 5040565389651241028527108478358702094321414951995545151283218219298793689698;\n    uint256 constant gammax1 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;\n    uint256 constant gammax2 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;\n    uint256 constant gammay1 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;\n    uint256 constant gammay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;\n    uint256 constant deltax1 = 4872800941673624408117103573496572818235254762596890341086629153376159488498;\n    uint256 constant deltax2 = 16544519324436232694436126212752585916013961280896837064928917819105280422149;\n    uint256 constant deltay1 = 20317073423971778448873759976590706916994189114835814126306194597202545852;\n    uint256 constant deltay2 = 3061177124711553686127496674706257528310322527891366735329277257090997937143;\n\n    \n    uint256 constant IC0x = 2405032009872333780392863027948915545659106308940525617902307693580477935742;\n    uint256 constant IC0y = 10950310308727648326779929034369228162877756823666242633197797465213724458760;\n    \n    uint256 constant IC1x = 1406203727501011247168871168171876084219325040148383370886340661843799716714;\n    uint256 constant IC1y = 11883747553578820074334321687269622878265505219062850883700770072963309039231;\n    \n    uint256 constant IC2x = 13998955667150781718907148928384374581934527320570066405638121820887201427193;\n    uint256 constant IC2y = 14659460533627445590147681054909268031090701862853939646357187500236779732002;\n    \n \n    // Memory data\n    uint16 constant pVk = 0;\n    uint16 constant pPairing = 128;\n\n    uint16 constant pLastMem = 896;\n\n    function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[2] calldata _pubSignals) public view returns (bool) {\n        assembly {\n            function checkField(v) {\n                if iszero(lt(v, r)) {\n                    mstore(0, 0)\n                    return(0, 0x20)\n                }\n            }\n            \n            // G1 function to multiply a G1 value(x,y) to value in an address\n            function g1_mulAccC(pR, x, y, s) {\n                let success\n                let mIn := mload(0x40)\n                mstore(mIn, x)\n                mstore(add(mIn, 32), y)\n                mstore(add(mIn, 64), s)\n\n                success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)\n\n                if iszero(success) {\n                    mstore(0, 0)\n                    return(0, 0x20)\n                }\n\n                mstore(add(mIn, 64), mload(pR))\n                mstore(add(mIn, 96), mload(add(pR, 32)))\n\n                success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)\n\n                if iszero(success) {\n                    mstore(0, 0)\n                    return(0, 0x20)\n                }\n            }\n\n            function checkPairing(pA, pB, pC, pubSignals, pMem) -> isOk {\n                let _pPairing := add(pMem, pPairing)\n                let _pVk := add(pMem, pVk)\n\n                mstore(_pVk, IC0x)\n                mstore(add(_pVk, 32), IC0y)\n\n                // Compute the linear combination vk_x\n                \n                g1_mulAccC(_pVk, IC1x, IC1y, calldataload(add(pubSignals, 0)))\n                \n                g1_mulAccC(_pVk, IC2x, IC2y, calldataload(add(pubSignals, 32)))\n                \n\n                // -A\n                mstore(_pPairing, calldataload(pA))\n                mstore(add(_pPairing, 32), mod(sub(q, calldataload(add(pA, 32))), q))\n\n                // B\n                mstore(add(_pPairing, 64), calldataload(pB))\n                mstore(add(_pPairing, 96), calldataload(add(pB, 32)))\n                mstore(add(_pPairing, 128), calldataload(add(pB, 64)))\n                mstore(add(_pPairing, 160), calldataload(add(pB, 96)))\n\n                // alpha1\n                mstore(add(_pPairing, 192), alphax)\n                mstore(add(_pPairing, 224), alphay)\n\n                // beta2\n                mstore(add(_pPairing, 256), betax1)\n                mstore(add(_pPairing, 288), betax2)\n                mstore(add(_pPairing, 320), betay1)\n                mstore(add(_pPairing, 352), betay2)\n\n                // vk_x\n                mstore(add(_pPairing, 384), mload(add(pMem, pVk)))\n                mstore(add(_pPairing, 416), mload(add(pMem, add(pVk, 32))))\n\n\n                // gamma2\n                mstore(add(_pPairing, 448), gammax1)\n                mstore(add(_pPairing, 480), gammax2)\n                mstore(add(_pPairing, 512), gammay1)\n                mstore(add(_pPairing, 544), gammay2)\n\n                // C\n                mstore(add(_pPairing, 576), calldataload(pC))\n                mstore(add(_pPairing, 608), calldataload(add(pC, 32)))\n\n                // delta2\n                mstore(add(_pPairing, 640), deltax1)\n                mstore(add(_pPairing, 672), deltax2)\n                mstore(add(_pPairing, 704), deltay1)\n                mstore(add(_pPairing, 736), deltay2)\n\n\n                let success := staticcall(sub(gas(), 2000), 8, _pPairing, 768, _pPairing, 0x20)\n\n                isOk := and(success, mload(_pPairing))\n            }\n\n            let pMem := mload(0x40)\n            mstore(0x40, add(pMem, pLastMem))\n\n            // Validate that all evaluations \u2208 F\n            \n            checkField(calldataload(add(_pubSignals, 0)))\n            \n            checkField(calldataload(add(_pubSignals, 32)))\n            \n\n            // Validate all evaluations\n            let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)\n\n            mstore(0, isValid)\n             return(0, 0x20)\n         }\n     }\n }\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "viaIR": true,
    "evmVersion": "paris",
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode",
          "evm.deployedBytecode",
          "metadata"
        ]
      }
    }
  }
}
