Address Details
contract
0x55E6Bd7ef032f3D8B2664B21E6EADF2B47A9bf10
- Contract Name
- WithdrawVerifier
- Creator
- 0x25f72e–df3745 at 0x8715b2–57d675
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- 0 Transactions
- Transfers
- 0 Transfers
- Gas Used
- Fetching gas used...
- Last Balance Update
- 24063658
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- WithdrawVerifier
- Optimization enabled
- true
- Compiler version
- v0.8.3+commit.8d00100c
- Optimization runs
- 200
- EVM Version
- istanbul
- Verified at
- 2021-10-20T03:28:02.974609Z
Contract source code
// SPDX-License-Identifier: GPL-3.0 /* Copyright 2021 0KIMS association. This file is generated with [snarkJS](https://github.com/iden3/snarkjs). snarkJS is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. snarkJS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with snarkJS. If not, see <https://www.gnu.org/licenses/>. */ pragma solidity >=0.7.0 <0.9.0; contract WithdrawVerifier { uint32 constant n = 8192; uint16 constant nPublic = 6; uint16 constant nLagrange = 6; uint256 constant Qmx = 9812990417891785149290853635884756604156925564429501791023176706534578654756; uint256 constant Qmy = 21783261496952229773068775145495989642092856536096059569224598705830038301860; uint256 constant Qlx = 4862569108601205547519388150221113650377056086643956065875631706522397703601; uint256 constant Qly = 12315787432543705786329072036255167053267284545546692315456743652579454667888; uint256 constant Qrx = 13346569727173239706080242910175284835144894727041218425529748182362840825680; uint256 constant Qry = 12412014216675284398817932643280922650738672273695597101791421236450379231553; uint256 constant Qox = 15246995584395848292127611626629639780522722553918254829267854394612001503688; uint256 constant Qoy = 4735032615497106247010267919244985892651438700479267612922851925980099754939; uint256 constant Qcx = 13817462705582723216926558160264393636147387531465034262210194411906615810562; uint256 constant Qcy = 11672296671516409346477277497494210250772049820088424582673825053903043378206; uint256 constant S1x = 18010578473107001911194954689672873895600146975978853155759666449922440622615; uint256 constant S1y = 8796436180464952119042498632500744654768422256099751727780243036468042776025; uint256 constant S2x = 10437044351743733960902126064430106837567773777909483816842955823917440584685; uint256 constant S2y = 1053129540443698952758538755518775583043236479776237775249506957724086383752; uint256 constant S3x = 9238726063826290257633503344688672073637924248460056731534547065675800581673; uint256 constant S3y = 8417284805985257806141282660737437020206447364384651342522568107013632925549; uint256 constant k1 = 2; uint256 constant k2 = 3; uint256 constant X2x1 = 21831381940315734285607113342023901060522397560371972897001948545212302161822; uint256 constant X2x2 = 17231025384763736816414546592865244497437017442647097510447326538965263639101; uint256 constant X2y1 = 2388026358213174446665280700919698872609886601280537296205114254867301080648; uint256 constant X2y2 = 11507326595632554467052522095592665270651932854513688777769618397986436103170; uint256 constant q = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 constant qf = 21888242871839275222246405745257275088696311157297823662689037894645226208583; uint256 constant w1 = 197302210312744933010843010704445784068657690384188106020011018676818793232; uint256 constant G1x = 1; uint256 constant G1y = 2; uint256 constant G2x1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 constant G2x2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 constant G2y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; uint256 constant G2y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint16 constant pA = 32; uint16 constant pB = 96; uint16 constant pC = 160; uint16 constant pZ = 224; uint16 constant pT1 = 288; uint16 constant pT2 = 352; uint16 constant pT3 = 416; uint16 constant pWxi = 480; uint16 constant pWxiw = 544; uint16 constant pEval_a = 608; uint16 constant pEval_b = 640; uint16 constant pEval_c = 672; uint16 constant pEval_s1 = 704; uint16 constant pEval_s2 = 736; uint16 constant pEval_zw = 768; uint16 constant pEval_r = 800; uint16 constant pAlpha = 0; uint16 constant pBeta = 32; uint16 constant pGamma = 64; uint16 constant pXi = 96; uint16 constant pXin = 128; uint16 constant pBetaXi = 160; uint16 constant pV1 = 192; uint16 constant pV2 = 224; uint16 constant pV3 = 256; uint16 constant pV4 = 288; uint16 constant pV5 = 320; uint16 constant pV6 = 352; uint16 constant pU = 384; uint16 constant pPl = 416; uint16 constant pEval_t = 448; uint16 constant pA1 = 480; uint16 constant pB1 = 544; uint16 constant pZh = 608; uint16 constant pZhInv = 640; uint16 constant pEval_l1 = 672; uint16 constant pEval_l2 = 704; uint16 constant pEval_l3 = 736; uint16 constant pEval_l4 = 768; uint16 constant pEval_l5 = 800; uint16 constant pEval_l6 = 832; uint16 constant lastMem = 864; function verifyProof(bytes memory proof, uint[] memory pubSignals) external view returns (bool) { assembly { ///////// // Computes the inverse using the extended euclidean algorithm ///////// function inverse(a, q) -> inv { let t := 0 let newt := 1 let r := q let newr := a let quotient let aux for { } newr { } { quotient := sdiv(r, newr) aux := sub(t, mul(quotient, newt)) t:= newt newt:= aux aux := sub(r,mul(quotient, newr)) r := newr newr := aux } if gt(r, 1) { revert(0,0) } if slt(t, 0) { t:= add(t, q) } inv := t } /////// // Computes the inverse of an array of values // See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations ////// function inverseArray(pVals, n) { let pAux := mload(0x40) // Point to the next free position let pIn := pVals let lastPIn := add(pVals, mul(n, 32)) // Read n elemnts let acc := mload(pIn) // Read the first element pIn := add(pIn, 32) // Point to the second element let inv for { } lt(pIn, lastPIn) { pAux := add(pAux, 32) pIn := add(pIn, 32) } { mstore(pAux, acc) acc := mulmod(acc, mload(pIn), q) } acc := inverse(acc, q) // At this point pAux pint to the next free position we substract 1 to point to the last used pAux := sub(pAux, 32) // pIn points to the n+1 element, we substract to point to n pIn := sub(pIn, 32) lastPIn := pVals // We don't process the first element for { } gt(pIn, lastPIn) { pAux := sub(pAux, 32) pIn := sub(pIn, 32) } { inv := mulmod(acc, mload(pAux), q) acc := mulmod(acc, mload(pIn), q) mstore(pIn, inv) } // pIn points to first element, we just set it. mstore(pIn, acc) } function checkField(v) { if iszero(lt(v, q)) { mstore(0, 0) return(0,0x20) } } function checkInput(pProof) { if iszero(eq(mload(pProof), 800 )) { mstore(0, 0) return(0,0x20) } checkField(mload(add(pProof, pEval_a))) checkField(mload(add(pProof, pEval_b))) checkField(mload(add(pProof, pEval_c))) checkField(mload(add(pProof, pEval_s1))) checkField(mload(add(pProof, pEval_s2))) checkField(mload(add(pProof, pEval_zw))) checkField(mload(add(pProof, pEval_r))) // Points are checked in the point operations precompiled smart contracts } function calculateChallanges(pProof, pMem) { let a let b b := mod(keccak256(add(pProof, pA), 192), q) mstore( add(pMem, pBeta), b) mstore( add(pMem, pGamma), mod(keccak256(add(pMem, pBeta), 32), q)) mstore( add(pMem, pAlpha), mod(keccak256(add(pProof, pZ), 64), q)) a := mod(keccak256(add(pProof, pT1), 192), q) mstore( add(pMem, pXi), a) mstore( add(pMem, pBetaXi), mulmod(b, a, q)) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) a:= mulmod(a, a, q) mstore( add(pMem, pXin), a) a:= mod(add(sub(a, 1),q), q) mstore( add(pMem, pZh), a) mstore( add(pMem, pZhInv), a) // We will invert later together with lagrange pols let v1 := mod(keccak256(add(pProof, pEval_a), 224), q) mstore( add(pMem, pV1), v1) a := mulmod(v1, v1, q) mstore( add(pMem, pV2), a) a := mulmod(a, v1, q) mstore( add(pMem, pV3), a) a := mulmod(a, v1, q) mstore( add(pMem, pV4), a) a := mulmod(a, v1, q) mstore( add(pMem, pV5), a) a := mulmod(a, v1, q) mstore( add(pMem, pV6), a) mstore( add(pMem, pU), mod(keccak256(add(pProof, pWxi), 128), q)) } function calculateLagrange(pMem) { let w := 1 mstore( add(pMem, pEval_l1), mulmod( n, mod( add( sub( mload(add(pMem, pXi)), w ), q ), q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l2), mulmod( n, mod( add( sub( mload(add(pMem, pXi)), w ), q ), q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l3), mulmod( n, mod( add( sub( mload(add(pMem, pXi)), w ), q ), q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l4), mulmod( n, mod( add( sub( mload(add(pMem, pXi)), w ), q ), q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l5), mulmod( n, mod( add( sub( mload(add(pMem, pXi)), w ), q ), q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l6), mulmod( n, mod( add( sub( mload(add(pMem, pXi)), w ), q ), q ), q ) ) inverseArray(add(pMem, pZhInv), 7 ) let zh := mload(add(pMem, pZh)) w := 1 mstore( add(pMem, pEval_l1 ), mulmod( mload(add(pMem, pEval_l1 )), zh, q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l2), mulmod( w, mulmod( mload(add(pMem, pEval_l2)), zh, q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l3), mulmod( w, mulmod( mload(add(pMem, pEval_l3)), zh, q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l4), mulmod( w, mulmod( mload(add(pMem, pEval_l4)), zh, q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l5), mulmod( w, mulmod( mload(add(pMem, pEval_l5)), zh, q ), q ) ) w := mulmod(w, w1, q) mstore( add(pMem, pEval_l6), mulmod( w, mulmod( mload(add(pMem, pEval_l6)), zh, q ), q ) ) } function calculatePl(pMem, pPub) { let pl := 0 pl := mod( add( sub( pl, mulmod( mload(add(pMem, pEval_l1)), mload(add(pPub, 32)), q ) ), q ), q ) pl := mod( add( sub( pl, mulmod( mload(add(pMem, pEval_l2)), mload(add(pPub, 64)), q ) ), q ), q ) pl := mod( add( sub( pl, mulmod( mload(add(pMem, pEval_l3)), mload(add(pPub, 96)), q ) ), q ), q ) pl := mod( add( sub( pl, mulmod( mload(add(pMem, pEval_l4)), mload(add(pPub, 128)), q ) ), q ), q ) pl := mod( add( sub( pl, mulmod( mload(add(pMem, pEval_l5)), mload(add(pPub, 160)), q ) ), q ), q ) pl := mod( add( sub( pl, mulmod( mload(add(pMem, pEval_l6)), mload(add(pPub, 192)), q ) ), q ), q ) mstore(add(pMem, pPl), pl) } function calculateT(pProof, pMem) { let t let t1 let t2 t := addmod( mload(add(pProof, pEval_r)), mload(add(pMem, pPl)), q ) t1 := mulmod( mload(add(pProof, pEval_s1)), mload(add(pMem, pBeta)), q ) t1 := addmod( t1, mload(add(pProof, pEval_a)), q ) t1 := addmod( t1, mload(add(pMem, pGamma)), q ) t2 := mulmod( mload(add(pProof, pEval_s2)), mload(add(pMem, pBeta)), q ) t2 := addmod( t2, mload(add(pProof, pEval_b)), q ) t2 := addmod( t2, mload(add(pMem, pGamma)), q ) t1 := mulmod(t1, t2, q) t2 := addmod( mload(add(pProof, pEval_c)), mload(add(pMem, pGamma)), q ) t1 := mulmod(t1, t2, q) t1 := mulmod(t1, mload(add(pProof, pEval_zw)), q) t1 := mulmod(t1, mload(add(pMem, pAlpha)), q) t2 := mulmod( mload(add(pMem, pEval_l1)), mload(add(pMem, pAlpha)), q ) t2 := mulmod( t2, mload(add(pMem, pAlpha)), q ) t1 := addmod(t1, t2, q) t := mod(sub(add(t, q), t1), q) t := mulmod(t, mload(add(pMem, pZhInv)), q) mstore( add(pMem, pEval_t) , t) } function g1_set(pR, pP) { mstore(pR, mload(pP)) mstore(add(pR, 32), mload(add(pP,32))) } function g1_acc(pR, pP) { let mIn := mload(0x40) mstore(mIn, mload(pR)) mstore(add(mIn,32), mload(add(pR, 32))) mstore(add(mIn,64), mload(pP)) mstore(add(mIn,96), mload(add(pP, 32))) let success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64) if iszero(success) { mstore(0, 0) return(0,0x20) } } function g1_mulAcc(pR, pP, s) { let success let mIn := mload(0x40) mstore(mIn, mload(pP)) mstore(add(mIn,32), mload(add(pP, 32))) mstore(add(mIn,64), s) success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64) if iszero(success) { mstore(0, 0) return(0,0x20) } 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) return(0,0x20) } } 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) return(0,0x20) } 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) return(0,0x20) } } function g1_mulSetC(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, pR, 64) if iszero(success) { mstore(0, 0) return(0,0x20) } } function calculateA1(pProof, pMem) { let p := add(pMem, pA1) g1_set(p, add(pProof, pWxi)) g1_mulAcc(p, add(pProof, pWxiw), mload(add(pMem, pU))) } function calculateB1(pProof, pMem) { let s let s1 let p := add(pMem, pB1) // Calculate D s := mulmod( mload(add(pProof, pEval_a)), mload(add(pMem, pV1)), q) g1_mulSetC(p, Qlx, Qly, s) s := mulmod( s, mload(add(pProof, pEval_b)), q) g1_mulAccC(p, Qmx, Qmy, s) s := mulmod( mload(add(pProof, pEval_b)), mload(add(pMem, pV1)), q) g1_mulAccC(p, Qrx, Qry, s) s := mulmod( mload(add(pProof, pEval_c)), mload(add(pMem, pV1)), q) g1_mulAccC(p, Qox, Qoy, s) s :=mload(add(pMem, pV1)) g1_mulAccC(p, Qcx, Qcy, s) s := addmod(mload(add(pProof, pEval_a)), mload(add(pMem, pBetaXi)), q) s := addmod(s, mload(add(pMem, pGamma)), q) s1 := mulmod(k1, mload(add(pMem, pBetaXi)), q) s1 := addmod(s1, mload(add(pProof, pEval_b)), q) s1 := addmod(s1, mload(add(pMem, pGamma)), q) s := mulmod(s, s1, q) s1 := mulmod(k2, mload(add(pMem, pBetaXi)), q) s1 := addmod(s1, mload(add(pProof, pEval_c)), q) s1 := addmod(s1, mload(add(pMem, pGamma)), q) s := mulmod(s, s1, q) s := mulmod(s, mload(add(pMem, pAlpha)), q) s := mulmod(s, mload(add(pMem, pV1)), q) s1 := mulmod(mload(add(pMem, pEval_l1)), mload(add(pMem, pAlpha)), q) s1 := mulmod(s1, mload(add(pMem, pAlpha)), q) s1 := mulmod(s1, mload(add(pMem, pV1)), q) s := addmod(s, s1, q) s := addmod(s, mload(add(pMem, pU)), q) g1_mulAcc(p, add(pProof, pZ), s) s := mulmod(mload(add(pMem, pBeta)), mload(add(pProof, pEval_s1)), q) s := addmod(s, mload(add(pProof, pEval_a)), q) s := addmod(s, mload(add(pMem, pGamma)), q) s1 := mulmod(mload(add(pMem, pBeta)), mload(add(pProof, pEval_s2)), q) s1 := addmod(s1, mload(add(pProof, pEval_b)), q) s1 := addmod(s1, mload(add(pMem, pGamma)), q) s := mulmod(s, s1, q) s := mulmod(s, mload(add(pMem, pAlpha)), q) s := mulmod(s, mload(add(pMem, pV1)), q) s := mulmod(s, mload(add(pMem, pBeta)), q) s := mulmod(s, mload(add(pProof, pEval_zw)), q) s := mod(sub(q, s), q) g1_mulAccC(p, S3x, S3y, s) // calculate F g1_acc(p , add(pProof, pT1)) s := mload(add(pMem, pXin)) g1_mulAcc(p, add(pProof, pT2), s) s := mulmod(s, s, q) g1_mulAcc(p, add(pProof, pT3), s) g1_mulAcc(p, add(pProof, pA), mload(add(pMem, pV2))) g1_mulAcc(p, add(pProof, pB), mload(add(pMem, pV3))) g1_mulAcc(p, add(pProof, pC), mload(add(pMem, pV4))) g1_mulAccC(p, S1x, S1y, mload(add(pMem, pV5))) g1_mulAccC(p, S2x, S2y, mload(add(pMem, pV6))) // calculate E s := mload(add(pMem, pEval_t)) s := addmod(s, mulmod(mload(add(pProof, pEval_r)), mload(add(pMem, pV1)), q), q) s := addmod(s, mulmod(mload(add(pProof, pEval_a)), mload(add(pMem, pV2)), q), q) s := addmod(s, mulmod(mload(add(pProof, pEval_b)), mload(add(pMem, pV3)), q), q) s := addmod(s, mulmod(mload(add(pProof, pEval_c)), mload(add(pMem, pV4)), q), q) s := addmod(s, mulmod(mload(add(pProof, pEval_s1)), mload(add(pMem, pV5)), q), q) s := addmod(s, mulmod(mload(add(pProof, pEval_s2)), mload(add(pMem, pV6)), q), q) s := addmod(s, mulmod(mload(add(pProof, pEval_zw)), mload(add(pMem, pU)), q), q) s := mod(sub(q, s), q) g1_mulAccC(p, G1x, G1y, s) // Last part of B s := mload(add(pMem, pXi)) g1_mulAcc(p, add(pProof, pWxi), s) s := mulmod(mload(add(pMem, pU)), mload(add(pMem, pXi)), q) s := mulmod(s, w1, q) g1_mulAcc(p, add(pProof, pWxiw), s) } function checkPairing(pMem) -> isOk { let mIn := mload(0x40) mstore(mIn, mload(add(pMem, pA1))) mstore(add(mIn,32), mload(add(add(pMem, pA1), 32))) mstore(add(mIn,64), X2x2) mstore(add(mIn,96), X2x1) mstore(add(mIn,128), X2y2) mstore(add(mIn,160), X2y1) mstore(add(mIn,192), mload(add(pMem, pB1))) let s := mload(add(add(pMem, pB1), 32)) s := mod(sub(qf, s), qf) mstore(add(mIn,224), s) mstore(add(mIn,256), G2x2) mstore(add(mIn,288), G2x1) mstore(add(mIn,320), G2y2) mstore(add(mIn,352), G2y1) let success := staticcall(sub(gas(), 2000), 8, mIn, 384, mIn, 0x20) isOk := and(success, mload(mIn)) } let pMem := mload(0x40) mstore(0x40, add(pMem, lastMem)) checkInput(proof) calculateChallanges(proof, pMem) calculateLagrange(pMem) calculatePl(pMem, pubSignals) calculateT(proof, pMem) calculateA1(proof, pMem) calculateB1(proof, pMem) let isValid := checkPairing(pMem) mstore(0x40, sub(pMem, lastMem)) mstore(0, isValid) return(0,0x20) } } }
Contract ABI
[{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"verifyProof","inputs":[{"type":"bytes","name":"proof","internalType":"bytes"},{"type":"uint256[]","name":"pubSignals","internalType":"uint256[]"}]}]
Contract Creation Code
0x608060405234801561001057600080fd5b5061183b806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631e8e1e1314610030575b600080fd5b61004361003e3660046116cf565b610057565b604051901515815260200160405180910390f35b60006115e0565b600080600184846000805b821561008b575092938183058581029091039350909181830290039081610069565b505050600181111561009c57600080fd5b505060008112156100aa5783015b9392505050565b60405181602084028301815160208301925060005b828410156100f7578185526000805160206117c68339815191528451830991506020850194506020840193506100c6565b61010f6000805160206117c68339815191528361005e565b91506020850394506020840393508592505b82841115610166576000805160206117c68339815191528551830990506000805160206117c683398151915284518309818552601f1995860195909401939150610121565b5090915250505050565b6000805160206117c6833981519152811061018f576000805260206000f35b50565b6103208151146101a6576000805260206000f35b6101b4610260820151610170565b6101c2610280820151610170565b6101d06102a0820151610170565b6101de6102c0820151610170565b6101ec6102e0820151610170565b6101fa610300820151610170565b61018f610320820151610170565b6000806000805160206117c683398151915260c060208501200690508060208501526000805160206117c68339815191526020808601200660408501526000805160206117c6833981519152604060e08501200660008501526000805160206117c683398151915260c06101208501200691508160608501526000805160206117c683398151915282820960a0850152506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990508060808401526000805160206117c683398151915280600183030106905080610260840152806102808401526000805160206117c683398151915260e0610260840120068060c08501526000805160206117c683398151915281820991508160e08501526000805160206117c68339815191528183099150816101008501526000805160206117c68339815191528183099150816101208501526000805160206117c68339815191528183099150816101408501526000805160206117c6833981519152818309610160850152505060806101e091909101206000805160206117c6833981519152900661018090910152565b60016000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096102a08301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096102c08301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096102e08301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096103008301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096103208301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c683398151915283606086015103010661200009610340830152610677600761028084016100b1565b610260820151600191506000805160206117c6833981519152816102a0850151096102a08401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c683398151915280826102c08601510983096102c08401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c683398151915280826102e08601510983096102e08401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c683398151915280826103008601510983096103008401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c683398151915280826103208601510983096103208401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c68339815191528082610340860151098309610340840152505050565b60006000805160206117c6833981519152806000805160206117c683398151915260208601516102a0860151098303010690506000805160206117c6833981519152806000805160206117c683398151915260408601516102c0860151098303010690506000805160206117c6833981519152806000805160206117c683398151915260608601516102e0860151098303010690506000805160206117c6833981519152806000805160206117c68339815191526080860151610300860151098303010690506000805160206117c6833981519152806000805160206117c683398151915260a0860151610320860151098303010690506000805160206117c6833981519152806000805160206117c683398151915260c086015161034086015109830301069050806101a0830152505050565b60008060006000805160206117c68339815191526101a08601516103208601510892506000805160206117c683398151915260208601516102c08601510991506000805160206117c6833981519152610260850151830891506000805160206117c68339815191526040860151830891506000805160206117c683398151915260208601516102e08601510990506000805160206117c6833981519152610280850151820890506000805160206117c68339815191526040860151820890506000805160206117c683398151915281830991506000805160206117c683398151915260408601516102a08601510890506000805160206117c683398151915281830991506000805160206117c6833981519152610300850151830991506000805160206117c68339815191526000860151830991506000805160206117c683398151915260008601516102a08701510990506000805160206117c68339815191526000860151820990506000805160206117c68339815191528183089150506000805160206117c6833981519152816000805160206117c6833981519152840103069150506000805160206117c683398151915261028084015182099050806101c0840152505050565b6040518151815260208201516020820152825160408201526020830151606082015260408260808360066107d05a03fa905080610b2c576000805260206000f35b505050565b6000604051835181526020840151602082015284604082015260408160608360076107d05a03fa915081610b69576000805260206000f35b825160408201526020830151606082015260408360808360066107d05a03fa91505080610b9a576000805260206000f35b50505050565b600060405183815284602082015285604082015260408160608360076107d05a03fa915081610bd3576000805260206000f35b825160408201526020830151606082015260408360808360066107d05a03fa91505080610c04576000805260206000f35b5050505050565b600060405183815284602082015285604082015260408360608360076107d05a03fa91505080610c04576000805260206000f35b6101e08201610c5c6101e083018281518152602091820151910152565b610b2c610180840151610220840183610b31565b60008061022084016000805160206117c683398151915260c0860151610260860151099250610ce1837f1b3a7d18f4188ca119d369d1d8be9c235f69bb9ce28f39266e021bc817b2cc707f0ac01dd875295d875318e5463b080e9c5e1f51a342b9faba59c7b7d8533bfdb184610c0b565b6000805160206117c683398151915261028085015184099250610d46837f3028e39b43e930fb20aaff14a85a8843e2db479338d42d1690984a0728836ca47f15b1f4ac25954cd7ffefdd381eed2712796783067e53d79f97220442f6690e2484610ba0565b6000805160206117c683398151915260c0860151610280860151099250610daf837f1b70f37abfc61e9b7d4eb6879d77d24fdf22158e3f7f414cc55eae2d7768f1417f1d81e40939e1600e3b1e0a0673f6ad2f8fd4cd1b9c4e83063e2ca4649b9aff5084610ba0565b6000805160206117c683398151915260c08601516102a0860151099250610e18837f0a77eef902d5c151c65ad12ded8b324255b9bf602ccf59dfb438bb5b626dbbbb7f21b57e6202ee690deadbe4d1c167009146bc5b28812b686d2968b286e1c779c884610ba0565b60c08501519250610e6b837f19ce492a10fd9cc297fade9bf6fc9094bf4a1b5fada98d93ee79774be1173c1e7f1e8c68208b5ec751a2a75fadf90361c33b6820e451ebf87942a9ebdc0bb91a0284610ba0565b6000805160206117c683398151915260a08601516102608601510892506000805160206117c68339815191526040860151840892506000805160206117c683398151915260a086015160020991506000805160206117c6833981519152610280850151830891506000805160206117c68339815191526040860151830891506000805160206117c683398151915282840992506000805160206117c683398151915260a086015160030991506000805160206117c68339815191526102a0850151830891506000805160206117c68339815191526040860151830891506000805160206117c683398151915282840992506000805160206117c68339815191526000860151840992506000805160206117c683398151915260c0860151840992506000805160206117c683398151915260008601516102a08701510991506000805160206117c68339815191526000860151830991506000805160206117c683398151915260c0860151830991506000805160206117c683398151915282840892506000805160206117c6833981519152610180860151840892506110148360e0860183610b31565b6000805160206117c68339815191526102c085015160208701510992506000805160206117c6833981519152610260850151840892506000805160206117c68339815191526040860151840892506000805160206117c68339815191526102e085015160208701510991506000805160206117c6833981519152610280850151830891506000805160206117c68339815191526040860151830891506000805160206117c683398151915282840992506000805160206117c68339815191526000860151840992506000805160206117c683398151915260c0860151840992506000805160206117c68339815191526020860151840992506000805160206117c683398151915261030085015184096000805160206117c6833981519152908103069250611184837f129c03adbe966f898444048c9f7e5447371ab4ce76b5f83cb1d25309cca79f6d7f146cef0367944d5e41e44bd661a3591c4af7cee6f0a6f26f60cb29d9605f162984610ba0565b611192610120850182610aeb565b608085015192506111a883610160860183610b31565b6000805160206117c683398151915283840992506111cb836101a0860183610b31565b6111dd60e08601516020860183610b31565b6111f06101008601516060860183610b31565b61120361012086015160a0860183610b31565b6112546101408601517f13729b3fd8db86682b48543d8f89a42793dcf39763e18087a3a6a5138d37bdd97f27d1a04c7fb5eaaf27d935901a0cf638a31974e855f307b43c461c750104f21784610ba0565b6112a56101608601517f02540cd9b058122bd1d78097f3cc6780573b5cd2984e54ab4f99127307f334887f171328630b7b7738c9f59c6dbc537dcdb8139ee0ade45d1d919ad91ce2c64bed84610ba0565b6101c085015192506000805160206117c68339815191528060c087015161032087015109840892506000805160206117c68339815191528060e087015161026087015109840892506000805160206117c68339815191528061010087015161028087015109840892506000805160206117c6833981519152806101208701516102a087015109840892506000805160206117c6833981519152806101408701516102c087015109840892506000805160206117c6833981519152806101608701516102e087015109840892506000805160206117c6833981519152806101808701516103008701510984086000805160206117c68339815191529081030692506113b3836002600184610ba0565b606085015192506113c9836101e0860183610b31565b6000805160206117c683398151915260608601516101808701510992506000805160206117c68339815191526000805160206117e683398151915284099250610c0483610220860183610b31565b60006040516101e0830151815260206101e08401015160208201527f26186a2d65ee4d2f9c9a5b91f86597d35f192cd120caf7e935d8443d1938e23d60408201527f30441fd1b5d3370482c42152a8899027716989a6996c2535bc9f7fee8aaef79e60608201527f1970ea81dd6992adfbc571effb03503adbbb6a857f578403c6c40e22d65b3c0260808201527f054793348f12c0cf5622c340573cb277586319de359ab9389778f689786b1e4860a082015261022083015160c08201526020610220840101517f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47817f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47030690508060e0830152507f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101008201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101208201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6101408201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6101608201526020816101808360086107d05a03fa90511692915050565b60405161036081016040526115f484610192565b6115fe8185610208565b61160781610490565b61161183826107ed565b61161b8185610921565b6116258185610c3f565b61162f8185610c70565b61163881611417565b610360820360405280600052505060206000f35b600082601f83011261165c578081fd5b8135602067ffffffffffffffff821115611678576116786117af565b8160051b61168782820161177e565b8381528281019086840183880185018910156116a1578687fd5b8693505b858410156116c35780358352600193909301929184019184016116a5565b50979650505050505050565b600080604083850312156116e1578182fd5b823567ffffffffffffffff808211156116f8578384fd5b818501915085601f83011261170b578384fd5b813560208282111561171f5761171f6117af565b611731601f8301601f1916820161177e565b8281528882848701011115611744578687fd5b828286018383013791820181019590955293850135915080821115611767578283fd5b506117748582860161164c565b9150509250929050565b604051601f8201601f1916810167ffffffffffffffff811182821017156117a7576117a76117af565b604052919050565b634e487b7160e01b600052604160045260246000fdfe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001006fab49b869ae62001deac878b2667bd31bf3e28e3a2d764aa49b8d9bbdd310a264697066735822122034afae0fbdd2fa7ba7be76a9ffceb9fdd2b44933d5471d6823b3ba262568477964736f6c63430008030033
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631e8e1e1314610030575b600080fd5b61004361003e3660046116cf565b610057565b604051901515815260200160405180910390f35b60006115e0565b600080600184846000805b821561008b575092938183058581029091039350909181830290039081610069565b505050600181111561009c57600080fd5b505060008112156100aa5783015b9392505050565b60405181602084028301815160208301925060005b828410156100f7578185526000805160206117c68339815191528451830991506020850194506020840193506100c6565b61010f6000805160206117c68339815191528361005e565b91506020850394506020840393508592505b82841115610166576000805160206117c68339815191528551830990506000805160206117c683398151915284518309818552601f1995860195909401939150610121565b5090915250505050565b6000805160206117c6833981519152811061018f576000805260206000f35b50565b6103208151146101a6576000805260206000f35b6101b4610260820151610170565b6101c2610280820151610170565b6101d06102a0820151610170565b6101de6102c0820151610170565b6101ec6102e0820151610170565b6101fa610300820151610170565b61018f610320820151610170565b6000806000805160206117c683398151915260c060208501200690508060208501526000805160206117c68339815191526020808601200660408501526000805160206117c6833981519152604060e08501200660008501526000805160206117c683398151915260c06101208501200691508160608501526000805160206117c683398151915282820960a0850152506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990506000805160206117c683398151915281820990508060808401526000805160206117c683398151915280600183030106905080610260840152806102808401526000805160206117c683398151915260e0610260840120068060c08501526000805160206117c683398151915281820991508160e08501526000805160206117c68339815191528183099150816101008501526000805160206117c68339815191528183099150816101208501526000805160206117c68339815191528183099150816101408501526000805160206117c6833981519152818309610160850152505060806101e091909101206000805160206117c6833981519152900661018090910152565b60016000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096102a08301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096102c08301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096102e08301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096103008301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c6833981519152836060860151030106612000096103208301526000805160206117c68339815191526000805160206117e6833981519152820990506000805160206117c6833981519152806000805160206117c683398151915283606086015103010661200009610340830152610677600761028084016100b1565b610260820151600191506000805160206117c6833981519152816102a0850151096102a08401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c683398151915280826102c08601510983096102c08401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c683398151915280826102e08601510983096102e08401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c683398151915280826103008601510983096103008401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c683398151915280826103208601510983096103208401526000805160206117c68339815191526000805160206117e6833981519152830991506000805160206117c68339815191528082610340860151098309610340840152505050565b60006000805160206117c6833981519152806000805160206117c683398151915260208601516102a0860151098303010690506000805160206117c6833981519152806000805160206117c683398151915260408601516102c0860151098303010690506000805160206117c6833981519152806000805160206117c683398151915260608601516102e0860151098303010690506000805160206117c6833981519152806000805160206117c68339815191526080860151610300860151098303010690506000805160206117c6833981519152806000805160206117c683398151915260a0860151610320860151098303010690506000805160206117c6833981519152806000805160206117c683398151915260c086015161034086015109830301069050806101a0830152505050565b60008060006000805160206117c68339815191526101a08601516103208601510892506000805160206117c683398151915260208601516102c08601510991506000805160206117c6833981519152610260850151830891506000805160206117c68339815191526040860151830891506000805160206117c683398151915260208601516102e08601510990506000805160206117c6833981519152610280850151820890506000805160206117c68339815191526040860151820890506000805160206117c683398151915281830991506000805160206117c683398151915260408601516102a08601510890506000805160206117c683398151915281830991506000805160206117c6833981519152610300850151830991506000805160206117c68339815191526000860151830991506000805160206117c683398151915260008601516102a08701510990506000805160206117c68339815191526000860151820990506000805160206117c68339815191528183089150506000805160206117c6833981519152816000805160206117c6833981519152840103069150506000805160206117c683398151915261028084015182099050806101c0840152505050565b6040518151815260208201516020820152825160408201526020830151606082015260408260808360066107d05a03fa905080610b2c576000805260206000f35b505050565b6000604051835181526020840151602082015284604082015260408160608360076107d05a03fa915081610b69576000805260206000f35b825160408201526020830151606082015260408360808360066107d05a03fa91505080610b9a576000805260206000f35b50505050565b600060405183815284602082015285604082015260408160608360076107d05a03fa915081610bd3576000805260206000f35b825160408201526020830151606082015260408360808360066107d05a03fa91505080610c04576000805260206000f35b5050505050565b600060405183815284602082015285604082015260408360608360076107d05a03fa91505080610c04576000805260206000f35b6101e08201610c5c6101e083018281518152602091820151910152565b610b2c610180840151610220840183610b31565b60008061022084016000805160206117c683398151915260c0860151610260860151099250610ce1837f1b3a7d18f4188ca119d369d1d8be9c235f69bb9ce28f39266e021bc817b2cc707f0ac01dd875295d875318e5463b080e9c5e1f51a342b9faba59c7b7d8533bfdb184610c0b565b6000805160206117c683398151915261028085015184099250610d46837f3028e39b43e930fb20aaff14a85a8843e2db479338d42d1690984a0728836ca47f15b1f4ac25954cd7ffefdd381eed2712796783067e53d79f97220442f6690e2484610ba0565b6000805160206117c683398151915260c0860151610280860151099250610daf837f1b70f37abfc61e9b7d4eb6879d77d24fdf22158e3f7f414cc55eae2d7768f1417f1d81e40939e1600e3b1e0a0673f6ad2f8fd4cd1b9c4e83063e2ca4649b9aff5084610ba0565b6000805160206117c683398151915260c08601516102a0860151099250610e18837f0a77eef902d5c151c65ad12ded8b324255b9bf602ccf59dfb438bb5b626dbbbb7f21b57e6202ee690deadbe4d1c167009146bc5b28812b686d2968b286e1c779c884610ba0565b60c08501519250610e6b837f19ce492a10fd9cc297fade9bf6fc9094bf4a1b5fada98d93ee79774be1173c1e7f1e8c68208b5ec751a2a75fadf90361c33b6820e451ebf87942a9ebdc0bb91a0284610ba0565b6000805160206117c683398151915260a08601516102608601510892506000805160206117c68339815191526040860151840892506000805160206117c683398151915260a086015160020991506000805160206117c6833981519152610280850151830891506000805160206117c68339815191526040860151830891506000805160206117c683398151915282840992506000805160206117c683398151915260a086015160030991506000805160206117c68339815191526102a0850151830891506000805160206117c68339815191526040860151830891506000805160206117c683398151915282840992506000805160206117c68339815191526000860151840992506000805160206117c683398151915260c0860151840992506000805160206117c683398151915260008601516102a08701510991506000805160206117c68339815191526000860151830991506000805160206117c683398151915260c0860151830991506000805160206117c683398151915282840892506000805160206117c6833981519152610180860151840892506110148360e0860183610b31565b6000805160206117c68339815191526102c085015160208701510992506000805160206117c6833981519152610260850151840892506000805160206117c68339815191526040860151840892506000805160206117c68339815191526102e085015160208701510991506000805160206117c6833981519152610280850151830891506000805160206117c68339815191526040860151830891506000805160206117c683398151915282840992506000805160206117c68339815191526000860151840992506000805160206117c683398151915260c0860151840992506000805160206117c68339815191526020860151840992506000805160206117c683398151915261030085015184096000805160206117c6833981519152908103069250611184837f129c03adbe966f898444048c9f7e5447371ab4ce76b5f83cb1d25309cca79f6d7f146cef0367944d5e41e44bd661a3591c4af7cee6f0a6f26f60cb29d9605f162984610ba0565b611192610120850182610aeb565b608085015192506111a883610160860183610b31565b6000805160206117c683398151915283840992506111cb836101a0860183610b31565b6111dd60e08601516020860183610b31565b6111f06101008601516060860183610b31565b61120361012086015160a0860183610b31565b6112546101408601517f13729b3fd8db86682b48543d8f89a42793dcf39763e18087a3a6a5138d37bdd97f27d1a04c7fb5eaaf27d935901a0cf638a31974e855f307b43c461c750104f21784610ba0565b6112a56101608601517f02540cd9b058122bd1d78097f3cc6780573b5cd2984e54ab4f99127307f334887f171328630b7b7738c9f59c6dbc537dcdb8139ee0ade45d1d919ad91ce2c64bed84610ba0565b6101c085015192506000805160206117c68339815191528060c087015161032087015109840892506000805160206117c68339815191528060e087015161026087015109840892506000805160206117c68339815191528061010087015161028087015109840892506000805160206117c6833981519152806101208701516102a087015109840892506000805160206117c6833981519152806101408701516102c087015109840892506000805160206117c6833981519152806101608701516102e087015109840892506000805160206117c6833981519152806101808701516103008701510984086000805160206117c68339815191529081030692506113b3836002600184610ba0565b606085015192506113c9836101e0860183610b31565b6000805160206117c683398151915260608601516101808701510992506000805160206117c68339815191526000805160206117e683398151915284099250610c0483610220860183610b31565b60006040516101e0830151815260206101e08401015160208201527f26186a2d65ee4d2f9c9a5b91f86597d35f192cd120caf7e935d8443d1938e23d60408201527f30441fd1b5d3370482c42152a8899027716989a6996c2535bc9f7fee8aaef79e60608201527f1970ea81dd6992adfbc571effb03503adbbb6a857f578403c6c40e22d65b3c0260808201527f054793348f12c0cf5622c340573cb277586319de359ab9389778f689786b1e4860a082015261022083015160c08201526020610220840101517f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47817f30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47030690508060e0830152507f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c26101008201527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6101208201527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b6101408201527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa6101608201526020816101808360086107d05a03fa90511692915050565b60405161036081016040526115f484610192565b6115fe8185610208565b61160781610490565b61161183826107ed565b61161b8185610921565b6116258185610c3f565b61162f8185610c70565b61163881611417565b610360820360405280600052505060206000f35b600082601f83011261165c578081fd5b8135602067ffffffffffffffff821115611678576116786117af565b8160051b61168782820161177e565b8381528281019086840183880185018910156116a1578687fd5b8693505b858410156116c35780358352600193909301929184019184016116a5565b50979650505050505050565b600080604083850312156116e1578182fd5b823567ffffffffffffffff808211156116f8578384fd5b818501915085601f83011261170b578384fd5b813560208282111561171f5761171f6117af565b611731601f8301601f1916820161177e565b8281528882848701011115611744578687fd5b828286018383013791820181019590955293850135915080821115611767578283fd5b506117748582860161164c565b9150509250929050565b604051601f8201601f1916810167ffffffffffffffff811182821017156117a7576117a76117af565b604052919050565b634e487b7160e01b600052604160045260246000fdfe30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001006fab49b869ae62001deac878b2667bd31bf3e28e3a2d764aa49b8d9bbdd310a264697066735822122034afae0fbdd2fa7ba7be76a9ffceb9fdd2b44933d5471d6823b3ba262568477964736f6c63430008030033