Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0xd06FC0D2...3B916AE01 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
VerifierExit
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.5.0; pragma experimental ABIEncoderV2; import "./KeysWithPlonkSingleVerifier.sol"; // Hardcoded constants to avoid accessing store contract VerifierExit is KeysWithPlonkSingleVerifier { function initialize(bytes calldata) external { } /// @notice VerifierExit contract upgrade. Can be external because Proxy contract intercepts illegal calls of this function. /// @param upgradeParameters Encoded representation of upgrade parameters function upgrade(bytes calldata upgradeParameters) external {} function verifyExitProof( bytes32 _rootHash, uint32 _accountId, address _owner, uint16 _tokenId, uint128 _amount, uint256[] calldata _proof ) external view returns (bool) { bytes32 commitment = sha256(abi.encodePacked(_rootHash, _accountId, _owner, _tokenId, _amount)); uint256[] memory inputs = new uint256[](1); uint256 mask = (~uint256(0)) >> 3; inputs[0] = uint256(commitment) & mask; Proof memory proof = deserialize_proof(inputs, _proof); VerificationKey memory vk = getVkExit(); require(vk.num_inputs == inputs.length); return verify(proof, vk); } function verifyExitNFTProof( bytes32 _rootHash, uint64 _tokenId, uint32 _creatorId, uint32 _seqId, bytes32 _uri, address _owner, uint256[] calldata _proof ) external view returns (bool) { bytes32 commitment = sha256(abi.encodePacked(_rootHash, _tokenId, _creatorId, _seqId, _uri, _owner)); uint256[] memory inputs = new uint256[](1); uint256 mask = (~uint256(0)) >> 3; inputs[0] = uint256(commitment) & mask; Proof memory proof = deserialize_proof(inputs, _proof); VerificationKey memory vk = getVkNFTExit(); require(vk.num_inputs == inputs.length); return verify(proof, vk); } function concatBytes(bytes memory param1, bytes memory param2) public pure returns (bytes memory) { bytes memory merged = new bytes(param1.length + param2.length); uint k = 0; for (uint i = 0; i < param1.length; i++) { merged[k] = param1[i]; k++; } for (uint i = 0; i < param2.length; i++) { merged[k] = param2[i]; k++; } return merged; } function verifyLpExitProof( bytes calldata _account_data, bytes calldata _pair_data0, bytes calldata _pair_data1, uint256[] calldata _proof ) external view returns (bool) { bytes memory _data1 = concatBytes(_account_data, _pair_data0); bytes memory _data2 = concatBytes(_data1, _pair_data1); bytes32 commitment = sha256(_data2); uint256[] memory inputs = new uint256[](1); uint256 mask = (~uint256(0)) >> 3; inputs[0] = uint256(commitment) & mask; Proof memory proof = deserialize_proof(inputs, _proof); VerificationKey memory vk = getVkLpExit(); require(vk.num_inputs == inputs.length); return verify(proof, vk); } }
pragma solidity >=0.5.0 <0.7.0; import "./PlonkSingleCore.sol"; // Hardcoded constants to avoid accessing store contract KeysWithPlonkSingleVerifier is SingleVerifierWithDeserialize { function isBlockSizeSupportedInternal(uint32 _size) internal pure returns (bool) { if (_size == uint32(12)) { return true; } else if (_size == uint32(36)) { return true; } else if (_size == uint32(78)) { return true; } else if (_size == uint32(156)) { return true; } else if (_size == uint32(318)) { return true; } else { return false; } } function getVkExit() internal pure returns(VerificationKey memory vk) { vk.domain_size = 262144; vk.num_inputs = 1; vk.omega = PairingsBn254.new_fr(0x0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe); vk.selector_commitments[0] = PairingsBn254.new_g1( 0x135a8971e309397099f1c5c0b9c2a141e83b888ff0504ba8c9a7c13b8c66873f, 0x0eed3feed06aa8e4d3493aefd4c6f9a6c337e20b7e2f20d22b08b3b4129f8efc ); vk.selector_commitments[1] = PairingsBn254.new_g1( 0x0b97dc8947583759347e13c8f2abdccf1004e13f771fe9c46155af71d336de2e, 0x1d39ffdb681fca7ce01b775e9aaaf5d8b71d9b7602ac00c60bbde91dca816dec ); vk.selector_commitments[2] = PairingsBn254.new_g1( 0x04b4d20919f8c66794a986ad27a0e4e820fb7a1bf863048017a59b1f7b3030f6, 0x2da162d6902e64de2d4f6178f090bf9db7fbb9199d1640d5eab9c0a26869524f ); vk.selector_commitments[3] = PairingsBn254.new_g1( 0x242d28e776c833130fb04fb097c1c166c4293018e64947c46086f1bea2184732, 0x277463020cda47c42366610a37cde00ef3a32b44906e1adee02fcd66bbe44a75 ); vk.selector_commitments[4] = PairingsBn254.new_g1( 0x24d289d00964c5501b4a32521df5685264fb490a4549e794f998f18f169f3195, 0x14307765ce1383efab72009df36fd97d28b94c9c1fce57a64697e5633d8d4e0d ); vk.selector_commitments[5] = PairingsBn254.new_g1( 0x0c3697df5aef9952def7b12d29447e9ae12fe6580f0e00399237bee51a5fa0e0, 0x2b120b7d414a0843aa2e9e606bcec5ff8eb3c38d8b73479de42fc8901bb626e6 ); // we only have access to value of the d(x) witness polynomial on the next // trace step, so we only need one element here and deal with it in other places // by having this in mind vk.next_step_selector_commitments[0] = PairingsBn254.new_g1( 0x0e09a50a8e0635250a3a200dab94a1a51de811b179f61df2d4683e59fd1774ee, 0x251732ea6c2951b7b54f2dbc349b14db2b63def8d132f86499d2e43edc21ad51 ); vk.permutation_commitments[0] = PairingsBn254.new_g1( 0x1889e41a3cebf0b097ec6cef8849e66480c344c422ed9a2e4d63fe75155af0d0, 0x0ed098f479a2f229cd47f645517737f512612915010cb576398cd4ec7c803baf ); vk.permutation_commitments[1] = PairingsBn254.new_g1( 0x141171280664b7aea2c65ddb87f28391cab60913a74f4255b3dd4295d162a02c, 0x033c1cc5f1e58a035eb5f3951e79cc90e9fccf3c82781c2553b1d49694a18991 ); vk.permutation_commitments[2] = PairingsBn254.new_g1( 0x0fc9a25cc839ef11afab0a9f320cf2b7346054f566135611bb25b6cec46205b3, 0x16ea53198b77ab1e469d166b36d89d9fd88b3c356958cdf377a534d73f47a9a3 ); vk.permutation_commitments[3] = PairingsBn254.new_g1( 0x2040345b5f92cc70a9607cf5fc28e5be26f673852450488d4e65f70890649b45, 0x2c0e0bf512b4aa690449b589513e2b34cbc5e748a4217947331e0350c73be310 ); vk.permutation_non_residues[0] = PairingsBn254.new_fr( 0x0000000000000000000000000000000000000000000000000000000000000005 ); vk.permutation_non_residues[1] = PairingsBn254.new_fr( 0x0000000000000000000000000000000000000000000000000000000000000007 ); vk.permutation_non_residues[2] = PairingsBn254.new_fr( 0x000000000000000000000000000000000000000000000000000000000000000a ); vk.g2_x = PairingsBn254.new_g2( [0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1, 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0], [0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4, 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55] ); } function getVkLpExit() internal pure returns(VerificationKey memory vk) { vk.domain_size = 524288; vk.num_inputs = 1; vk.omega = PairingsBn254.new_fr(0x0cf1526aaafac6bacbb67d11a4077806b123f767e4b0883d14cc0193568fc082); vk.selector_commitments[0] = PairingsBn254.new_g1( 0x26aafba448a6c22abfa5286eef01b17a6bffaacf20a8a0fca1a59035c8e45ddd, 0x160835d2c20ea81f2f4c2c7f1644e30ae41b2541588a27552c08c190d5b32af8 ); vk.selector_commitments[1] = PairingsBn254.new_g1( 0x20954e6cd2ad660dd9723263311b03986d6f8993ebfeb67a60a46608b35701fe, 0x059ce6f6469bb72b8758473f86e86a959c4b9f74193d931dd172883c641a25c7 ); vk.selector_commitments[2] = PairingsBn254.new_g1( 0x26245ff891a4328caa0da951efba1b5b3cc13136cd315ac7c8794053e47a4315, 0x1681b7685491b5f8fb470a21a326bc91bd75178d411ead030aefcddd9b51bd06 ); vk.selector_commitments[3] = PairingsBn254.new_g1( 0x2857e4543592da2693e7e97477f186736c4a0a325bd9477bbd996819dc0ca4ce, 0x0ffe00e34dd8592675469bb7a92b1e78e7c9e4ace22343605fb3a48dd4f15970 ); vk.selector_commitments[4] = PairingsBn254.new_g1( 0x0180059910e776f202efcb1b96d72ab597e811caef2a9af5d8b42fc79949d913, 0x1a43d65fba7b7340f6cb120a31ad0a1d5a26e0a1151398d9a80d6930e623be21 ); vk.selector_commitments[5] = PairingsBn254.new_g1( 0x007b755d547d62eaf1375f3efe8a62ef52ed1b40ef2ec0943ab9a1de7198f274, 0x28f96cb876dc97aada23aa73d202682e3f29a29126d5711df0747234660cd83d ); // we only have access to value of the d(x) witness polynomial on the next // trace step, so we only need one element here and deal with it in other places // by having this in mind vk.next_step_selector_commitments[0] = PairingsBn254.new_g1( 0x00dfc41dc088a145be5a6978121abea7dffaef90012b9d6f1b577e957a28dd24, 0x2ef1b64e6b0afe751b5531869a17dd9d5c90d734880de7fed3d3ae74a01d989a ); vk.permutation_commitments[0] = PairingsBn254.new_g1( 0x1d69be00b5e7d9d2af9d10da25eda41333effe6b9435caefe07ddae096d30ddf, 0x162137b0ead7f1be6f448f36db186c5bee0e44f19a926e88b53f7760b64e9dbd ); vk.permutation_commitments[1] = PairingsBn254.new_g1( 0x179c8e2df764ec8a2a5f5dbd37ffdde057178b6c10ef04bbb3331a7843934331, 0x1a71e27ade54b801c811bd10d93c2b9e6c80bfea3d808487cf375f50e065e896 ); vk.permutation_commitments[2] = PairingsBn254.new_g1( 0x2fc48aa7bcba72e922843e8732398afe655368a3aedca1f204b0e1bd9ddbf981, 0x2f6adc4261e3dd2fc80affdb39de386de5c38aa0066a8560f76dff220341071a ); vk.permutation_commitments[3] = PairingsBn254.new_g1( 0x2a096bb764588fb3f422291918e33c1d8d9f5a8ef6c9cf41d288a5ddea0cf26a, 0x1e2ab7435be44f4101b1af83f76d5b621f4ecdd9d673a4b019ffb41072413f9b ); vk.permutation_non_residues[0] = PairingsBn254.new_fr( 0x0000000000000000000000000000000000000000000000000000000000000005 ); vk.permutation_non_residues[1] = PairingsBn254.new_fr( 0x0000000000000000000000000000000000000000000000000000000000000007 ); vk.permutation_non_residues[2] = PairingsBn254.new_fr( 0x000000000000000000000000000000000000000000000000000000000000000a ); vk.g2_x = PairingsBn254.new_g2( [0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1, 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0], [0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4, 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55] ); } function getVkNFTExit() internal pure returns(VerificationKey memory vk) { vk.domain_size = 262144; vk.num_inputs = 1; vk.omega = PairingsBn254.new_fr(0x0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe); vk.selector_commitments[0] = PairingsBn254.new_g1( 0x27ad08e12b6087f6fe0d7e1d8d8f14f53e92aaabf05e4f7d1051b0fbe3db046d, 0x11f1f49ccf9f433366c3dc71fe9efa794678b87cbb2b07deea0cfbb7093e5369 ); vk.selector_commitments[1] = PairingsBn254.new_g1( 0x1ee701b0be61332b7de5d4260ad352a3f50a8e51ac4a761f6ab5077c8dffab51, 0x21451115294a50d06c5c442e9a61b04699fd8f296e70ef00e78a5908ef541444 ); vk.selector_commitments[2] = PairingsBn254.new_g1( 0x1eccd5e119cc4a7bc8d274e0d8f61a054ee38694796790dacd22a098642bf2bc, 0x10bb95ce678a633560f0a704001e4c148aff47b7aee0856bfec735fb13884e02 ); vk.selector_commitments[3] = PairingsBn254.new_g1( 0x013fa8820794811964f35f04adb7600a9a3c76c9960b9cbb162b8324e09a14f5, 0x0c110889cdf3554c95c7876f3e9d64804b3f0a6effa2baaf8bcb4ca847e5ed1d ); vk.selector_commitments[4] = PairingsBn254.new_g1( 0x1d5d922608eb262a5b05dc872b81238a352ba3521a1e847b06606d0937c7a34c, 0x291cd60f7f242bd5e1075f99ed70583f40460758aa58c8cd418cb5b6929e8c12 ); vk.selector_commitments[5] = PairingsBn254.new_g1( 0x2bc438c9650f27fd6b4125e098c5d87f874cfd29efad4a3e4ecae04e23b05009, 0x283af270ef1c1c897e85b844536745dbf4d744f2e0fe8dc113143b5209a60baa ); // we only have access to value of the d(x) witness polynomial on the next // trace step, so we only need one element here and deal with it in other places // by having this in mind vk.next_step_selector_commitments[0] = PairingsBn254.new_g1( 0x16f50151d8dccdd5e06a29eee62a9f614d534c542640bee31e9e9a3f2b708a83, 0x120854cacf85957ca9777576bda620a21312769ab9596c7c64dc742156839882 ); vk.permutation_commitments[0] = PairingsBn254.new_g1( 0x27d2cd3c7a778fed777f6410fca3a65521282818e187e901827b1e666281d38b, 0x1f5484c3976cadaea11704759c33ecfffe4900b696febcffb397ec15324c484a ); vk.permutation_commitments[1] = PairingsBn254.new_g1( 0x26a13c2a6968f979cfc4ef24b965487c5f22f2dfc5e9008942fa32bbb72f7b3c, 0x2bbb803702a9e0c0d4e3a078e2ffa2c525165f940a551555efbdd8876cc3f06e ); vk.permutation_commitments[2] = PairingsBn254.new_g1( 0x17210a663b894d0d08db4ba0f2da65bf67b5e4c94317d03e0eb6077b11e849ef, 0x2c98fb45631bd244290296ce55afc885e0e3cc96b506037183338141e97fdf61 ); vk.permutation_commitments[3] = PairingsBn254.new_g1( 0x1ef739c21d81d82ecb30445c5c6e775597aed256ee615b84c71dff243c81dd9e, 0x072138b9876fc2f52d29b5cf35478fe4091f384c034fa59ab4b29deb69e98281 ); vk.permutation_non_residues[0] = PairingsBn254.new_fr( 0x0000000000000000000000000000000000000000000000000000000000000005 ); vk.permutation_non_residues[1] = PairingsBn254.new_fr( 0x0000000000000000000000000000000000000000000000000000000000000007 ); vk.permutation_non_residues[2] = PairingsBn254.new_fr( 0x000000000000000000000000000000000000000000000000000000000000000a ); vk.g2_x = PairingsBn254.new_g2( [0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1, 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0], [0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4, 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55] ); } }
pragma solidity >=0.5.0 <0.7.0; import "./PlonkCoreLib.sol"; contract Plonk4SingleVerifierWithAccessToDNext { using PairingsBn254 for PairingsBn254.G1Point; using PairingsBn254 for PairingsBn254.G2Point; using PairingsBn254 for PairingsBn254.Fr; using TranscriptLibrary for TranscriptLibrary.Transcript; uint256 constant STATE_WIDTH = 4; uint256 constant ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP = 1; struct VerificationKey { uint256 domain_size; uint256 num_inputs; PairingsBn254.Fr omega; PairingsBn254.G1Point[STATE_WIDTH+2] selector_commitments; // STATE_WIDTH for witness + multiplication + constant PairingsBn254.G1Point[ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP] next_step_selector_commitments; PairingsBn254.G1Point[STATE_WIDTH] permutation_commitments; PairingsBn254.Fr[STATE_WIDTH-1] permutation_non_residues; PairingsBn254.G2Point g2_x; } struct Proof { uint256[] input_values; PairingsBn254.G1Point[STATE_WIDTH] wire_commitments; PairingsBn254.G1Point grand_product_commitment; PairingsBn254.G1Point[STATE_WIDTH] quotient_poly_commitments; PairingsBn254.Fr[STATE_WIDTH] wire_values_at_z; PairingsBn254.Fr[ACCESSIBLE_STATE_POLYS_ON_NEXT_STEP] wire_values_at_z_omega; PairingsBn254.Fr grand_product_at_z_omega; PairingsBn254.Fr quotient_polynomial_at_z; PairingsBn254.Fr linearization_polynomial_at_z; PairingsBn254.Fr[STATE_WIDTH-1] permutation_polynomials_at_z; PairingsBn254.G1Point opening_at_z_proof; PairingsBn254.G1Point opening_at_z_omega_proof; } struct PartialVerifierState { PairingsBn254.Fr alpha; PairingsBn254.Fr beta; PairingsBn254.Fr gamma; PairingsBn254.Fr v; PairingsBn254.Fr u; PairingsBn254.Fr z; PairingsBn254.Fr[] cached_lagrange_evals; } function evaluate_lagrange_poly_out_of_domain( uint256 poly_num, uint256 domain_size, PairingsBn254.Fr memory omega, PairingsBn254.Fr memory at ) internal view returns (PairingsBn254.Fr memory res) { require(poly_num < domain_size); PairingsBn254.Fr memory one = PairingsBn254.new_fr(1); PairingsBn254.Fr memory omega_power = omega.pow(poly_num); res = at.pow(domain_size); res.sub_assign(one); require(res.value != 0); // Vanishing polynomial can not be zero at point `at` res.mul_assign(omega_power); PairingsBn254.Fr memory den = PairingsBn254.copy(at); den.sub_assign(omega_power); den.mul_assign(PairingsBn254.new_fr(domain_size)); den = den.inverse(); res.mul_assign(den); } function evaluate_vanishing( uint256 domain_size, PairingsBn254.Fr memory at ) internal view returns (PairingsBn254.Fr memory res) { res = at.pow(domain_size); res.sub_assign(PairingsBn254.new_fr(1)); } function verify_at_z( PartialVerifierState memory state, Proof memory proof, VerificationKey memory vk ) internal view returns (bool) { PairingsBn254.Fr memory lhs = evaluate_vanishing(vk.domain_size, state.z); require(lhs.value != 0); // we can not check a polynomial relationship if point `z` is in the domain lhs.mul_assign(proof.quotient_polynomial_at_z); PairingsBn254.Fr memory quotient_challenge = PairingsBn254.new_fr(1); PairingsBn254.Fr memory rhs = PairingsBn254.copy(proof.linearization_polynomial_at_z); // public inputs PairingsBn254.Fr memory tmp = PairingsBn254.new_fr(0); for (uint256 i = 0; i < proof.input_values.length; i++) { tmp.assign(state.cached_lagrange_evals[i]); tmp.mul_assign(PairingsBn254.new_fr(proof.input_values[i])); rhs.add_assign(tmp); } quotient_challenge.mul_assign(state.alpha); PairingsBn254.Fr memory z_part = PairingsBn254.copy(proof.grand_product_at_z_omega); for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { tmp.assign(proof.permutation_polynomials_at_z[i]); tmp.mul_assign(state.beta); tmp.add_assign(state.gamma); tmp.add_assign(proof.wire_values_at_z[i]); z_part.mul_assign(tmp); } tmp.assign(state.gamma); // we need a wire value of the last polynomial in enumeration tmp.add_assign(proof.wire_values_at_z[STATE_WIDTH - 1]); z_part.mul_assign(tmp); z_part.mul_assign(quotient_challenge); rhs.sub_assign(z_part); quotient_challenge.mul_assign(state.alpha); tmp.assign(state.cached_lagrange_evals[0]); tmp.mul_assign(quotient_challenge); rhs.sub_assign(tmp); return lhs.value == rhs.value; } function reconstruct_d( PartialVerifierState memory state, Proof memory proof, VerificationKey memory vk ) internal view returns (PairingsBn254.G1Point memory res) { // we compute what power of v is used as a delinearization factor in batch opening of // commitments. Let's label W(x) = 1 / (x - z) * // [ // t_0(x) + z^n * t_1(x) + z^2n * t_2(x) + z^3n * t_3(x) - t(z) // + v (r(x) - r(z)) // + v^{2..5} * (witness(x) - witness(z)) // + v^(6..8) * (permutation(x) - permutation(z)) // ] // W'(x) = 1 / (x - z*omega) * // [ // + v^9 (z(x) - z(z*omega)) <- we need this power // + v^10 * (d(x) - d(z*omega)) // ] // // we pay a little for a few arithmetic operations to not introduce another constant uint256 power_for_z_omega_opening = 1 + 1 + STATE_WIDTH + STATE_WIDTH - 1; res = PairingsBn254.copy_g1(vk.selector_commitments[STATE_WIDTH + 1]); PairingsBn254.G1Point memory tmp_g1 = PairingsBn254.P1(); PairingsBn254.Fr memory tmp_fr = PairingsBn254.new_fr(0); // addition gates for (uint256 i = 0; i < STATE_WIDTH; i++) { tmp_g1 = vk.selector_commitments[i].point_mul(proof.wire_values_at_z[i]); res.point_add_assign(tmp_g1); } // multiplication gate tmp_fr.assign(proof.wire_values_at_z[0]); tmp_fr.mul_assign(proof.wire_values_at_z[1]); tmp_g1 = vk.selector_commitments[STATE_WIDTH].point_mul(tmp_fr); res.point_add_assign(tmp_g1); // d_next tmp_g1 = vk.next_step_selector_commitments[0].point_mul(proof.wire_values_at_z_omega[0]); res.point_add_assign(tmp_g1); // z * non_res * beta + gamma + a PairingsBn254.Fr memory grand_product_part_at_z = PairingsBn254.copy(state.z); grand_product_part_at_z.mul_assign(state.beta); grand_product_part_at_z.add_assign(proof.wire_values_at_z[0]); grand_product_part_at_z.add_assign(state.gamma); for (uint256 i = 0; i < vk.permutation_non_residues.length; i++) { tmp_fr.assign(state.z); tmp_fr.mul_assign(vk.permutation_non_residues[i]); tmp_fr.mul_assign(state.beta); tmp_fr.add_assign(state.gamma); tmp_fr.add_assign(proof.wire_values_at_z[i+1]); grand_product_part_at_z.mul_assign(tmp_fr); } grand_product_part_at_z.mul_assign(state.alpha); tmp_fr.assign(state.cached_lagrange_evals[0]); tmp_fr.mul_assign(state.alpha); tmp_fr.mul_assign(state.alpha); grand_product_part_at_z.add_assign(tmp_fr); PairingsBn254.Fr memory grand_product_part_at_z_omega = state.v.pow(power_for_z_omega_opening); grand_product_part_at_z_omega.mul_assign(state.u); PairingsBn254.Fr memory last_permutation_part_at_z = PairingsBn254.new_fr(1); for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { tmp_fr.assign(state.beta); tmp_fr.mul_assign(proof.permutation_polynomials_at_z[i]); tmp_fr.add_assign(state.gamma); tmp_fr.add_assign(proof.wire_values_at_z[i]); last_permutation_part_at_z.mul_assign(tmp_fr); } last_permutation_part_at_z.mul_assign(state.beta); last_permutation_part_at_z.mul_assign(proof.grand_product_at_z_omega); last_permutation_part_at_z.mul_assign(state.alpha); // add to the linearization tmp_g1 = proof.grand_product_commitment.point_mul(grand_product_part_at_z); tmp_g1.point_sub_assign(vk.permutation_commitments[STATE_WIDTH - 1].point_mul(last_permutation_part_at_z)); res.point_add_assign(tmp_g1); res.point_mul_assign(state.v); res.point_add_assign(proof.grand_product_commitment.point_mul(grand_product_part_at_z_omega)); } function verify_commitments( PartialVerifierState memory state, Proof memory proof, VerificationKey memory vk ) internal view returns (bool) { PairingsBn254.G1Point memory d = reconstruct_d(state, proof, vk); PairingsBn254.Fr memory z_in_domain_size = state.z.pow(vk.domain_size); PairingsBn254.G1Point memory tmp_g1 = PairingsBn254.P1(); PairingsBn254.Fr memory aggregation_challenge = PairingsBn254.new_fr(1); PairingsBn254.G1Point memory commitment_aggregation = PairingsBn254.copy_g1(proof.quotient_poly_commitments[0]); PairingsBn254.Fr memory tmp_fr = PairingsBn254.new_fr(1); for (uint i = 1; i < proof.quotient_poly_commitments.length; i++) { tmp_fr.mul_assign(z_in_domain_size); tmp_g1 = proof.quotient_poly_commitments[i].point_mul(tmp_fr); commitment_aggregation.point_add_assign(tmp_g1); } aggregation_challenge.mul_assign(state.v); commitment_aggregation.point_add_assign(d); for (uint i = 0; i < proof.wire_commitments.length; i++) { aggregation_challenge.mul_assign(state.v); tmp_g1 = proof.wire_commitments[i].point_mul(aggregation_challenge); commitment_aggregation.point_add_assign(tmp_g1); } for (uint i = 0; i < vk.permutation_commitments.length - 1; i++) { aggregation_challenge.mul_assign(state.v); tmp_g1 = vk.permutation_commitments[i].point_mul(aggregation_challenge); commitment_aggregation.point_add_assign(tmp_g1); } aggregation_challenge.mul_assign(state.v); aggregation_challenge.mul_assign(state.v); tmp_fr.assign(aggregation_challenge); tmp_fr.mul_assign(state.u); tmp_g1 = proof.wire_commitments[STATE_WIDTH - 1].point_mul(tmp_fr); commitment_aggregation.point_add_assign(tmp_g1); // collect opening values aggregation_challenge = PairingsBn254.new_fr(1); PairingsBn254.Fr memory aggregated_value = PairingsBn254.copy(proof.quotient_polynomial_at_z); aggregation_challenge.mul_assign(state.v); tmp_fr.assign(proof.linearization_polynomial_at_z); tmp_fr.mul_assign(aggregation_challenge); aggregated_value.add_assign(tmp_fr); for (uint i = 0; i < proof.wire_values_at_z.length; i++) { aggregation_challenge.mul_assign(state.v); tmp_fr.assign(proof.wire_values_at_z[i]); tmp_fr.mul_assign(aggregation_challenge); aggregated_value.add_assign(tmp_fr); } for (uint i = 0; i < proof.permutation_polynomials_at_z.length; i++) { aggregation_challenge.mul_assign(state.v); tmp_fr.assign(proof.permutation_polynomials_at_z[i]); tmp_fr.mul_assign(aggregation_challenge); aggregated_value.add_assign(tmp_fr); } aggregation_challenge.mul_assign(state.v); tmp_fr.assign(proof.grand_product_at_z_omega); tmp_fr.mul_assign(aggregation_challenge); tmp_fr.mul_assign(state.u); aggregated_value.add_assign(tmp_fr); aggregation_challenge.mul_assign(state.v); tmp_fr.assign(proof.wire_values_at_z_omega[0]); tmp_fr.mul_assign(aggregation_challenge); tmp_fr.mul_assign(state.u); aggregated_value.add_assign(tmp_fr); commitment_aggregation.point_sub_assign(PairingsBn254.P1().point_mul(aggregated_value)); PairingsBn254.G1Point memory pair_with_generator = commitment_aggregation; pair_with_generator.point_add_assign(proof.opening_at_z_proof.point_mul(state.z)); tmp_fr.assign(state.z); tmp_fr.mul_assign(vk.omega); tmp_fr.mul_assign(state.u); pair_with_generator.point_add_assign(proof.opening_at_z_omega_proof.point_mul(tmp_fr)); PairingsBn254.G1Point memory pair_with_x = proof.opening_at_z_omega_proof.point_mul(state.u); pair_with_x.point_add_assign(proof.opening_at_z_proof); pair_with_x.negate(); return PairingsBn254.pairingProd2(pair_with_generator, PairingsBn254.P2(), pair_with_x, vk.g2_x); } function verify_initial( PartialVerifierState memory state, Proof memory proof, VerificationKey memory vk ) internal view returns (bool) { require(proof.input_values.length == vk.num_inputs); require(vk.num_inputs == 1); TranscriptLibrary.Transcript memory transcript = TranscriptLibrary.new_transcript(); for (uint256 i = 0; i < vk.num_inputs; i++) { transcript.update_with_u256(proof.input_values[i]); } for (uint256 i = 0; i < proof.wire_commitments.length; i++) { transcript.update_with_g1(proof.wire_commitments[i]); } state.beta = transcript.get_challenge(); state.gamma = transcript.get_challenge(); transcript.update_with_g1(proof.grand_product_commitment); state.alpha = transcript.get_challenge(); for (uint256 i = 0; i < proof.quotient_poly_commitments.length; i++) { transcript.update_with_g1(proof.quotient_poly_commitments[i]); } state.z = transcript.get_challenge(); state.cached_lagrange_evals = new PairingsBn254.Fr[](1); state.cached_lagrange_evals[0] = evaluate_lagrange_poly_out_of_domain( 0, vk.domain_size, vk.omega, state.z ); bool valid = verify_at_z(state, proof, vk); if (valid == false) { return false; } for (uint256 i = 0; i < proof.wire_values_at_z.length; i++) { transcript.update_with_fr(proof.wire_values_at_z[i]); } for (uint256 i = 0; i < proof.wire_values_at_z_omega.length; i++) { transcript.update_with_fr(proof.wire_values_at_z_omega[i]); } for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { transcript.update_with_fr(proof.permutation_polynomials_at_z[i]); } transcript.update_with_fr(proof.quotient_polynomial_at_z); transcript.update_with_fr(proof.linearization_polynomial_at_z); transcript.update_with_fr(proof.grand_product_at_z_omega); state.v = transcript.get_challenge(); transcript.update_with_g1(proof.opening_at_z_proof); transcript.update_with_g1(proof.opening_at_z_omega_proof); state.u = transcript.get_challenge(); return true; } // This verifier is for a PLONK with a state width 4 // and main gate equation // q_a(X) * a(X) + // q_b(X) * b(X) + // q_c(X) * c(X) + // q_d(X) * d(X) + // q_m(X) * a(X) * b(X) + // q_constants(X)+ // q_d_next(X) * d(X*omega) // where q_{}(X) are selectors a, b, c, d - state (witness) polynomials // q_d_next(X) "peeks" into the next row of the trace, so it takes // the same d(X) polynomial, but shifted function verify(Proof memory proof, VerificationKey memory vk) internal view returns (bool) { PartialVerifierState memory state; bool valid = verify_initial(state, proof, vk); if (valid == false) { return false; } valid = verify_commitments(state, proof, vk); return valid; } } contract SingleVerifierWithDeserialize is Plonk4SingleVerifierWithAccessToDNext { uint256 constant SERIALIZED_PROOF_LENGTH = 33; function deserialize_proof( uint256[] memory public_inputs, uint256[] memory serialized_proof ) internal pure returns(Proof memory proof) { require(serialized_proof.length == SERIALIZED_PROOF_LENGTH); proof.input_values = new uint256[](public_inputs.length); for (uint256 i = 0; i < public_inputs.length; i++) { proof.input_values[i] = public_inputs[i]; } uint256 j = 0; for (uint256 i = 0; i < STATE_WIDTH; i++) { proof.wire_commitments[i] = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j+1] ); j += 2; } proof.grand_product_commitment = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j+1] ); j += 2; for (uint256 i = 0; i < STATE_WIDTH; i++) { proof.quotient_poly_commitments[i] = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j+1] ); j += 2; } for (uint256 i = 0; i < STATE_WIDTH; i++) { proof.wire_values_at_z[i] = PairingsBn254.new_fr( serialized_proof[j] ); j += 1; } for (uint256 i = 0; i < proof.wire_values_at_z_omega.length; i++) { proof.wire_values_at_z_omega[i] = PairingsBn254.new_fr( serialized_proof[j] ); j += 1; } proof.grand_product_at_z_omega = PairingsBn254.new_fr( serialized_proof[j] ); j += 1; proof.quotient_polynomial_at_z = PairingsBn254.new_fr( serialized_proof[j] ); j += 1; proof.linearization_polynomial_at_z = PairingsBn254.new_fr( serialized_proof[j] ); j += 1; for (uint256 i = 0; i < proof.permutation_polynomials_at_z.length; i++) { proof.permutation_polynomials_at_z[i] = PairingsBn254.new_fr( serialized_proof[j] ); j += 1; } proof.opening_at_z_proof = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j+1] ); j += 2; proof.opening_at_z_omega_proof = PairingsBn254.new_g1_checked( serialized_proof[j], serialized_proof[j+1] ); } }
pragma solidity >=0.5.0 <0.7.0; library PairingsBn254 { uint256 constant q_mod = 21888242871839275222246405745257275088696311157297823662689037894645226208583; uint256 constant r_mod = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 constant bn254_b_coeff = 3; struct G1Point { uint256 X; uint256 Y; } struct Fr { uint256 value; } function new_fr(uint256 fr) internal pure returns (Fr memory) { require(fr < r_mod); return Fr({value: fr}); } function copy(Fr memory self) internal pure returns (Fr memory n) { n.value = self.value; } function assign(Fr memory self, Fr memory other) internal pure { self.value = other.value; } function inverse(Fr memory fr) internal view returns (Fr memory) { require(fr.value != 0); return pow(fr, r_mod-2); } function add_assign(Fr memory self, Fr memory other) internal pure { self.value = addmod(self.value, other.value, r_mod); } function sub_assign(Fr memory self, Fr memory other) internal pure { self.value = addmod(self.value, r_mod - other.value, r_mod); } function mul_assign(Fr memory self, Fr memory other) internal pure { self.value = mulmod(self.value, other.value, r_mod); } function pow(Fr memory self, uint256 power) internal view returns (Fr memory) { uint256[6] memory input = [32, 32, 32, self.value, power, r_mod]; uint256[1] memory result; bool success; assembly { success := staticcall(gas(), 0x05, input, 0xc0, result, 0x20) } require(success); return Fr({value: result[0]}); } // Encoding of field elements is: X[0] * z + X[1] struct G2Point { uint[2] X; uint[2] Y; } function P1() internal pure returns (G1Point memory) { return G1Point(1, 2); } function new_g1(uint256 x, uint256 y) internal pure returns (G1Point memory) { return G1Point(x, y); } function new_g1_checked(uint256 x, uint256 y) internal pure returns (G1Point memory) { if (x == 0 && y == 0) { // point of infinity is (0,0) return G1Point(x, y); } // check encoding require(x < q_mod); require(y < q_mod); // check on curve uint256 lhs = mulmod(y, y, q_mod); // y^2 uint256 rhs = mulmod(x, x, q_mod); // x^2 rhs = mulmod(rhs, x, q_mod); // x^3 rhs = addmod(rhs, bn254_b_coeff, q_mod); // x^3 + b require(lhs == rhs); return G1Point(x, y); } function new_g2(uint256[2] memory x, uint256[2] memory y) internal pure returns (G2Point memory) { return G2Point(x, y); } function copy_g1(G1Point memory self) internal pure returns (G1Point memory result) { result.X = self.X; result.Y = self.Y; } function P2() internal pure returns (G2Point memory) { // for some reason ethereum expects to have c1*v + c0 form return G2Point( [0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed], [0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa] ); } function negate(G1Point memory self) internal pure { // The prime q in the base field F_q for G1 if (self.Y == 0) { require(self.X == 0); return; } self.Y = q_mod - self.Y; } function point_add(G1Point memory p1, G1Point memory p2) internal view returns (G1Point memory r) { point_add_into_dest(p1, p2, r); return r; } function point_add_assign(G1Point memory p1, G1Point memory p2) internal view { point_add_into_dest(p1, p2, p1); } function point_add_into_dest(G1Point memory p1, G1Point memory p2, G1Point memory dest) internal view { if (p2.X == 0 && p2.Y == 0) { // we add zero, nothing happens dest.X = p1.X; dest.Y = p1.Y; return; } else if (p1.X == 0 && p1.Y == 0) { // we add into zero, and we add non-zero point dest.X = p2.X; dest.Y = p2.Y; return; } else { uint256[4] memory input; input[0] = p1.X; input[1] = p1.Y; input[2] = p2.X; input[3] = p2.Y; bool success = false; assembly { success := staticcall(gas(), 6, input, 0x80, dest, 0x40) } require(success); } } function point_sub_assign(G1Point memory p1, G1Point memory p2) internal view { point_sub_into_dest(p1, p2, p1); } function point_sub_into_dest(G1Point memory p1, G1Point memory p2, G1Point memory dest) internal view { if (p2.X == 0 && p2.Y == 0) { // we subtracted zero, nothing happens dest.X = p1.X; dest.Y = p1.Y; return; } else if (p1.X == 0 && p1.Y == 0) { // we subtract from zero, and we subtract non-zero point dest.X = p2.X; dest.Y = q_mod - p2.Y; return; } else { uint256[4] memory input; input[0] = p1.X; input[1] = p1.Y; input[2] = p2.X; input[3] = q_mod - p2.Y; bool success = false; assembly { success := staticcall(gas(), 6, input, 0x80, dest, 0x40) } require(success); } } function point_mul(G1Point memory p, Fr memory s) internal view returns (G1Point memory r) { point_mul_into_dest(p, s, r); return r; } function point_mul_assign(G1Point memory p, Fr memory s) internal view { point_mul_into_dest(p, s, p); } function point_mul_into_dest(G1Point memory p, Fr memory s, G1Point memory dest) internal view { uint[3] memory input; input[0] = p.X; input[1] = p.Y; input[2] = s.value; bool success; assembly { success := staticcall(gas(), 7, input, 0x60, dest, 0x40) } require(success); } function pairing(G1Point[] memory p1, G2Point[] memory p2) internal view returns (bool) { require(p1.length == p2.length); uint elements = p1.length; uint inputSize = elements * 6; uint[] memory input = new uint[](inputSize); for (uint i = 0; i < elements; i++) { input[i * 6 + 0] = p1[i].X; input[i * 6 + 1] = p1[i].Y; input[i * 6 + 2] = p2[i].X[0]; input[i * 6 + 3] = p2[i].X[1]; input[i * 6 + 4] = p2[i].Y[0]; input[i * 6 + 5] = p2[i].Y[1]; } uint[1] memory out; bool success; assembly { success := staticcall(gas(), 8, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) } require(success); return out[0] != 0; } /// Convenience method for a pairing check for two pairs. function pairingProd2(G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal view returns (bool) { G1Point[] memory p1 = new G1Point[](2); G2Point[] memory p2 = new G2Point[](2); p1[0] = a1; p1[1] = b1; p2[0] = a2; p2[1] = b2; return pairing(p1, p2); } } library TranscriptLibrary { // flip 0xe000000000000000000000000000000000000000000000000000000000000000; uint256 constant FR_MASK = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; uint32 constant DST_0 = 0; uint32 constant DST_1 = 1; uint32 constant DST_CHALLENGE = 2; struct Transcript { bytes32 state_0; bytes32 state_1; uint32 challenge_counter; } function new_transcript() internal pure returns (Transcript memory t) { t.state_0 = bytes32(0); t.state_1 = bytes32(0); t.challenge_counter = 0; } function update_with_u256(Transcript memory self, uint256 value) internal pure { bytes32 old_state_0 = self.state_0; self.state_0 = keccak256(abi.encodePacked(DST_0, old_state_0, self.state_1, value)); self.state_1 = keccak256(abi.encodePacked(DST_1, old_state_0, self.state_1, value)); } function update_with_fr(Transcript memory self, PairingsBn254.Fr memory value) internal pure { update_with_u256(self, value.value); } function update_with_g1(Transcript memory self, PairingsBn254.G1Point memory p) internal pure { update_with_u256(self, p.X); update_with_u256(self, p.Y); } function get_challenge(Transcript memory self) internal pure returns(PairingsBn254.Fr memory challenge) { bytes32 query = keccak256(abi.encodePacked(DST_CHALLENGE, self.state_0, self.state_1, self.challenge_counter)); self.challenge_counter += 1; challenge = PairingsBn254.Fr({value: uint256(query) & FR_MASK}); } }
{ "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "optimizer": { "enabled": true, "runs": 200 } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[{"internalType":"bytes","name":"param1","type":"bytes"},{"internalType":"bytes","name":"param2","type":"bytes"}],"name":"concatBytes","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"upgradeParameters","type":"bytes"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_rootHash","type":"bytes32"},{"internalType":"uint64","name":"_tokenId","type":"uint64"},{"internalType":"uint32","name":"_creatorId","type":"uint32"},{"internalType":"uint32","name":"_seqId","type":"uint32"},{"internalType":"bytes32","name":"_uri","type":"bytes32"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256[]","name":"_proof","type":"uint256[]"}],"name":"verifyExitNFTProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"_rootHash","type":"bytes32"},{"internalType":"uint32","name":"_accountId","type":"uint32"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint16","name":"_tokenId","type":"uint16"},{"internalType":"uint128","name":"_amount","type":"uint128"},{"internalType":"uint256[]","name":"_proof","type":"uint256[]"}],"name":"verifyExitProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes","name":"_account_data","type":"bytes"},{"internalType":"bytes","name":"_pair_data0","type":"bytes"},{"internalType":"bytes","name":"_pair_data1","type":"bytes"},{"internalType":"uint256[]","name":"_proof","type":"uint256[]"}],"name":"verifyLpExitProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100625760003560e01c80630bb0482f146100675780632539464514610090578063439fab9114610090578063ac95103d146100a5578063c81a27ad146100c5578063ea58ce3c146100d8575b600080fd5b61007a610075366004613570565b6100eb565b6040516100879190613820565b60405180910390f35b6100a361009e36600461347f565b6101d2565b005b6100b86100b33660046134c0565b6101d6565b6040516100879190613812565b6100b86100d3366004613324565b6103ba565b6100b86100e63660046133c8565b610503565b60608082518451016040519080825280601f01601f19166020018201604052801561011d576020820181803883390190505b5090506000805b85518110156101735785818151811061013957fe5b602001015160f81c60f81b83838151811061015057fe5b60200101906001600160f81b031916908160001a90535060019182019101610124565b5060005b84518110156101c65784818151811061018c57fe5b602001015160f81c60f81b8383815181106101a357fe5b60200101906001600160f81b031916908160001a90535060019182019101610177565b50909150505b92915050565b5050565b6000606061024d8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8e018190048102820181019092528c815292508c91508b90819084018382808284376000920191909152506100eb92505050565b905060606102918288888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506100eb92505050565b905060006002826040516102a59190613776565b602060405180830381855afa1580156102c2573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506102e591908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b03918483169150839060009061032557fe5b602002602001018181525050610339612e5d565b610376838a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b9050610380612eff565b6103886108fb565b9050835181602001511461039b57600080fd5b6103a58282610db9565b97505050505050505098975050505050505050565b600080600289898989896040516020016103d89594939291906136b3565b60408051601f19818403018152908290526103f291613776565b602060405180830381855afa15801561040f573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061043291908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b03918483169150839060009061047257fe5b602002602001018181525050610486612e5d565b6104c38388888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b90506104cd612eff565b6104d5610df6565b905083518160200151146104e857600080fd5b6104f28282610db9565b9d9c50505050505050505050505050565b60008060028a8a8a8a8a8a6040516020016105239695949392919061370c565b60408051601f198184030181529082905261053d91613776565b602060405180830381855afa15801561055a573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525061057d91908101906132fe565b6040805160018082528183019092529192506060919060208083019080388339505081519192506001600160fd1b0391848316915083906000906105bd57fe5b6020026020010181815250506105d1612e5d565b61060e8388888080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061064f92505050565b9050610618612eff565b6106206111b7565b9050835181602001511461063357600080fd5b61063d8282610db9565b9e9d5050505050505050505050505050565b610657612e5d565b602182511461066557600080fd5b8251604051908082528060200260200182016040528015610690578160200160208202803883390190505b50815260005b83518110156106d6578381815181106106ab57fe5b6020026020010151826000015182815181106106c357fe5b6020908102919091010152600101610696565b506000805b600481101561073b576107178483815181106106f357fe5b602002602001015185846001018151811061070a57fe5b6020026020010151611578565b8360200151826004811061072757fe5b6020020152600291909101906001016106db565b5061076283828151811061074b57fe5b602002602001015184836001018151811061070a57fe5b604083015260020160005b60048110156107a9576107858483815181106106f357fe5b8360600151826004811061079557fe5b60200201526002919091019060010161076d565b5060005b60048110156107f3576107d28483815181106107c557fe5b602002602001015161165a565b836080015182600481106107e257fe5b6020020152600191820191016107ad565b5060005b60018110156108305761080f8483815181106107c557fe5b8360a00151826001811061081f57fe5b6020020152600191820191016107f7565b506108408382815181106107c557fe5b8260c0018190525060018101905061085d8382815181106107c557fe5b8260e0018190525060018101905061087a8382815181106107c557fe5b61010083015260010160005b60038110156108c05761089e8483815181106107c557fe5b83610120015182600381106108af57fe5b602002015260019182019101610886565b506108d083828151811061074b57fe5b8261014001819052506002810190506108ee83828151811061074b57fe5b6101608301525092915050565b610903612eff565b620800008152600160208201526109397f0cf1526aaafac6bacbb67d11a4077806b123f767e4b0883d14cc0193568fc08261165a565b60408201526109887f26aafba448a6c22abfa5286eef01b17a6bffaacf20a8a0fca1a59035c8e45ddd7f160835d2c20ea81f2f4c2c7f1644e30ae41b2541588a27552c08c190d5b32af861168e565b6060820151526109d87f20954e6cd2ad660dd9723263311b03986d6f8993ebfeb67a60a46608b35701fe7f059ce6f6469bb72b8758473f86e86a959c4b9f74193d931dd172883c641a25c761168e565b606082015160200152610a2b7f26245ff891a4328caa0da951efba1b5b3cc13136cd315ac7c8794053e47a43157f1681b7685491b5f8fb470a21a326bc91bd75178d411ead030aefcddd9b51bd0661168e565b606082015160400152610a7e7f2857e4543592da2693e7e97477f186736c4a0a325bd9477bbd996819dc0ca4ce7f0ffe00e34dd8592675469bb7a92b1e78e7c9e4ace22343605fb3a48dd4f1597061168e565b6060828101510152610ad07f0180059910e776f202efcb1b96d72ab597e811caef2a9af5d8b42fc79949d9137f1a43d65fba7b7340f6cb120a31ad0a1d5a26e0a1151398d9a80d6930e623be2161168e565b606082015160800152610b227e7b755d547d62eaf1375f3efe8a62ef52ed1b40ef2ec0943ab9a1de7198f2747f28f96cb876dc97aada23aa73d202682e3f29a29126d5711df0747234660cd83d61168e565b606082015160a00152610b747edfc41dc088a145be5a6978121abea7dffaef90012b9d6f1b577e957a28dd247f2ef1b64e6b0afe751b5531869a17dd9d5c90d734880de7fed3d3ae74a01d989a61168e565b608082015152610bc47f1d69be00b5e7d9d2af9d10da25eda41333effe6b9435caefe07ddae096d30ddf7f162137b0ead7f1be6f448f36db186c5bee0e44f19a926e88b53f7760b64e9dbd61168e565b60a082015152610c147f179c8e2df764ec8a2a5f5dbd37ffdde057178b6c10ef04bbb3331a78439343317f1a71e27ade54b801c811bd10d93c2b9e6c80bfea3d808487cf375f50e065e89661168e565b60a082015160200152610c677f2fc48aa7bcba72e922843e8732398afe655368a3aedca1f204b0e1bd9ddbf9817f2f6adc4261e3dd2fc80affdb39de386de5c38aa0066a8560f76dff220341071a61168e565b60a082015160400152610cba7f2a096bb764588fb3f422291918e33c1d8d9f5a8ef6c9cf41d288a5ddea0cf26a7f1e2ab7435be44f4101b1af83f76d5b621f4ecdd9d673a4b019ffb41072413f9b61168e565b60a082015160600152610ccd600561165a565b60c082015152610cdd600761165a565b60c082015160200152610cf0600a61165a565b60c082015160026020020181905250610db160405180604001604052807f260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c181526020017f0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b081525060405180604001604052807f04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe481526020017f22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e558152506116ac565b60e082015290565b6000610dc3612f62565b6000610dd08286866116b4565b905080610de2576000925050506101cc565b610ded82868661198c565b95945050505050565b610dfe612eff565b62040000815260016020820152610e347f0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe61165a565b6040820152610e837f135a8971e309397099f1c5c0b9c2a141e83b888ff0504ba8c9a7c13b8c66873f7f0eed3feed06aa8e4d3493aefd4c6f9a6c337e20b7e2f20d22b08b3b4129f8efc61168e565b606082015152610ed37f0b97dc8947583759347e13c8f2abdccf1004e13f771fe9c46155af71d336de2e7f1d39ffdb681fca7ce01b775e9aaaf5d8b71d9b7602ac00c60bbde91dca816dec61168e565b606082015160200152610f267f04b4d20919f8c66794a986ad27a0e4e820fb7a1bf863048017a59b1f7b3030f67f2da162d6902e64de2d4f6178f090bf9db7fbb9199d1640d5eab9c0a26869524f61168e565b606082015160400152610f797f242d28e776c833130fb04fb097c1c166c4293018e64947c46086f1bea21847327f277463020cda47c42366610a37cde00ef3a32b44906e1adee02fcd66bbe44a7561168e565b6060828101510152610fcb7f24d289d00964c5501b4a32521df5685264fb490a4549e794f998f18f169f31957f14307765ce1383efab72009df36fd97d28b94c9c1fce57a64697e5633d8d4e0d61168e565b60608201516080015261101e7f0c3697df5aef9952def7b12d29447e9ae12fe6580f0e00399237bee51a5fa0e07f2b120b7d414a0843aa2e9e606bcec5ff8eb3c38d8b73479de42fc8901bb626e661168e565b606082015160a001526110717f0e09a50a8e0635250a3a200dab94a1a51de811b179f61df2d4683e59fd1774ee7f251732ea6c2951b7b54f2dbc349b14db2b63def8d132f86499d2e43edc21ad5161168e565b6080820151526110c17f1889e41a3cebf0b097ec6cef8849e66480c344c422ed9a2e4d63fe75155af0d07f0ed098f479a2f229cd47f645517737f512612915010cb576398cd4ec7c803baf61168e565b60a0820151526111117f141171280664b7aea2c65ddb87f28391cab60913a74f4255b3dd4295d162a02c7f033c1cc5f1e58a035eb5f3951e79cc90e9fccf3c82781c2553b1d49694a1899161168e565b60a0820151602001526111647f0fc9a25cc839ef11afab0a9f320cf2b7346054f566135611bb25b6cec46205b37f16ea53198b77ab1e469d166b36d89d9fd88b3c356958cdf377a534d73f47a9a361168e565b60a082015160400152610cba7f2040345b5f92cc70a9607cf5fc28e5be26f673852450488d4e65f70890649b457f2c0e0bf512b4aa690449b589513e2b34cbc5e748a4217947331e0350c73be31061168e565b6111bf612eff565b620400008152600160208201526111f57f0f60c8fe0414cb9379b2d39267945f6bd60d06a05216231b26a9fcf88ddbfebe61165a565b60408201526112447f27ad08e12b6087f6fe0d7e1d8d8f14f53e92aaabf05e4f7d1051b0fbe3db046d7f11f1f49ccf9f433366c3dc71fe9efa794678b87cbb2b07deea0cfbb7093e536961168e565b6060820151526112947f1ee701b0be61332b7de5d4260ad352a3f50a8e51ac4a761f6ab5077c8dffab517f21451115294a50d06c5c442e9a61b04699fd8f296e70ef00e78a5908ef54144461168e565b6060820151602001526112e77f1eccd5e119cc4a7bc8d274e0d8f61a054ee38694796790dacd22a098642bf2bc7f10bb95ce678a633560f0a704001e4c148aff47b7aee0856bfec735fb13884e0261168e565b60608201516040015261133a7f013fa8820794811964f35f04adb7600a9a3c76c9960b9cbb162b8324e09a14f57f0c110889cdf3554c95c7876f3e9d64804b3f0a6effa2baaf8bcb4ca847e5ed1d61168e565b606082810151015261138c7f1d5d922608eb262a5b05dc872b81238a352ba3521a1e847b06606d0937c7a34c7f291cd60f7f242bd5e1075f99ed70583f40460758aa58c8cd418cb5b6929e8c1261168e565b6060820151608001526113df7f2bc438c9650f27fd6b4125e098c5d87f874cfd29efad4a3e4ecae04e23b050097f283af270ef1c1c897e85b844536745dbf4d744f2e0fe8dc113143b5209a60baa61168e565b606082015160a001526114327f16f50151d8dccdd5e06a29eee62a9f614d534c542640bee31e9e9a3f2b708a837f120854cacf85957ca9777576bda620a21312769ab9596c7c64dc74215683988261168e565b6080820151526114827f27d2cd3c7a778fed777f6410fca3a65521282818e187e901827b1e666281d38b7f1f5484c3976cadaea11704759c33ecfffe4900b696febcffb397ec15324c484a61168e565b60a0820151526114d27f26a13c2a6968f979cfc4ef24b965487c5f22f2dfc5e9008942fa32bbb72f7b3c7f2bbb803702a9e0c0d4e3a078e2ffa2c525165f940a551555efbdd8876cc3f06e61168e565b60a0820151602001526115257f17210a663b894d0d08db4ba0f2da65bf67b5e4c94317d03e0eb6077b11e849ef7f2c98fb45631bd244290296ce55afc885e0e3cc96b506037183338141e97fdf6161168e565b60a082015160400152610cba7f1ef739c21d81d82ecb30445c5c6e775597aed256ee615b84c71dff243c81dd9e7f072138b9876fc2f52d29b5cf35478fe4091f384c034fa59ab4b29deb69e9828161168e565b611580612fc3565b8215801561158c575081155b156115ad5760405180604001604052808481526020018381525090506101cc565b6000805160206139c883398151915283106115c757600080fd5b6000805160206139c883398151915282106115e157600080fd5b60006000805160206139c8833981519152838409905060006000805160206139c883398151915285860990506000805160206139c883398151915285820990506000805160206139c883398151915260038208905080821461164257600080fd5b50506040805180820190915292835250602082015290565b611662612fdd565b6000805160206139e8833981519152821061167c57600080fd5b50604080516020810190915290815290565b611696612fc3565b5060408051808201909152918252602082015290565b611696612ff0565b6020810151825151600091146116c957600080fd5b81602001516001146116da57600080fd5b6116e2613010565b6116ea611ecc565b905060005b836020015181101561172d576117258560000151828151811061170e57fe5b602002602001015183611ee890919063ffffffff16565b6001016116ef565b5060005b60048110156117675761175f8560200151826004811061174d57fe5b6020020151839063ffffffff611f5b16565b600101611731565b5061177181611f77565b602086015261177f81611f77565b60408087019190915284015161179c90829063ffffffff611f5b16565b6117a581611f77565b855260005b60048110156117ce576117c68560600151826004811061174d57fe5b6001016117aa565b506117d881611f77565b60a086015260408051600180825281830190925290816020015b6117fa612fdd565b8152602001906001900390816117f257505060c08601528251604084015160a087015161182b926000929091611fe8565b8560c0015160008151811061183c57fe5b602002602001018190525060006118548686866120c9565b90508061186657600092505050611985565b60005b600481101561189f576118978660800151826004811061188557fe5b6020020151849063ffffffff61232216565b600101611869565b5060005b60018110156118c7576118bf8660a00151826001811061188557fe5b6001016118a3565b5060005b60038110156118f0576118e8866101200151826003811061188557fe5b6001016118cb565b5060e085015161190790839063ffffffff61232216565b61010085015161191e90839063ffffffff61232216565b60c085015161193490839063ffffffff61232216565b61193d82611f77565b606087015261014085015161195990839063ffffffff611f5b16565b61016085015161197090839063ffffffff611f5b16565b61197982611f77565b60808701525060019150505b9392505050565b6000611996612fc3565b6119a1858585612330565b90506119ab612fdd565b835160a08701516119c19163ffffffff61274116565b90506119cb612fc3565b6119d36127cd565b90506119dd612fdd565b6119e7600161165a565b90506119f1612fc3565b6060880151611a079060005b60200201516127ee565b9050611a11612fdd565b611a1b600161165a565b905060015b6004811015611a7857611a39828763ffffffff61280a16565b611a5e828b606001518360048110611a4d57fe5b60200201519063ffffffff61282416565b9450611a70838663ffffffff61283716565b600101611a20565b5060608a0151611a8f90849063ffffffff61280a16565b611a9f828763ffffffff61283716565b60005b6004811015611aef5760608b0151611ac190859063ffffffff61280a16565b611ad5848b602001518360048110611a4d57fe5b9450611ae7838663ffffffff61283716565b600101611aa2565b5060005b6003811015611b405760608b0151611b1290859063ffffffff61280a16565b611b26848a60a001518360048110611a4d57fe5b9450611b38838663ffffffff61283716565b600101611af3565b5060608a0151611b5790849063ffffffff61280a16565b60608a0151611b6d90849063ffffffff61280a16565b611b7d818463ffffffff61284216565b60808a0151611b9390829063ffffffff61280a16565b6020890151611ba59082906003611a4d565b9350611bb7828563ffffffff61283716565b611bc1600161165a565b9250611bcb612fdd565b611bd88a60e00151612847565b9050611bf18b606001518561280a90919063ffffffff16565b6101008a0151611c0890839063ffffffff61284216565b611c18828563ffffffff61280a16565b611c28818363ffffffff61285616565b60005b6004811015611c975760608c0151611c4a90869063ffffffff61280a16565b611c6f8b608001518260048110611c5d57fe5b6020020151849063ffffffff61284216565b611c7f838663ffffffff61280a16565b611c8f828463ffffffff61285616565b600101611c2b565b5060005b6003811015611cf65760608c0151611cba90869063ffffffff61280a16565b611cce8b61012001518260038110611c5d57fe5b611cde838663ffffffff61280a16565b611cee828463ffffffff61285616565b600101611c9b565b5060608b0151611d0d90859063ffffffff61280a16565b60c08a0151611d2390839063ffffffff61284216565b611d33828563ffffffff61280a16565b60808b0151611d4990839063ffffffff61280a16565b611d59818363ffffffff61285616565b60608b0151611d6f90859063ffffffff61280a16565b60a08a015151611d80908390612842565b611d90828563ffffffff61280a16565b60808b0151611da690839063ffffffff61280a16565b611db6818363ffffffff61285616565b611dde611dd182611dc56127cd565b9063ffffffff61282416565b849063ffffffff61287016565b611de6612fc3565b5060a08b01516101408b01518491611e1491611e079163ffffffff61282416565b829063ffffffff61283716565b60a08c0151611e2a90849063ffffffff61284216565b60408a0151611e4090849063ffffffff61280a16565b60808c0151611e5690849063ffffffff61280a16565b6101608b0151611e7090611e07908563ffffffff61282416565b611e78612fc3565b60808d01516101608d0151611e929163ffffffff61282416565b9050611eac8c61014001518261283790919063ffffffff16565b611eb58161287b565b6104f282611ec16128b1565b838e60e00151612971565b611ed4613010565b600080825260208201819052604082015290565b8151602080840151604051611f069260009285929091879101613782565b60408051601f1981840301815291815281516020928301208552848201519051611f399260019285929091879101613782565b60408051601f1981840301815291905280516020918201209301929092525050565b611f69828260000151611ee8565b6101d2828260200151611ee8565b611f7f612fdd565b60006002836000015184602001518560400151604051602001611fa594939291906137ca565b60408051808303601f190181529181528151602092830120948101805160010163ffffffff169052805191820190526001600160fd1b0390931683525090919050565b611ff0612fdd565b838510611ffc57600080fd5b612004612fdd565b61200e600161165a565b9050612018612fdd565b612028858863ffffffff61274116565b905061203a848763ffffffff61274116565b925061204c838363ffffffff612a5716565b825161205757600080fd5b612067838263ffffffff61280a16565b61206f612fdd565b61207885612847565b905061208a818363ffffffff612a5716565b6120a36120968861165a565b829063ffffffff61280a16565b6120ac81612a75565b90506120be848263ffffffff61280a16565b505050949350505050565b60006120d3612fdd565b6120e583600001518660a00151612ab2565b80519091506120f357600080fd5b60e084015161210990829063ffffffff61280a16565b612111612fdd565b61211b600161165a565b9050612125612fdd565b612133866101000151612847565b905061213d612fdd565b612147600061165a565b905060005b8751518110156121bb576121808960c00151828151811061216957fe5b60200260200101518361284290919063ffffffff16565b6121a3612196896000015183815181106107c557fe5b839063ffffffff61280a16565b6121b3838363ffffffff61285616565b60010161214c565b5087516121cf90849063ffffffff61280a16565b6121d7612fdd565b6121e48860c00151612847565b905060005b600381101561226f576122068961012001518260038110611c5d57fe5b60208a015161221c90849063ffffffff61280a16565b60408a015161223290849063ffffffff61285616565b6122578960800151826004811061224557fe5b6020020151849063ffffffff61285616565b612267828463ffffffff61280a16565b6001016121e9565b50604089015161228690839063ffffffff61284216565b60808801516060015161229a908390612856565b6122aa818363ffffffff61280a16565b6122ba818563ffffffff61280a16565b6122ca838263ffffffff612a5716565b88516122dd90859063ffffffff61280a16565b6122f18960c0015160008151811061216957fe5b612301828563ffffffff61280a16565b612311838363ffffffff612a5716565b505051915190911495945050505050565b6101d2828260000151611ee8565b612338612fc3565b606082015160099061234b9060056119fd565b9150612355612fc3565b61235d6127cd565b9050612367612fdd565b612371600061165a565b905060005b60048110156123c1576123a78760800151826004811061239257fe5b602002015187606001518360068110611a4d57fe5b92506123b9858463ffffffff61283716565b600101612376565b506080860151516123d3908290612842565b6080860151602001516123e790829061280a565b60608501516123f99082906004611a4d565b915061240b848363ffffffff61283716565b60a086015151608086015161242291906000611a4d565b9150612434848363ffffffff61283716565b61243c612fdd565b6124498860a00151612847565b905061246288602001518261280a90919063ffffffff16565b608087015151612473908290612856565b604088015161248990829063ffffffff61285616565b60005b600381101561252a5760a08901516124ab90849063ffffffff61284216565b6124d08760c0015182600381106124be57fe5b6020020151849063ffffffff61280a16565b60208901516124e690849063ffffffff61280a16565b60408901516124fc90849063ffffffff61285616565b6125128860800151826001016004811061224557fe5b612522828463ffffffff61280a16565b60010161248c565b50875161253e90829063ffffffff61280a16565b6125528860c0015160008151811061216957fe5b875161256590839063ffffffff61280a16565b875161257890839063ffffffff61280a16565b612588818363ffffffff61285616565b612590612fdd565b60608901516125a5908663ffffffff61274116565b90506125be89608001518261280a90919063ffffffff16565b6125c6612fdd565b6125d0600161165a565b905060005b600381101561266d5760208b01516125f490869063ffffffff61284216565b61261a8a6101200151826003811061260857fe5b6020020151869063ffffffff61280a16565b60408b015161263090869063ffffffff61285616565b6126558a60800151826004811061264357fe5b6020020151869063ffffffff61285616565b612665828663ffffffff61280a16565b6001016125d5565b5060208a015161268490829063ffffffff61280a16565b60c089015161269a90829063ffffffff61280a16565b89516126ad90829063ffffffff61280a16565b60408901516126c2908463ffffffff61282416565b60a08901519095506126e8906126db9083906003611a4d565b869063ffffffff61287016565b6126f8878663ffffffff61283716565b60608a015161270e90889063ffffffff612ae616565b604089015161273490612727908463ffffffff61282416565b889063ffffffff61283716565b5050505050509392505050565b612749612fdd565b612751613030565b6040518060c00160405280602081526020016020815260200160208152602001856000015181526020018481526020016000805160206139e8833981519152815250905061279d61304e565b600060208260c08560055afa9050806127b557600080fd5b50604080516020810190915290518152949350505050565b6127d5612fc3565b5060408051808201909152600181526002602082015290565b6127f6612fc3565b815181526020918201519181019190915290565b6000805160206139e8833981519152815183510990915250565b61282c612fc3565b6101cc838383612aed565b6101d2828284612b2f565b519052565b61284f612fdd565b9051815290565b6000805160206139e8833981519152815183510890915250565b6101d2828284612bc7565b60208101516128955780511561289057600080fd5b6128ae565b6020810180516000805160206139c88339815191520390525b50565b6128b9612ff0565b50604080516080810182527f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c28183019081527f1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed6060830152815281518083019092527f090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b82527f12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa60208381019190915281019190915290565b60408051600280825260608281019093526000929190816020015b612994612fc3565b81526020019060019003908161298c57505060408051600280825260608083019093529293509091602082015b6129c9612ff0565b8152602001906001900390816129c157905050905086826000815181106129ec57fe5b60200260200101819052508482600181518110612a0557fe5b60200260200101819052508581600081518110612a1e57fe5b60200260200101819052508381600181518110612a3757fe5b6020026020010181905250612a4c8282612c61565b979650505050505050565b805182516000805160206139e8833981519152918203900890915250565b612a7d612fdd565b8151612a8857600080fd5b6101cc827f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffffff612741565b612aba612fdd565b612aca828463ffffffff61274116565b90506101cc612ad9600161165a565b829063ffffffff612a5716565b6101d28282845b612af561306c565b835181526020840151816001602002015282518160026020020152600060408360608460075afa905080612b2857600080fd5b5050505050565b8151158015612b4057506020820151155b15612b58578251815260208084015190820152612bc2565b8251158015612b6957506020830151155b15612b81578151815260208083015190820152612bc2565b612b8961308a565b8351815260208085015181830152835160408301528301518160035b6020020152600060408360808460065afa905080612b2857600080fd5b505050565b8151158015612bd857506020820151155b15612bf0578251815260208084015190820152612bc2565b8251158015612c0157506020830151155b15612c2957815181526020808301516000805160206139c88339815191520390820152612bc2565b612c3161308a565b8351815260208085015181830152835160408301528301516000805160206139c883398151915203816003612ba5565b60008151835114612c7157600080fd5b8251604080516006830280825260c084028201602001909252606090828015612ca4578160200160208202803883390190505b50905060005b83811015612e2957868181518110612cbe57fe5b602002602001015160000151828260060260000181518110612cdc57fe5b602002602001018181525050868181518110612cf457fe5b602002602001015160200151828260060260010181518110612d1257fe5b602002602001018181525050858181518110612d2a57fe5b602090810291909101015151518251839060026006850201908110612d4b57fe5b602002602001018181525050858181518110612d6357fe5b60209081029190910101515160016020020151828260060260030181518110612d8857fe5b602002602001018181525050858181518110612da057fe5b602002602001015160200151600060028110612db857fe5b6020020151828260060260040181518110612dcf57fe5b602002602001018181525050858181518110612de757fe5b602002602001015160200151600160028110612dff57fe5b6020020151828260060260050181518110612e1657fe5b6020908102919091010152600101612caa565b50612e3261304e565b6000602082602086026020860160085afa905080612e4f57600080fd5b505115159695505050505050565b60405180610180016040528060608152602001612e786130a8565b8152602001612e85612fc3565b8152602001612e926130a8565b8152602001612e9f6130d5565b8152602001612eac613102565b8152602001612eb9612fdd565b8152602001612ec6612fdd565b8152602001612ed3612fdd565b8152602001612ee061312f565b8152602001612eed612fc3565b8152602001612efa612fc3565b905290565b6040518061010001604052806000815260200160008152602001612f21612fdd565b8152602001612f2e61315c565b8152602001612f3b613189565b8152602001612f486130a8565b8152602001612f5561312f565b8152602001612efa612ff0565b6040518060e00160405280612f75612fdd565b8152602001612f82612fdd565b8152602001612f8f612fdd565b8152602001612f9c612fdd565b8152602001612fa9612fdd565b8152602001612fb6612fdd565b8152602001606081525090565b604051806040016040528060008152602001600081525090565b6040518060200160405280600081525090565b60405180604001604052806130036131b6565b8152602001612efa6131b6565b604080516060810182526000808252602082018190529181019190915290565b6040518060c001604052806006906020820280388339509192915050565b60405180602001604052806001906020820280388339509192915050565b60405180606001604052806003906020820280388339509192915050565b60405180608001604052806004906020820280388339509192915050565b60405180608001604052806004905b6130bf612fc3565b8152602001906001900390816130b75790505090565b60405180608001604052806004905b6130ec612fdd565b8152602001906001900390816130e45790505090565b60405180602001604052806001905b613119612fdd565b8152602001906001900390816131115790505090565b60405180606001604052806003905b613146612fdd565b81526020019060019003908161313e5790505090565b6040518060c001604052806006905b613173612fc3565b81526020019060019003908161316b5790505090565b60405180602001604052806001905b6131a0612fc3565b8152602001906001900390816131985790505090565b60405180604001604052806002906020820280388339509192915050565b80356101cc81613986565b60008083601f8401126131f157600080fd5b5081356001600160401b0381111561320857600080fd5b60208301915083602082028301111561322057600080fd5b9250929050565b80356101cc8161399a565b80516101cc8161399a565b60008083601f84011261324f57600080fd5b5081356001600160401b0381111561326657600080fd5b60208301915083600182028301111561322057600080fd5b600082601f83011261328f57600080fd5b81356132a261329d82613857565b613831565b915080825260208301602083018583830111156132be57600080fd5b6132c98382846138e0565b50505092915050565b80356101cc816139a3565b80356101cc816139ac565b80356101cc816139b5565b80356101cc816139be565b60006020828403121561331057600080fd5b600061331c8484613232565b949350505050565b600080600080600080600060c0888a03121561333f57600080fd5b600061334b8a8a613227565b975050602061335c8a828b016132e8565b965050604061336d8a828b016131d4565b955050606061337e8a828b016132dd565b945050608061338f8a828b016132d2565b93505060a08801356001600160401b038111156133ab57600080fd5b6133b78a828b016131df565b925092505092959891949750929550565b60008060008060008060008060e0898b0312156133e457600080fd5b60006133f08b8b613227565b98505060206134018b828c016132f3565b97505060406134128b828c016132e8565b96505060606134238b828c016132e8565b95505060806134348b828c01613227565b94505060a06134458b828c016131d4565b93505060c08901356001600160401b0381111561346157600080fd5b61346d8b828c016131df565b92509250509295985092959890939650565b6000806020838503121561349257600080fd5b82356001600160401b038111156134a857600080fd5b6134b48582860161323d565b92509250509250929050565b6000806000806000806000806080898b0312156134dc57600080fd5b88356001600160401b038111156134f257600080fd5b6134fe8b828c0161323d565b985098505060208901356001600160401b0381111561351c57600080fd5b6135288b828c0161323d565b965096505060408901356001600160401b0381111561354657600080fd5b6135528b828c0161323d565b945094505060608901356001600160401b0381111561346157600080fd5b6000806040838503121561358357600080fd5b82356001600160401b0381111561359957600080fd5b6135a58582860161327e565b92505060208301356001600160401b038111156135c157600080fd5b6135cd8582860161327e565b9150509250929050565b6135e86135e382613890565b61391c565b82525050565b6135e88161389b565b6135e8613603826138a0565b6138a0565b60006136138261387e565b61361d8185613882565b935061362d8185602086016138ec565b6136368161395e565b9093019392505050565b600061364b8261387e565b613655818561388b565b93506136658185602086016138ec565b9290920192915050565b6135e861367b826138a3565b613927565b6135e861368c826138b8565b613932565b6135e861369d826138cb565b613948565b6135e86136ae826138d4565b613953565b60006136bf82886135f7565b6020820191506136cf8287613691565b6004820191506136df82866135d7565b6014820191506136ef8285613680565b6002820191506136ff828461366f565b5060100195945050505050565b600061371882896135f7565b60208201915061372882886136a2565b6008820191506137388287613691565b6004820191506137488286613691565b60048201915061375882856135f7565b60208201915061376882846135d7565b506014019695505050505050565b60006119858284613640565b600061378e8287613691565b60048201915061379e82866135f7565b6020820191506137ae82856135f7565b6020820191506137be82846135f7565b50602001949350505050565b60006137d68287613691565b6004820191506137e682866135f7565b6020820191506137f682856135f7565b6020820191506138068284613691565b50600401949350505050565b602081016101cc82846135ee565b602080825281016119858184613608565b6040518181016001600160401b038111828210171561384f57600080fd5b604052919050565b60006001600160401b0382111561386d57600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b919050565b60006101cc826138bf565b151590565b90565b6fffffffffffffffffffffffffffffffff1690565b61ffff1690565b6001600160a01b031690565b63ffffffff1690565b6001600160401b031690565b82818337506000910152565b60005b838110156139075781810151838201526020016138ef565b83811115613916576000848401525b50505050565b60006101cc8261393d565b60006101cc82613968565b60006101cc8261397a565b60006101cc82613980565b60006101cc82613974565b60006101cc8261396e565b601f01601f191690565b60801b90565b60c01b90565b60e01b90565b60f01b90565b60601b90565b61398f81613890565b81146128ae57600080fd5b61398f816138a0565b61398f816138a3565b61398f816138b8565b61398f816138cb565b61398f816138d456fe30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4730644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001a365627a7a72315820d4b1b0c8b8faf3db02641cc60cf25dce191cd6a2f14fcb0d486f616f4f5deada6c6578706572696d656e74616cf564736f6c63430005100040
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.