diff --git a/Makefile b/Makefile index 96b244c4..043cb9b1 100644 --- a/Makefile +++ b/Makefile @@ -86,13 +86,9 @@ deploy-linea-rollup: LINEA_ROLLUP_GENESIS_TIMESTAMP=1683325137 \ npx ts-node local-deployments-artifacts/deployPlonkVerifierAndLineaRollupV$(L1_CONTRACT_VERSION).ts -deploy-linea-rollup-v5: - $(MAKE) deploy-linea-rollup L1_CONTRACT_VERSION=5 - deploy-linea-rollup-v6: $(MAKE) deploy-linea-rollup L1_CONTRACT_VERSION=6 - deploy-l2messageservice: # WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE cd contracts/; \ @@ -243,7 +239,7 @@ testnet-start-l2: testnet-start-l2-traces-node-only: docker compose -f docker/compose.yml -f docker/compose-testnet-sync.overries.yml up traces-node -d -testnet-start: start-l1 deploy-linea-rollup-v5 testnet-start-l2 +testnet-start: start-l1 deploy-linea-rollup-v6 testnet-start-l2 testnet-restart-l2-keep-state: docker compose -f docker/compose.yml -f docker/compose-testnet-sync.overrides.yml rm -f -s -v sequencer traces-node coordinator make testnet-start-l2 diff --git a/config/coordinator/coordinator-docker.config.toml b/config/coordinator/coordinator-docker.config.toml index 781bb0b6..8096ef01 100644 --- a/config/coordinator/coordinator-docker.config.toml +++ b/config/coordinator/coordinator-docker.config.toml @@ -110,11 +110,11 @@ finalized-block-tag="latest" # reset this once we know what to do on dev/UAT earliest-block=0 genesis-state-root-hash="0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd" -# shnarf for contract V5 +# shnarf for contract V6 # Keccak256(parentShnarf="0x00...00", snarkHash="0x00...00", # parentStateRootHash="0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd", # evaludationClaim="0x00...00", evaludationPoint="0x00...00") -genesis-shnarf-v5="0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f" +genesis-shnarf-v6="0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f" [l2] rpc-endpoint="http://sequencer:8545" diff --git a/contracts/README.md b/contracts/README.md index e8f9acdb..3cd70d49 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -111,7 +111,7 @@ The L2MessageService deploy uses nonce 2 as the following are deployed beforehan **Deploying the L1 contracts** ``` -# This will deploy the Linea Rollup that is currently deployed on Mainnet - the current version is the LineaRollupV5. +# This will deploy the Linea Rollup that is currently deployed on Mainnet - the current version is the LineaRollupV6. # Some end to end tests will test future upgrades to validate the stack remains functional. # Note: By default a test/placeholder verifier contract is used `IntegrationTestTrueVerifier` if you wish to use a proper verifier, adjust the @@ -119,10 +119,7 @@ The L2MessageService deploy uses nonce 2 as the following are deployed beforehan # Be sure to check the parameter values in the Makefile before executing the command. -# Deploy v5 -make deploy-linea-rollup-v5 - -# Or deploy v6 +# deploy v6 make deploy-linea-rollup-v6 make deploy-token-bridge-l1 @@ -145,7 +142,7 @@ make deploy-contracts The above command will trigger the following commands to deploy: -- deploy-linea-rollup-v5 +- deploy-linea-rollup-v6 - deploy-token-bridge-l1 - deploy-l1-test-erc20 - deploy-l2messageservice diff --git a/contracts/abi/LineaRollupV5.0.abi b/contracts/abi/LineaRollupV5.0.abi deleted file mode 100644 index 9fe8a1a8..00000000 --- a/contracts/abi/LineaRollupV5.0.abi +++ /dev/null @@ -1,2354 +0,0 @@ -[ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "BlobSubmissionDataIsMissing", - "type": "error" - }, - { - "inputs": [], - "name": "BytesLengthNotMultipleOf32", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "bytesLength", - "type": "uint256" - } - ], - "name": "BytesLengthNotMultipleOfTwo", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "currentDataHash", - "type": "bytes32" - } - ], - "name": "DataAlreadySubmitted", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - } - ], - "name": "DataStartingBlockDoesNotMatch", - "type": "error" - }, - { - "inputs": [], - "name": "EmptyBlobData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "EmptyBlobDataAtIndex", - "type": "error" - }, - { - "inputs": [], - "name": "EmptySubmissionData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - } - ], - "name": "FeePaymentFailed", - "type": "error" - }, - { - "inputs": [], - "name": "FeeTooLow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - } - ], - "name": "FinalBlockDoesNotMatchShnarfFinalBlock", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "finalBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lastFinalizedBlock", - "type": "uint256" - } - ], - "name": "FinalBlockNumberLessThanOrEqualToLastFinalizedBlock", - "type": "error" - }, - { - "inputs": [], - "name": "FinalBlockStateEqualsZeroHash", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "value", - "type": "bytes32" - } - ], - "name": "FinalShnarfWrong", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "l2BlockTimestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "currentBlockTimestamp", - "type": "uint256" - } - ], - "name": "FinalizationInTheFuture", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "value", - "type": "bytes32" - } - ], - "name": "FinalizationStateIncorrect", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "firstBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockNumber", - "type": "uint256" - } - ], - "name": "FirstBlockGreaterThanFinalBlock", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "firstBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lastFinalizedBlock", - "type": "uint256" - } - ], - "name": "FirstBlockLessThanOrEqualToLastFinalizedBlock", - "type": "error" - }, - { - "inputs": [], - "name": "FirstByteIsNotZero", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidMerkleProof", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidProof", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidProofType", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "pauseType", - "type": "uint256" - } - ], - "name": "IsNotPaused", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "pauseType", - "type": "uint256" - } - ], - "name": "IsPaused", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "rollingHash", - "type": "bytes32" - } - ], - "name": "L1RollingHashDoesNotExistOnL1", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "merkleRoot", - "type": "bytes32" - } - ], - "name": "L2MerkleRootAlreadyAnchored", - "type": "error" - }, - { - "inputs": [], - "name": "L2MerkleRootDoesNotExist", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "actual", - "type": "bytes32" - } - ], - "name": "LastFinalizedShnarfWrong", - "type": "error" - }, - { - "inputs": [], - "name": "LimitIsZero", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "messageIndex", - "type": "uint256" - } - ], - "name": "MessageAlreadyClaimed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "MessageDoesNotExistOrHasAlreadyBeenClaimed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "destination", - "type": "address" - } - ], - "name": "MessageSendingFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "rollingHash", - "type": "bytes32" - } - ], - "name": "MissingMessageNumberForRollingHash", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - } - ], - "name": "MissingRollingHashForMessageNumber", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "actual", - "type": "bytes32" - } - ], - "name": "ParentStateRootHashInvalid", - "type": "error" - }, - { - "inputs": [], - "name": "PeriodIsZero", - "type": "error" - }, - { - "inputs": [], - "name": "PointEvaluationFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "fieldElements", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "blsCurveModulus", - "type": "uint256" - } - ], - "name": "PointEvaluationResponseInvalid", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - } - ], - "name": "PrecompileReturnDataLengthWrong", - "type": "error" - }, - { - "inputs": [], - "name": "ProofIsEmpty", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "ProofLengthDifferentThanMerkleDepth", - "type": "error" - }, - { - "inputs": [], - "name": "RateLimitExceeded", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrantCall", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "shnarfsLength", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockNumbers", - "type": "uint256" - } - ], - "name": "ShnarfAndFinalBlockNumberLengthsMismatched", - "type": "error" - }, - { - "inputs": [], - "name": "SnarkHashIsZeroHash", - "type": "error" - }, - { - "inputs": [], - "name": "StartingRootHashDoesNotMatch", - "type": "error" - }, - { - "inputs": [], - "name": "ValueSentTooLow", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddressNotAllowed", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "resettingAddress", - "type": "address" - } - ], - "name": "AmountUsedInPeriodReset", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "stateRootHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bool", - "name": "finalizedWithProof", - "type": "bool" - } - ], - "name": "BlockFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "lastBlockFinalized", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "startingRootHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "finalRootHash", - "type": "bytes32" - } - ], - "name": "BlocksVerificationDone", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "lastBlockFinalized", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "startingRootHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "finalRootHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bool", - "name": "withProof", - "type": "bool" - } - ], - "name": "DataFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "shnarf", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "startBlock", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "endBlock", - "type": "uint256" - } - ], - "name": "DataSubmittedV2", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32[]", - "name": "messageHashes", - "type": "bytes32[]" - } - ], - "name": "L1L2MessagesReceivedOnL2", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "L2L1MessageHashAddedToInbox", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "l2MerkleRoot", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "treeDepth", - "type": "uint256" - } - ], - "name": "L2MerkleRootAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "l2Block", - "type": "uint256" - } - ], - "name": "L2MessagingBlockAnchored", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "amountChangeBy", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bool", - "name": "amountUsedLoweredToLimit", - "type": "bool" - }, - { - "indexed": false, - "internalType": "bool", - "name": "usedAmountResetToZero", - "type": "bool" - } - ], - "name": "LimitAmountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "_messageHash", - "type": "bytes32" - } - ], - "name": "MessageClaimed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_fee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "_calldata", - "type": "bytes" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "_messageHash", - "type": "bytes32" - } - ], - "name": "MessageSent", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "messageSender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "pauseType", - "type": "uint256" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "periodInSeconds", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "limitInWei", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "currentPeriodEnd", - "type": "uint256" - } - ], - "name": "RateLimitInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "rollingHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "RollingHashUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "systemMigrationBlock", - "type": "uint256" - } - ], - "name": "SystemMigrationBlockInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "messageSender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "pauseType", - "type": "uint256" - } - ], - "name": "UnPaused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "verifierAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "proofType", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "verifierSetBy", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "oldVerifierAddress", - "type": "address" - } - ], - "name": "VerifierAddressChanged", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "GENERAL_PAUSE_TYPE", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "GENESIS_SHNARF", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INBOX_STATUS_RECEIVED", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INBOX_STATUS_UNKNOWN", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_L2_PAUSE_TYPE", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_L1_PAUSE_TYPE", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPERATOR_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OUTBOX_STATUS_RECEIVED", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OUTBOX_STATUS_SENT", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OUTBOX_STATUS_UNKNOWN", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PAUSE_MANAGER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PROVING_SYSTEM_PAUSE_TYPE", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RATE_LIMIT_SETTER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERIFIER_SETTER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "_feeRecipient", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_calldata", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - } - ], - "name": "claimMessage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32[]", - "name": "proof", - "type": "bytes32[]" - }, - { - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "leafIndex", - "type": "uint32" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "feeRecipient", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "merkleRoot", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct IL1MessageService.ClaimMessageWithProofParams", - "name": "_params", - "type": "tuple" - } - ], - "name": "claimMessageWithProof", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "currentFinalizedShnarf", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentFinalizedState", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentL2BlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentL2StoredL1MessageNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentL2StoredL1RollingHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentPeriodAmountInWei", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentPeriodEnd", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataEndingBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "endingBlock", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataFinalStateRootHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataParents", - "outputs": [ - { - "internalType": "bytes32", - "name": "parentHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataShnarfHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "shnarfHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataStartingBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "startingBlock", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_aggregatedProof", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_proofType", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "parentStateRootHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "lastFinalizedShnarf", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "parentShnarf", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "dataEvaluationPoint", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "dataEvaluationClaim", - "type": "bytes32" - } - ], - "internalType": "struct ILineaRollup.ShnarfData", - "name": "shnarfData", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "lastFinalizedTimestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalTimestamp", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "lastFinalizedL1RollingHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "l1RollingHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "lastFinalizedL1RollingHashMessageNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l1RollingHashMessageNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l2MerkleTreesDepth", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "l2MerkleRoots", - "type": "bytes32[]" - }, - { - "internalType": "bytes", - "name": "l2MessagingBlocksOffsets", - "type": "bytes" - } - ], - "internalType": "struct ILineaRollup.FinalizationDataV2", - "name": "_finalizationData", - "type": "tuple" - } - ], - "name": "finalizeBlocksWithProof", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "parentStateRootHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "lastFinalizedShnarf", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "parentShnarf", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "dataEvaluationPoint", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "dataEvaluationClaim", - "type": "bytes32" - } - ], - "internalType": "struct ILineaRollup.ShnarfData", - "name": "shnarfData", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "lastFinalizedTimestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalTimestamp", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "lastFinalizedL1RollingHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "l1RollingHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "lastFinalizedL1RollingHashMessageNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l1RollingHashMessageNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l2MerkleTreesDepth", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "l2MerkleRoots", - "type": "bytes32[]" - }, - { - "internalType": "bytes", - "name": "l2MessagingBlocksOffsets", - "type": "bytes" - } - ], - "internalType": "struct ILineaRollup.FinalizationDataV2", - "name": "_finalizationData", - "type": "tuple" - } - ], - "name": "finalizeBlocksWithoutProof", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "inboxL2L1MessageStatus", - "outputs": [ - { - "internalType": "uint256", - "name": "messageStatus", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_initialStateRootHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_initialL2BlockNumber", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_defaultVerifier", - "type": "address" - }, - { - "internalType": "address", - "name": "_securityCouncil", - "type": "address" - }, - { - "internalType": "address[]", - "name": "_operators", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "_rateLimitPeriodInSeconds", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_rateLimitAmountInWei", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_genesisTimestamp", - "type": "uint256" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32[]", - "name": "_shnarfs", - "type": "bytes32[]" - }, - { - "internalType": "uint256[]", - "name": "_finalBlockNumbers", - "type": "uint256[]" - } - ], - "name": "initializeParentShnarfsAndFinalizedState", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_messageNumber", - "type": "uint256" - } - ], - "name": "isMessageClaimed", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "_pauseType", - "type": "uint8" - } - ], - "name": "isPaused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "merkleRoot", - "type": "bytes32" - } - ], - "name": "l2MerkleRootsDepths", - "outputs": [ - { - "internalType": "uint256", - "name": "treeDepth", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "limitInWei", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nextMessageNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "outboxL1L2MessageStatus", - "outputs": [ - { - "internalType": "uint256", - "name": "messageStatus", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "_pauseType", - "type": "uint8" - } - ], - "name": "pauseByType", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "pauseType", - "type": "bytes32" - } - ], - "name": "pauseTypeStatuses", - "outputs": [ - { - "internalType": "bool", - "name": "pauseStatus", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "periodInSeconds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "resetAmountUsedInPeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "resetRateLimitAmount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - } - ], - "name": "rollingHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "rollingHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_fee", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_calldata", - "type": "bytes" - } - ], - "name": "sendMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "sender", - "outputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_newVerifierAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_proofType", - "type": "uint256" - } - ], - "name": "setVerifierAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "shnarf", - "type": "bytes32" - } - ], - "name": "shnarfFinalBlockNumbers", - "outputs": [ - { - "internalType": "uint256", - "name": "finalBlockNumber", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - } - ], - "name": "stateRootHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "stateRootHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "firstBlockInData", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - } - ], - "internalType": "struct ILineaRollup.SupportingSubmissionDataV2", - "name": "submissionData", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "dataEvaluationClaim", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "kzgCommitment", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "kzgProof", - "type": "bytes" - } - ], - "internalType": "struct ILineaRollup.BlobSubmissionData[]", - "name": "_blobSubmissionData", - "type": "tuple[]" - }, - { - "internalType": "bytes32", - "name": "_parentShnarf", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_finalBlobShnarf", - "type": "bytes32" - } - ], - "name": "submitBlobs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "firstBlockInData", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "compressedData", - "type": "bytes" - } - ], - "internalType": "struct ILineaRollup.SubmissionDataV2", - "name": "_submissionData", - "type": "tuple" - }, - { - "internalType": "bytes32", - "name": "_parentShnarf", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_expectedShnarf", - "type": "bytes32" - } - ], - "name": "submitDataAsCalldata", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "systemMigrationBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "_pauseType", - "type": "uint8" - } - ], - "name": "unPauseByType", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_proofType", - "type": "uint256" - } - ], - "name": "unsetVerifierAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "proofType", - "type": "uint256" - } - ], - "name": "verifiers", - "outputs": [ - { - "internalType": "address", - "name": "verifierAddress", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } -] \ No newline at end of file diff --git a/contracts/deploy/03_deploy_LineaRollupV5.ts b/contracts/deploy/03_deploy_LineaRollupV5.ts deleted file mode 100644 index e5478c4e..00000000 --- a/contracts/deploy/03_deploy_LineaRollupV5.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { DeployFunction } from "hardhat-deploy/types"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; -import { deployUpgradableFromFactory } from "../scripts/hardhat/utils"; -import { - LogContractDeployment, - getDeployedContractAddress, - getRequiredEnvVar, - tryStoreAddress, - tryVerifyContract, -} from "contracts/common/helpers"; - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployments } = hre; - - const contractName = "LineaRollupV5"; - const verifierName = "PlonkVerifier"; - const existingContractAddress = await getDeployedContractAddress(contractName, deployments); - let verifierAddress = await getDeployedContractAddress(verifierName, deployments); - if (verifierAddress === undefined) { - if (process.env["PLONKVERIFIER_ADDRESS"] !== undefined) { - console.log(`Using environment variable for PlonkVerifier , ${process.env["PLONKVERIFIER_ADDRESS"]}`); - verifierAddress = process.env["PLONKVERIFIER_ADDRESS"]; - } else { - throw "Missing PLONKVERIFIER_ADDRESS environment variable"; - } - } else { - console.log(`Using deployed variable for PlonkVerifier , ${verifierAddress}`); - } - - // LineaRollup DEPLOYED AS UPGRADEABLE PROXY - const LineaRollup_initialStateRootHash = getRequiredEnvVar("LINEA_ROLLUP_INITIAL_STATE_ROOT_HASH"); - const LineaRollup_initialL2BlockNumber = getRequiredEnvVar("LINEA_ROLLUP_INITIAL_L2_BLOCK_NUMBER"); - const LineaRollup_securityCouncil = getRequiredEnvVar("LINEA_ROLLUP_SECURITY_COUNCIL"); - const LineaRollup_operators = getRequiredEnvVar("LINEA_ROLLUP_OPERATORS"); - const LineaRollup_rateLimitPeriodInSeconds = getRequiredEnvVar("LINEA_ROLLUP_RATE_LIMIT_PERIOD"); - const LineaRollup_rateLimitAmountInWei = getRequiredEnvVar("LINEA_ROLLUP_RATE_LIMIT_AMOUNT"); - const LineaRollup_genesisTimestamp = getRequiredEnvVar("LINEA_ROLLUP_GENESIS_TIMESTAMP"); - - console.log(`Setting operators ${LineaRollup_operators}`); - - if (existingContractAddress === undefined) { - console.log(`Deploying initial version, NB: the address will be saved if env SAVE_ADDRESS=true.`); - } else { - console.log(`Deploying new version, NB: ${existingContractAddress} will be overwritten if env SAVE_ADDRESS=true.`); - } - const contract = await deployUpgradableFromFactory( - "LineaRollupV5", - [ - LineaRollup_initialStateRootHash, - LineaRollup_initialL2BlockNumber, - verifierAddress, - LineaRollup_securityCouncil, - LineaRollup_operators?.split(","), - LineaRollup_rateLimitPeriodInSeconds, - LineaRollup_rateLimitAmountInWei, - LineaRollup_genesisTimestamp, - ], - { - initializer: "initialize(bytes32,uint256,address,address,address[],uint256,uint256,uint256)", - unsafeAllow: ["constructor"], - }, - ); - - await LogContractDeployment(contractName, contract); - const contractAddress = await contract.getAddress(); - - await tryStoreAddress(hre.network.name, contractName, contractAddress, contract.deploymentTransaction()!.hash); - - await tryVerifyContract(contractAddress); -}; - -export default func; -func.tags = ["LineaRollupV5"]; diff --git a/contracts/local-deployments-artifacts/deployPlonkVerifierAndLineaRollupV5.ts b/contracts/local-deployments-artifacts/deployPlonkVerifierAndLineaRollupV5.ts deleted file mode 100644 index 6b704750..00000000 --- a/contracts/local-deployments-artifacts/deployPlonkVerifierAndLineaRollupV5.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { ethers } from "ethers"; -import fs from "fs"; -import path from "path"; -import * as dotenv from "dotenv"; -import { abi as LineaRollupV5Abi, bytecode as LineaRollupV5Bytecode } from "./dynamic-artifacts/LineaRollupV5.json"; -import { - contractName as ProxyAdminContractName, - abi as ProxyAdminAbi, - bytecode as ProxyAdminBytecode, -} from "./static-artifacts/ProxyAdmin.json"; -import { - abi as TransparentUpgradeableProxyAbi, - bytecode as TransparentUpgradeableProxyBytecode, -} from "./static-artifacts/TransparentUpgradeableProxy.json"; -import { getRequiredEnvVar } from "../common/helpers/environment"; -import { deployContractFromArtifacts, getInitializerData } from "../common/helpers/deployments"; -import { get1559Fees } from "../scripts/utils"; - -dotenv.config(); - -function findContractArtifacts( - folderPath: string, - contractName: string, -): { abi: ethers.InterfaceAbi; bytecode: ethers.BytesLike } { - const files = fs.readdirSync(folderPath); - - const foundFile = files.find((file) => file === `${contractName}.json`); - - if (!foundFile) { - // Throw an error if the file is not found - throw new Error(`Contract "${contractName}" not found in folder "${folderPath}"`); - } - - // Construct the full file path - const filePath = path.join(folderPath, foundFile); - - // Read the file content - const fileContent = fs.readFileSync(filePath, "utf-8").trim(); - const parsedContent = JSON.parse(fileContent); - return parsedContent; -} - -async function main() { - const verifierName = getRequiredEnvVar("VERIFIER_CONTRACT_NAME"); - const lineaRollupInitialStateRootHash = getRequiredEnvVar("LINEA_ROLLUP_INITIAL_STATE_ROOT_HASH"); - const lineaRollupInitialL2BlockNumber = getRequiredEnvVar("LINEA_ROLLUP_INITIAL_L2_BLOCK_NUMBER"); - const lineaRollupSecurityCouncil = getRequiredEnvVar("LINEA_ROLLUP_SECURITY_COUNCIL"); - const lineaRollupOperators = getRequiredEnvVar("LINEA_ROLLUP_OPERATORS").split(","); - const lineaRollupRateLimitPeriodInSeconds = getRequiredEnvVar("LINEA_ROLLUP_RATE_LIMIT_PERIOD"); - const lineaRollupTateLimitAmountInWei = getRequiredEnvVar("LINEA_ROLLUP_RATE_LIMIT_AMOUNT"); - const lineaRollupGenesisTimestamp = getRequiredEnvVar("LINEA_ROLLUP_GENESIS_TIMESTAMP"); - const lineaRollupName = "LineaRollupV5"; - const lineaRollupImplementationName = "LineaRollupV5Implementation"; - const verifierArtifacts = findContractArtifacts(path.join(__dirname, "./dynamic-artifacts"), verifierName); - - const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); - const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider); - - const { gasPrice } = await get1559Fees(provider); - - let walletNonce; - - if (!process.env.L1_NONCE) { - walletNonce = await wallet.getNonce(); - } else { - walletNonce = parseInt(process.env.L1_NONCE); - } - - const [verifier, lineaRollupImplementation, proxyAdmin] = await Promise.all([ - deployContractFromArtifacts(verifierName, verifierArtifacts.abi, verifierArtifacts.bytecode, wallet, { - nonce: walletNonce, - gasPrice, - }), - deployContractFromArtifacts(lineaRollupImplementationName, LineaRollupV5Abi, LineaRollupV5Bytecode, wallet, { - nonce: walletNonce + 1, - gasPrice, - }), - deployContractFromArtifacts(ProxyAdminContractName, ProxyAdminAbi, ProxyAdminBytecode, wallet, { - nonce: walletNonce + 2, - gasPrice, - }), - ]); - - const proxyAdminAddress = await proxyAdmin.getAddress(); - const verifierAddress = await verifier.getAddress(); - const lineaRollupImplementationAddress = await lineaRollupImplementation.getAddress(); - - const initializer = getInitializerData(LineaRollupV5Abi, "initialize", [ - lineaRollupInitialStateRootHash, - lineaRollupInitialL2BlockNumber, - verifierAddress, - lineaRollupSecurityCouncil, - lineaRollupOperators, - lineaRollupRateLimitPeriodInSeconds, - lineaRollupTateLimitAmountInWei, - lineaRollupGenesisTimestamp, - ]); - - await deployContractFromArtifacts( - lineaRollupName, - TransparentUpgradeableProxyAbi, - TransparentUpgradeableProxyBytecode, - wallet, - lineaRollupImplementationAddress, - proxyAdminAddress, - initializer, - { gasPrice }, - ); -} - -main().catch((error) => { - console.error(error); - process.exit(1); -}); diff --git a/contracts/local-deployments-artifacts/dynamic-artifacts/LineaRollupV5.json b/contracts/local-deployments-artifacts/dynamic-artifacts/LineaRollupV5.json deleted file mode 100644 index 538dfdbe..00000000 --- a/contracts/local-deployments-artifacts/dynamic-artifacts/LineaRollupV5.json +++ /dev/null @@ -1,2363 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "LineaRollupV5", - "sourceName": "contracts/test-contracts/LineaRollupV5.sol", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "BlobSubmissionDataIsMissing", - "type": "error" - }, - { - "inputs": [], - "name": "BytesLengthNotMultipleOf32", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "bytesLength", - "type": "uint256" - } - ], - "name": "BytesLengthNotMultipleOfTwo", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "currentDataHash", - "type": "bytes32" - } - ], - "name": "DataAlreadySubmitted", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - } - ], - "name": "DataStartingBlockDoesNotMatch", - "type": "error" - }, - { - "inputs": [], - "name": "EmptyBlobData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "EmptyBlobDataAtIndex", - "type": "error" - }, - { - "inputs": [], - "name": "EmptySubmissionData", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "recipient", - "type": "address" - } - ], - "name": "FeePaymentFailed", - "type": "error" - }, - { - "inputs": [], - "name": "FeeTooLow", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - } - ], - "name": "FinalBlockDoesNotMatchShnarfFinalBlock", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "finalBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lastFinalizedBlock", - "type": "uint256" - } - ], - "name": "FinalBlockNumberLessThanOrEqualToLastFinalizedBlock", - "type": "error" - }, - { - "inputs": [], - "name": "FinalBlockStateEqualsZeroHash", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "value", - "type": "bytes32" - } - ], - "name": "FinalShnarfWrong", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "l2BlockTimestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "currentBlockTimestamp", - "type": "uint256" - } - ], - "name": "FinalizationInTheFuture", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "value", - "type": "bytes32" - } - ], - "name": "FinalizationStateIncorrect", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "firstBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockNumber", - "type": "uint256" - } - ], - "name": "FirstBlockGreaterThanFinalBlock", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "firstBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "lastFinalizedBlock", - "type": "uint256" - } - ], - "name": "FirstBlockLessThanOrEqualToLastFinalizedBlock", - "type": "error" - }, - { - "inputs": [], - "name": "FirstByteIsNotZero", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidMerkleProof", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidProof", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidProofType", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "pauseType", - "type": "uint256" - } - ], - "name": "IsNotPaused", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "pauseType", - "type": "uint256" - } - ], - "name": "IsPaused", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "rollingHash", - "type": "bytes32" - } - ], - "name": "L1RollingHashDoesNotExistOnL1", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "merkleRoot", - "type": "bytes32" - } - ], - "name": "L2MerkleRootAlreadyAnchored", - "type": "error" - }, - { - "inputs": [], - "name": "L2MerkleRootDoesNotExist", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "actual", - "type": "bytes32" - } - ], - "name": "LastFinalizedShnarfWrong", - "type": "error" - }, - { - "inputs": [], - "name": "LimitIsZero", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "messageIndex", - "type": "uint256" - } - ], - "name": "MessageAlreadyClaimed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "MessageDoesNotExistOrHasAlreadyBeenClaimed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "destination", - "type": "address" - } - ], - "name": "MessageSendingFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "rollingHash", - "type": "bytes32" - } - ], - "name": "MissingMessageNumberForRollingHash", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - } - ], - "name": "MissingRollingHashForMessageNumber", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "expected", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "actual", - "type": "bytes32" - } - ], - "name": "ParentStateRootHashInvalid", - "type": "error" - }, - { - "inputs": [], - "name": "PeriodIsZero", - "type": "error" - }, - { - "inputs": [], - "name": "PointEvaluationFailed", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "fieldElements", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "blsCurveModulus", - "type": "uint256" - } - ], - "name": "PointEvaluationResponseInvalid", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - } - ], - "name": "PrecompileReturnDataLengthWrong", - "type": "error" - }, - { - "inputs": [], - "name": "ProofIsEmpty", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "actual", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "ProofLengthDifferentThanMerkleDepth", - "type": "error" - }, - { - "inputs": [], - "name": "RateLimitExceeded", - "type": "error" - }, - { - "inputs": [], - "name": "ReentrantCall", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "shnarfsLength", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockNumbers", - "type": "uint256" - } - ], - "name": "ShnarfAndFinalBlockNumberLengthsMismatched", - "type": "error" - }, - { - "inputs": [], - "name": "SnarkHashIsZeroHash", - "type": "error" - }, - { - "inputs": [], - "name": "StartingRootHashDoesNotMatch", - "type": "error" - }, - { - "inputs": [], - "name": "ValueSentTooLow", - "type": "error" - }, - { - "inputs": [], - "name": "ZeroAddressNotAllowed", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "resettingAddress", - "type": "address" - } - ], - "name": "AmountUsedInPeriodReset", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "stateRootHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bool", - "name": "finalizedWithProof", - "type": "bool" - } - ], - "name": "BlockFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "lastBlockFinalized", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "startingRootHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "finalRootHash", - "type": "bytes32" - } - ], - "name": "BlocksVerificationDone", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "lastBlockFinalized", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "startingRootHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "finalRootHash", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bool", - "name": "withProof", - "type": "bool" - } - ], - "name": "DataFinalized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "shnarf", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "startBlock", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "endBlock", - "type": "uint256" - } - ], - "name": "DataSubmittedV2", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes32[]", - "name": "messageHashes", - "type": "bytes32[]" - } - ], - "name": "L1L2MessagesReceivedOnL2", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "L2L1MessageHashAddedToInbox", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "l2MerkleRoot", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "treeDepth", - "type": "uint256" - } - ], - "name": "L2MerkleRootAdded", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "l2Block", - "type": "uint256" - } - ], - "name": "L2MessagingBlockAnchored", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "amountChangeBy", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bool", - "name": "amountUsedLoweredToLimit", - "type": "bool" - }, - { - "indexed": false, - "internalType": "bool", - "name": "usedAmountResetToZero", - "type": "bool" - } - ], - "name": "LimitAmountChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "_messageHash", - "type": "bytes32" - } - ], - "name": "MessageClaimed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_fee", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "_calldata", - "type": "bytes" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "_messageHash", - "type": "bytes32" - } - ], - "name": "MessageSent", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "messageSender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "pauseType", - "type": "uint256" - } - ], - "name": "Paused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "periodInSeconds", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "limitInWei", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "currentPeriodEnd", - "type": "uint256" - } - ], - "name": "RateLimitInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "previousAdminRole", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "newAdminRole", - "type": "bytes32" - } - ], - "name": "RoleAdminChanged", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleGranted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - } - ], - "name": "RoleRevoked", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "rollingHash", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "RollingHashUpdated", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "systemMigrationBlock", - "type": "uint256" - } - ], - "name": "SystemMigrationBlockInitialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "messageSender", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "pauseType", - "type": "uint256" - } - ], - "name": "UnPaused", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "verifierAddress", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "proofType", - "type": "uint256" - }, - { - "indexed": true, - "internalType": "address", - "name": "verifierSetBy", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "oldVerifierAddress", - "type": "address" - } - ], - "name": "VerifierAddressChanged", - "type": "event" - }, - { - "inputs": [], - "name": "DEFAULT_ADMIN_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "GENERAL_PAUSE_TYPE", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "GENESIS_SHNARF", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INBOX_STATUS_RECEIVED", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INBOX_STATUS_UNKNOWN", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L1_L2_PAUSE_TYPE", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "L2_L1_PAUSE_TYPE", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OPERATOR_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OUTBOX_STATUS_RECEIVED", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OUTBOX_STATUS_SENT", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "OUTBOX_STATUS_UNKNOWN", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PAUSE_MANAGER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "PROVING_SYSTEM_PAUSE_TYPE", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "RATE_LIMIT_SETTER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "VERIFIER_SETTER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "_feeRecipient", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_calldata", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - } - ], - "name": "claimMessage", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32[]", - "name": "proof", - "type": "bytes32[]" - }, - { - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "leafIndex", - "type": "uint32" - }, - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "fee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - }, - { - "internalType": "address payable", - "name": "feeRecipient", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "merkleRoot", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "internalType": "struct IL1MessageService.ClaimMessageWithProofParams", - "name": "_params", - "type": "tuple" - } - ], - "name": "claimMessageWithProof", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "currentFinalizedShnarf", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentFinalizedState", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentL2BlockNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentL2StoredL1MessageNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentL2StoredL1RollingHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentPeriodAmountInWei", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentPeriodEnd", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "currentTimestamp", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataEndingBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "endingBlock", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataFinalStateRootHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataParents", - "outputs": [ - { - "internalType": "bytes32", - "name": "parentHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataShnarfHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "shnarfHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "dataHash", - "type": "bytes32" - } - ], - "name": "dataStartingBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "startingBlock", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "_aggregatedProof", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_proofType", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "parentStateRootHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "lastFinalizedShnarf", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "parentShnarf", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "dataEvaluationPoint", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "dataEvaluationClaim", - "type": "bytes32" - } - ], - "internalType": "struct ILineaRollupV5.ShnarfData", - "name": "shnarfData", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "lastFinalizedTimestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalTimestamp", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "lastFinalizedL1RollingHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "l1RollingHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "lastFinalizedL1RollingHashMessageNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l1RollingHashMessageNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l2MerkleTreesDepth", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "l2MerkleRoots", - "type": "bytes32[]" - }, - { - "internalType": "bytes", - "name": "l2MessagingBlocksOffsets", - "type": "bytes" - } - ], - "internalType": "struct ILineaRollupV5.FinalizationDataV2", - "name": "_finalizationData", - "type": "tuple" - } - ], - "name": "finalizeBlocksWithProof", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "parentStateRootHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "lastFinalizedShnarf", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "parentShnarf", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "dataEvaluationPoint", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "dataEvaluationClaim", - "type": "bytes32" - } - ], - "internalType": "struct ILineaRollupV5.ShnarfData", - "name": "shnarfData", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "lastFinalizedTimestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalTimestamp", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "lastFinalizedL1RollingHash", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "l1RollingHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "lastFinalizedL1RollingHashMessageNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l1RollingHashMessageNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "l2MerkleTreesDepth", - "type": "uint256" - }, - { - "internalType": "bytes32[]", - "name": "l2MerkleRoots", - "type": "bytes32[]" - }, - { - "internalType": "bytes", - "name": "l2MessagingBlocksOffsets", - "type": "bytes" - } - ], - "internalType": "struct ILineaRollupV5.FinalizationDataV2", - "name": "_finalizationData", - "type": "tuple" - } - ], - "name": "finalizeBlocksWithoutProof", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - } - ], - "name": "getRoleAdmin", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "grantRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "hasRole", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "inboxL2L1MessageStatus", - "outputs": [ - { - "internalType": "uint256", - "name": "messageStatus", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "_initialStateRootHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "_initialL2BlockNumber", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_defaultVerifier", - "type": "address" - }, - { - "internalType": "address", - "name": "_securityCouncil", - "type": "address" - }, - { - "internalType": "address[]", - "name": "_operators", - "type": "address[]" - }, - { - "internalType": "uint256", - "name": "_rateLimitPeriodInSeconds", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_rateLimitAmountInWei", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_genesisTimestamp", - "type": "uint256" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32[]", - "name": "_shnarfs", - "type": "bytes32[]" - }, - { - "internalType": "uint256[]", - "name": "_finalBlockNumbers", - "type": "uint256[]" - } - ], - "name": "initializeParentShnarfsAndFinalizedState", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_messageNumber", - "type": "uint256" - } - ], - "name": "isMessageClaimed", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "_pauseType", - "type": "uint8" - } - ], - "name": "isPaused", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "merkleRoot", - "type": "bytes32" - } - ], - "name": "l2MerkleRootsDepths", - "outputs": [ - { - "internalType": "uint256", - "name": "treeDepth", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "limitInWei", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "nextMessageNumber", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "messageHash", - "type": "bytes32" - } - ], - "name": "outboxL1L2MessageStatus", - "outputs": [ - { - "internalType": "uint256", - "name": "messageStatus", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "_pauseType", - "type": "uint8" - } - ], - "name": "pauseByType", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "pauseType", - "type": "bytes32" - } - ], - "name": "pauseTypeStatuses", - "outputs": [ - { - "internalType": "bool", - "name": "pauseStatus", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "periodInSeconds", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "renounceRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "resetAmountUsedInPeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_amount", - "type": "uint256" - } - ], - "name": "resetRateLimitAmount", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "role", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "revokeRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "messageNumber", - "type": "uint256" - } - ], - "name": "rollingHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "rollingHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_fee", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_calldata", - "type": "bytes" - } - ], - "name": "sendMessage", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "sender", - "outputs": [ - { - "internalType": "address", - "name": "addr", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_newVerifierAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_proofType", - "type": "uint256" - } - ], - "name": "setVerifierAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "shnarf", - "type": "bytes32" - } - ], - "name": "shnarfFinalBlockNumbers", - "outputs": [ - { - "internalType": "uint256", - "name": "finalBlockNumber", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "blockNumber", - "type": "uint256" - } - ], - "name": "stateRootHashes", - "outputs": [ - { - "internalType": "bytes32", - "name": "stateRootHash", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "firstBlockInData", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - } - ], - "internalType": "struct ILineaRollupV5.SupportingSubmissionDataV2", - "name": "submissionData", - "type": "tuple" - }, - { - "internalType": "uint256", - "name": "dataEvaluationClaim", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "kzgCommitment", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "kzgProof", - "type": "bytes" - } - ], - "internalType": "struct ILineaRollupV5.BlobSubmissionData[]", - "name": "_blobSubmissionData", - "type": "tuple[]" - }, - { - "internalType": "bytes32", - "name": "_parentShnarf", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_finalBlobShnarf", - "type": "bytes32" - } - ], - "name": "submitBlobs", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes32", - "name": "finalStateRootHash", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "firstBlockInData", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "finalBlockInData", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "snarkHash", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "compressedData", - "type": "bytes" - } - ], - "internalType": "struct ILineaRollupV5.SubmissionDataV2", - "name": "_submissionData", - "type": "tuple" - }, - { - "internalType": "bytes32", - "name": "_parentShnarf", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_expectedShnarf", - "type": "bytes32" - } - ], - "name": "submitDataAsCalldata", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "systemMigrationBlock", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint8", - "name": "_pauseType", - "type": "uint8" - } - ], - "name": "unPauseByType", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "_proofType", - "type": "uint256" - } - ], - "name": "unsetVerifierAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "proofType", - "type": "uint256" - } - ], - "name": "verifiers", - "outputs": [ - { - "internalType": "address", - "name": "verifierAddress", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x608060405234801562000010575f80fd5b506200001b62000021565b620000df565b5f54610100900460ff16156200008d5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff90811614620000dd575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b614d0980620000ed5f395ff3fe6080604052600436106103b3575f3560e01c80637d1e8c55116101e9578063b837dbe911610108578063d05d9c3d1161009d578063e196fb5d1161006d578063e196fb5d14610b42578063e97a1e9e14610b61578063f5b541a614610bd3578063f93e985714610c06575f80fd5b8063d05d9c3d14610abb578063d547741f14610ada578063d5d4b83514610af9578063d84f91e814610b0f575f80fd5b8063c1dc0f07116100d8578063c1dc0f0714610a43578063c211697414610a58578063cc5782f614610a77578063cd9b9e9a14610aa5575f80fd5b8063b837dbe9146109b8578063bc61e733146109cd578063bf3e7505146109fb578063c0729ab114610a2e575f80fd5b80639f3ce55a1161017e578063ac1eff681161014e578063ac1eff6814610939578063ad422ff01461097b578063aea4f74514610990578063b4a5a4b7146109a4575f80fd5b80639f3ce55a146108e0578063a217fddf146108f3578063abd6230d14610906578063abffac321461091a575f80fd5b806391d14854116101b957806391d148541461085a578063921b278e146108ab578063986fcddd146107d05780639ee8b211146108c1575f80fd5b80637d1e8c55146107d05780638116d995146107e35780638be745d114610802578063914e57eb1461082e575f80fd5b80635355420e116102d557806363a283931161026a578063695378f51161023a578063695378f5146107875780636a637967146105835780636e6738431461079d57806373bd07b714610430575f80fd5b806363a28393146106e45780636463fb2a1461070357806366f96e981461072257806367e404ce1461074e575f80fd5b80635c721a0c116102a55780635c721a0c146106355780635ed73ceb146106605780636078bfd81461068c57806360e83cf3146106b8575f80fd5b80635355420e146105e2578063557eac731461060157806358794456146106205780635b7eb4bd14610583575f80fd5b80632c70645c1161034b57806342fbe8421161031b57806342fbe8421461056457806348922ab714610583578063491e0936146105975780634cdd389b146105b6575f80fd5b80632c70645c146104e55780632f2ff15d146104fb57806336568abe1461051a5780633fc08b6514610539575f80fd5b80631e2ff94f116103865780631e2ff94f146104565780631f443da01461046c578063248a9ca31461049857806328958174146104c6575f80fd5b806301ffc9a7146103b757806305861180146103eb5780631065a3991461040f57806311314d0f14610430575b5f80fd5b3480156103c2575f80fd5b506103d66103d136600461412d565b610c32565b60405190151581526020015b60405180910390f35b3480156103f6575f80fd5b506104016101bb5481565b6040519081526020016103e2565b34801561041a575f80fd5b5061042e61042936600461416c565b610cca565b005b34801561043b575f80fd5b50610444600281565b60405160ff90911681526020016103e2565b348015610461575f80fd5b506104016101185481565b348015610477575f80fd5b5061040161048636600461418c565b6101b96020525f908152604090205481565b3480156104a3575f80fd5b506104016104b236600461418c565b5f9081526065602052604090206001015490565b3480156104d1575f80fd5b5061042e6104e036600461418c565b610da2565b3480156104f0575f80fd5b506104016101835481565b348015610506575f80fd5b5061042e6105153660046141c4565b610e62565b348015610525575f80fd5b5061042e6105343660046141c4565b610e8b565b348015610544575f80fd5b5061040161055336600461418c565b60a56020525f908152604090205481565b34801561056f575f80fd5b5061042e61057e36600461423a565b610f3e565b34801561058e575f80fd5b50610444600181565b3480156105a2575f80fd5b5061042e6105b13660046142c5565b611209565b3480156105c1575f80fd5b506104016105d036600461418c565b6101b76020525f908152604090205481565b3480156105ed575f80fd5b5061042e6105fc366004614355565b611531565b34801561060c575f80fd5b5061042e61061b36600461418c565b611968565b34801561062b575f80fd5b5061040160995481565b348015610640575f80fd5b5061040161064f36600461418c565b60a66020525f908152604090205481565b34801561066b575f80fd5b5061040161067a36600461418c565b6101ba6020525f908152604090205481565b348015610697575f80fd5b506104016106a636600461418c565b6101b66020525f908152604090205481565b3480156106c3575f80fd5b506104016106d236600461418c565b6101506020525f908152604090205481565b3480156106ef575f80fd5b5061042e6106fe3660046143fa565b611a2e565b34801561070e575f80fd5b5061042e61071d366004614434565b611a57565b34801561072d575f80fd5b5061040161073c36600461418c565b6101b86020525f908152604090205481565b348015610759575f80fd5b50610762611f3f565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103e2565b348015610792575f80fd5b506104016101195481565b3480156107a8575f80fd5b506104017f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c81565b3480156107db575f80fd5b506104445f81565b3480156107ee575f80fd5b5061042e6107fd36600461446c565b611f77565b34801561080d575f80fd5b5061040161081c36600461418c565b61011a6020525f908152604090205481565b348015610839575f80fd5b5061040161084836600461418c565b61014e6020525f908152604090205481565b348015610865575f80fd5b506103d66108743660046141c4565b5f91825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156108b6575f80fd5b506104016101bf5481565b3480156108cc575f80fd5b506103d66108db36600461418c565b61217c565b61042e6108ee3660046144d3565b61219f565b3480156108fe575f80fd5b506104015f81565b348015610911575f80fd5b50610444600381565b348015610925575f80fd5b5061042e61093436600461451f565b61230c565b348015610944575f80fd5b5061076261095336600461418c565b61011b6020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610986575f80fd5b5061040160985481565b34801561099b575f80fd5b5061042e61244b565b3480156109af575f80fd5b50610444600481565b3480156109c3575f80fd5b5061040160e45481565b3480156109d8575f80fd5b506103d66109e736600461416c565b60da54600160ff9092169190911b16151590565b348015610a06575f80fd5b506104017f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b348015610a39575f80fd5b50610401609a5481565b348015610a4e575f80fd5b5061040160975481565b348015610a63575f80fd5b5061042e610a7236600461458d565b6124a6565b348015610a82575f80fd5b506103d6610a9136600461418c565b60d96020525f908152604090205460ff1681565b348015610ab0575f80fd5b506104016101bd5481565b348015610ac6575f80fd5b5061042e610ad53660046145b7565b6125d3565b348015610ae5575f80fd5b5061042e610af43660046141c4565b612808565b348015610b04575f80fd5b506104016101bc5481565b348015610b1a575f80fd5b506104017f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a2681565b348015610b4d575f80fd5b5061042e610b5c36600461416c565b61282c565b348015610b6c575f80fd5b50610401604080515f602082018190529181018290527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608201526080810182905260a081019190915260c0016040516020818303038152906040528051906020012081565b348015610bde575f80fd5b506104017f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b348015610c11575f80fd5b50610401610c2036600461418c565b6101be6020525f908152604090205481565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610cc457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b7f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a26610cf4816128d7565b60da54600160ff84161b16610d3f576040517fb015579f00000000000000000000000000000000000000000000000000000000815260ff831660048201526024015b60405180910390fd5b60da8054600160ff851690811b199091169091557fef04ba2036ccaeab3a59717b51d2b9146b0b0904077177f1148a5418bf1eae23335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b7f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c610dcc816128d7565b5f82815261011b6020908152604080832054905173ffffffffffffffffffffffffffffffffffffffff90911681523392859290917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b5f82815260656020526040902060010154610e7c816128d7565b610e8683836128e1565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610f30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610d36565b610f3a82826129d3565b5050565b6004610f4981612a8c565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929610f73816128d7565b845f819003610fae576040517fb1504a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610119545f908190610ffa60408051610100810182525f6080820181815260a0830182905260c0830182905260e083018290528252602082015260609181018290528181019190915290565b5f8981526101be60205260408120548a915b87811015611106578d8d8281811061102657611026614605565b90506020028101906110389190614632565b6110419061476b565b81499650935085611081576040517fc0e41e1d00000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b835161108e908387612b12565b8351606001515f90815260208790526040902096506110be86885f1c866020015187604001518860600151612c79565b83516060808201519151602080880151604080519889529188019490945286810191909152908501899052608085019190915260a0909320845190930151915060010161100c565b50818a1461114a576040517fd3664fb3000000000000000000000000000000000000000000000000000000008152600481018b905260248101839052604401610d36565b5f8281526101be602052604090205415611193576040517f0f06cd1500000000000000000000000000000000000000000000000000000000815260048101839052602401610d36565b5f8281526101be6020526040812082905581908e908e90816111b7576111b7614605565b90506020028101906111c99190614632565b6040516020909101359084907f52bd912b0041a6ec8554b0ffae3cc1cb7b137bade0dc9e3f8f0b6758466d5df9905f90a450505050505050505050505050565b611211612e51565b85878484875f5a90506112246003612a8c565b61125861125260017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b8f612eee565b5f8e8e8e8e8b8e8e60405160200161127697969594939291906148aa565b60405160208183030381529060405280519060200120905061129781612ef5565b6112a96112a48d8f614902565b612f4f565b5f808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d6040516112d3929190614915565b5f6040518083038185875af1925050503d805f811461130d576040519150601f19603f3d011682016040523d82523d5f602084013e611312565b606091505b50915091508161137c5780511561132c5780518082602001fd5b8f6040517f54613443000000000000000000000000000000000000000000000000000000008152600401610d36919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6113b06113aa60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b5f612eee565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a250508615905061151957855f84900361146857853b158015611466573a5a61140461bc7c86614902565b61140e9190614850565b6114189190614924565b9150818811156114625773ffffffffffffffffffffffffffffffffffffffff87166108fc611446848b614850565b6040518115909202915f818181858888f1935050505050611466565b8791505b505b5f73ffffffffffffffffffffffffffffffffffffffff84161561148b578361148d565b335b90505f8173ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050905080611515576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610d36565b5050505b505050505050611527612fc4565b5050505050505050565b5f54610100900460ff161580801561154f57505f54600160ff909116105b806115685750303b15801561156857505f5460ff166001145b6115f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610d36565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611650575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b73ffffffffffffffffffffffffffffffffffffffff881661169d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5b85811015611774575f8787838181106116ba576116ba614605565b90506020020160208101906116cf919061493b565b73ffffffffffffffffffffffffffffffffffffffff160361171c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61176c7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92988888481811061175257611752614605565b9050602002016020810190611767919061493b565b6128e1565b60010161169f565b5061177f5f886128e1565b6117a97f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c886128e1565b6117b587888686612ff2565b7f033d11f27e62ab919708ec716731da80d261a6e4253259b7acde9bf89d28ec1880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a161790556101198990555f89815261011a602090815260408083208d905580518083018490528082018490527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608083018290526080830186905260a08084018790528451808503909101815260c08401855280519086012086526101be85528386208f905560e08301869052610100830186905261012083019190915261014082018590526101608083018690528351808403909101815261018083019384905280519401939093206101bd558382526101a08101939093526101c090920184905290206101bf55801561195c575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d82611992816128d7565b5f805f4260995410156119b7576097546119ac9042614902565b6099555060016119c9565b609a548510156119c957849250600191505b609885905580806119d75750815b156119e257609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b6001611a39816131a3565b5f611a43816128d7565b611a5183610119545f6131ea565b50505050565b611a5f612e51565b60a08101803590611a73906080840161493b565b611a81610120840184614956565b611a92610100860160e0870161493b565b5f5a9050611aa06003612a8c565b6101008701355f908152610150602052604081205490819003611aef576040517f4e68667500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af988806149b7565b90508114611b485780611b0c89806149b7565b6040517f5e3fd6ad0000000000000000000000000000000000000000000000000000000081526004810193909352602483015250604401610d36565b611b5588602001356134df565b611b6a6112a460c08a013560a08b0135614902565b5f611b7b60808a0160608b0161493b565b611b8b60a08b0160808c0161493b565b60a08b013560c08c013560208d0135611ba86101208f018f614956565b604051602001611bbe97969594939291906148aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209050611c1f81611c048b806149b7565b611c1460608e0160408f01614a1b565b8d6101000135613557565b611c55576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c98611c8360017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b611c9360808c0160608d0161493b565b612eee565b5f80611caa60a08c0160808d0161493b565b73ffffffffffffffffffffffffffffffffffffffff1660c08c0135611cd36101208e018e614956565b604051611ce1929190614915565b5f6040518083038185875af1925050503d805f8114611d1b576040519150601f19603f3d011682016040523d82523d5f602084013e611d20565b606091505b509150915081611d9557805115611d3a5780518082602001fd5b611d4a60a08c0160808d0161493b565b6040517f5461344300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d36565b611dc36113aa60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a2505050505f861115611f2e57855f849003611e7d57853b158015611e7b573a5a611e1961bc7c86614902565b611e239190614850565b611e2d9190614924565b915081881115611e775773ffffffffffffffffffffffffffffffffffffffff87166108fc611e5b848b614850565b6040518115909202915f818181858888f1935050505050611e7b565b8791505b505b5f73ffffffffffffffffffffffffffffffffffffffff841615611ea05783611ea2565b335b90505f8173ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050905080611f2a576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610d36565b5050505b505050505050611f3c612fc4565b50565b5f611f72611f6e60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b5c90565b905090565b5f54600590610100900460ff16158015611f9757505f5460ff8083169116105b612023576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610d36565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100179055838214612096576040517f2526f1080000000000000000000000000000000000000000000000000000000081526004810185905260248101839052604401610d36565b5f5b848110156120f0578383828181106120b2576120b2614605565b905060200201356101be5f8888858181106120cf576120cf614605565b602090810292909201358352508101919091526040015f2055600101612098565b506101bb546101bc546101185460408051938452602084019290925290820152606090206101bf555f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600881901c5f90815261014f6020526040812054600160ff84161b161515610cc4565b60026121aa81612a8c565b73ffffffffffffffffffffffffffffffffffffffff85166121f7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34841115612231576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e480545f918261224183614a3e565b9091555090505f6122528634614850565b90505f33888884868a8a60405160200161227297969594939291906148aa565b60405160208183030381529060405280519060200120905061229483826135eb565b808873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8a86888c8c6040516122fa959493929190614a75565b60405180910390a45050505050505050565b600461231781612a8c565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929612341816128d7565b5f85900361237b576040517f7907d79b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610119545f81815261011a60205260409020548435146123c7576040517fead4c30e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101bd5460208501358114612415576040517f2f22b98a0000000000000000000000000000000000000000000000000000000081526004810182905260208601356024820152604401610d36565b5f612422868460016131ea565b90505f61243187848487613667565b905061195c81898c8c8b3560408d013560a08e01356136ef565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d82612475816128d7565b5f609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b7f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c6124d0816128d7565b73ffffffffffffffffffffffffffffffffffffffff831661251d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82815261011b602090815260409182902054915173ffffffffffffffffffffffffffffffffffffffff928316815233928592908716917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60046125de81612a8c565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929612608816128d7565b6126156080860186614956565b90505f0361264f576040517fc01eab5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051608080820183528735825260208089013590830152878301359282019290925260608088013590820152905f9061268c90880188614956565b60405161269a929190614915565b604051809103902090506126c4826101be5f8981526020019081526020015f205461011954612b12565b60608701355f90815260208290526040812090505f612727888a606001358b5f0135856127008e80608001906126fa9190614956565b896138a6565b604080519586526020860194909452928401919091526060830152608082015260a0902090565b905080871461276c576040517fd3664fb30000000000000000000000000000000000000000000000000000000081526004810188905260248101829052604401610d36565b5f8181526101be6020526040902054156127b5576040517f0f06cd1500000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b5f8181526101be60209081526040808320818d01359081905590519092918c01359184917f52bd912b0041a6ec8554b0ffae3cc1cb7b137bade0dc9e3f8f0b6758466d5df99190a4505050505050505050565b5f82815260656020526040902060010154612822816128d7565b610e8683836129d3565b7f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a26612856816128d7565b60da54600160ff84161b161561289d576040517fdb246dde00000000000000000000000000000000000000000000000000000000815260ff83166004820152602401610d36565b60da8054600160ff851690811b9091179091557fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d33610d76565b611f3c81336139a7565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610f3a575f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556129753390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610f3a575f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60da54600160ff83161b811615612ad4576040517fdb246dde00000000000000000000000000000000000000000000000000000000815260ff83166004820152602401610d36565b6002811615610f3a576040517fdb246dde00000000000000000000000000000000000000000000000000000000815260016004820152602401610d36565b8251612b4a576040517f2898482a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060830151612b85576040517f7dc2487d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82602001518260010114612bd75760208301516040517fabefa5e80000000000000000000000000000000000000000000000000000000081526001840160048201526024810191909152604401610d36565b80836020015111612c245760208301516040517fa386ed70000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610d36565b826040015183602001511115610e8657602083015160408085015190517fcbbd795300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610d36565b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001840693505f80600a73ffffffffffffffffffffffffffffffffffffffff168787878787604051602001612cd1959493929190614ac7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052612d0991614b10565b5f60405180830381855afa9150503d805f8114612d41576040519150601f19603f3d011682016040523d82523d5f602084013e612d46565b606091505b509150915081612d82576040517fa71194af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040815114612dca578051604080517ff75db381000000000000000000000000000000000000000000000000000000008152610d369290600401918252602082015260400190565b6020810151604082015161100082141580612e0557507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018114155b15612e46576040517f68dcad5f0000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610d36565b505050505050505050565b5f612e80611f6e60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614850565b14612eb7576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612eec612ee560017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614850565b6001612eee565b565b80825d5050565b5f81815260a66020526040902054600114612f3f576040517f992d87c300000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b5f90815260a66020526040812055565b5f426099541015612f7157609754612f679042614902565b6099555080612f82565b81609a54612f7f9190614902565b90505b609854811115612fbe576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a5550565b612eec6113aa60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614850565b5f54610100900460ff16613088576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610d36565b73ffffffffffffffffffffffffffffffffffffffff84166130d5576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316613122576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61312a613a60565b613132613a60565b61313a613a60565b6131448282613af6565b61316e7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d82856128e1565b6131987f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a26846128e1565b5050600160e4555050565b60da54600160ff83161b1615611f3c576040517fdb246dde00000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610d36565b5f8284604001351161323557604080517f7061440500000000000000000000000000000000000000000000000000000000815290850135600482015260248101849052604401610d36565b613249846101a00135856101600135613c63565b6101bf5460408051610180870135815261014087013560208201526101008701359181019190915260609020146132e157604080516101808601358152610140860135602082015261010086013591810191909152606090206101bf546040517fbc5aad1100000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610d36565b428461012001351061332c576040517fbf81c6e00000000000000000000000000000000000000000000000000000000081526101208501356004820152426024820152604401610d36565b60a0840135613367576040517f2898482a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060868101358252608080880135602084015260a0808901359484019490945260c08801359183019190915260e087013590820152205f8181526101be6020526040908190205491925085013514613409575f8181526101be6020526040908190205481517ffb4cd6ef0000000000000000000000000000000000000000000000000000000081529186013560048301526024820152604401610d36565b61342561341a6101e08601866149b7565b866101c00135613d30565b61343c613436610200860186614956565b85613e36565b6040808501355f81815261011a6020529190912060a08601359055610119556101bd8190556134906101a0850135610160860135610120870135604080519384526020840192909252908201526060902090565b6101bf5560408051831515815260a08601359186359190870135907f1335f1a2b3ff25f07f5fef07dd35d8fb4312c3c73b138e2fad9347b3319ab53c9060200160405180910390a49392505050565b600881901c5f90815261014f6020526040902054600160ff83161b1615613535576040517f335a4a9000000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b600881901c5f90815261014f602052604090208054600160ff84161b17905550565b5f85815b858110156135de57600163ffffffff8616821c811690036135a8576135a187878381811061358b5761358b614605565b90506020020135835f9182526020526040902090565b91506135d6565b6135d3828888848181106135be576135be614605565b905060200201355f9182526020526040902090565b91505b60010161355b565b5090911495945050505050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015f90815261014e60208181526040808420548452848252808420868552929091528083208290555190918391839186917fea3b023b4c8680d4b4824f0143132c95476359a2bb70a81d6c5a36f6918f63399190a4505050565b5f60405184815283602082015260406101008701604083013782608082015260206040870160a083013760a0610140870160c083013761018081016102208701356020810261024089018337602002902061016082015261018090207f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900695945050505050565b6040805160018082528183019092525f916020808301908036833701905050905087815f8151811061372357613723614605565b6020908102919091018101919091525f88815261011b909152604090205473ffffffffffffffffffffffffffffffffffffffff168061378e576040517f69ed70ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7e4f7a8a0000000000000000000000000000000000000000000000000000000081525f9073ffffffffffffffffffffffffffffffffffffffff831690637e4f7a8a906137e6908b908b908890600401614b21565b6020604051808303815f875af1158015613802573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138269190614b78565b90508061385f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518781526020810186905286917f5c885a794662ebe3b08ae0874fc2c88b5343b0223ba9cd2cad92b69c0d0c901f910160405180910390a250505050505050505050565b5f6138b2602084614b97565b156138e9576040517f6426c6c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f729eebce00000000000000000000000000000000000000000000000000000000835b801561399e57602081039050808601357fff0000000000000000000000000000000000000000000000000000000000000081161561394f57604051838152600481fd5b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001817f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018787090893505061390c565b50509392505050565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610f3a576139e681613eca565b6139f1836020613ee9565b604051602001613a02929190614bcf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610d3691600401614c4f565b5f54610100900460ff16612eec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610d36565b5f54610100900460ff16613b8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610d36565b815f03613bc5576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f03613bfe576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60978290556098819055613c128242614902565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a99060600160405180910390a15050565b815f03613ca5578015610f3a576040517f0c25659200000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b80613cdf576040517f5228f4c800000000000000000000000000000000000000000000000000000000815260048101839052602401610d36565b5f82815261014e60205260409020548114610f3a576040517f36459fa00000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610d36565b5f5b82811015611a51576101505f858584818110613d5057613d50614605565b9050602002013581526020019081526020015f20545f14613db957838382818110613d7d57613d7d614605565b905060200201356040517fe5d14425000000000000000000000000000000000000000000000000000000008152600401610d3691815260200190565b816101505f868685818110613dd057613dd0614605565b9050602002013581526020019081526020015f208190555081848483818110613dfb57613dfb614605565b905060200201357f300e6f978eee6a4b0bba78dd8400dc64fd5652dbfc868a2258e16d0977be222b60405160405180910390a3600101613d32565b613e41600283614b97565b15613e7b576040517f0c91d77600000000000000000000000000000000000000000000000000000000815260048101839052602401610d36565b5f805b83811015613ec3576040518582013560f01c9250838301907f3c116827db9db3a30c1a25db8b0ee4bab9d2b223560209cfd839601b621c726d905f90a2600201613e7e565b5050505050565b6060610cc473ffffffffffffffffffffffffffffffffffffffff831660145b60605f613ef7836002614924565b613f02906002614902565b67ffffffffffffffff811115613f1a57613f1a61466e565b6040519080825280601f01601f191660200182016040528015613f44576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110613f7a57613f7a614605565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613fdc57613fdc614605565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f614016846002614924565b614021906001614902565b90505b60018111156140bd577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061406257614062614605565b1a60f81b82828151811061407857614078614605565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c936140b681614c9f565b9050614024565b508315614126576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d36565b9392505050565b5f6020828403121561413d575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114614126575f80fd5b5f6020828403121561417c575f80fd5b813560ff81168114614126575f80fd5b5f6020828403121561419c575f80fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611f3c575f80fd5b5f80604083850312156141d5575f80fd5b8235915060208301356141e7816141a3565b809150509250929050565b5f8083601f840112614202575f80fd5b50813567ffffffffffffffff811115614219575f80fd5b6020830191508360208260051b8501011115614233575f80fd5b9250929050565b5f805f806060858703121561424d575f80fd5b843567ffffffffffffffff811115614263575f80fd5b61426f878288016141f2565b90989097506020870135966040013595509350505050565b5f8083601f840112614297575f80fd5b50813567ffffffffffffffff8111156142ae575f80fd5b602083019150836020828501011115614233575f80fd5b5f805f805f805f8060e0898b0312156142dc575f80fd5b88356142e7816141a3565b975060208901356142f7816141a3565b965060408901359550606089013594506080890135614315816141a3565b935060a089013567ffffffffffffffff811115614330575f80fd5b61433c8b828c01614287565b999c989b50969995989497949560c00135949350505050565b5f805f805f805f805f6101008a8c03121561436e575f80fd5b8935985060208a0135975060408a0135614387816141a3565b965060608a0135614397816141a3565b955060808a013567ffffffffffffffff8111156143b2575f80fd5b6143be8c828d016141f2565b9a9d999c50979a9699979860a08801359760c0810135975060e0013595509350505050565b5f61022082840312156143f4575f80fd5b50919050565b5f6020828403121561440a575f80fd5b813567ffffffffffffffff811115614420575f80fd5b61442c848285016143e3565b949350505050565b5f60208284031215614444575f80fd5b813567ffffffffffffffff81111561445a575f80fd5b82016101408185031215614126575f80fd5b5f805f806040858703121561447f575f80fd5b843567ffffffffffffffff80821115614496575f80fd5b6144a2888389016141f2565b909650945060208701359150808211156144ba575f80fd5b506144c7878288016141f2565b95989497509550505050565b5f805f80606085870312156144e6575f80fd5b84356144f1816141a3565b935060208501359250604085013567ffffffffffffffff811115614513575f80fd5b6144c787828801614287565b5f805f8060608587031215614532575f80fd5b843567ffffffffffffffff80821115614549575f80fd5b61455588838901614287565b9096509450602087013593506040870135915080821115614574575f80fd5b50614581878288016143e3565b91505092959194509250565b5f806040838503121561459e575f80fd5b82356145a9816141a3565b946020939093013593505050565b5f805f606084860312156145c9575f80fd5b833567ffffffffffffffff8111156145df575f80fd5b840160a081870312156145f0575f80fd5b95602085013595506040909401359392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff21833603018112614664575f80fd5b9190910192915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516080810167ffffffffffffffff811182821017156146be576146be61466e565b60405290565b5f82601f8301126146d3575f80fd5b813567ffffffffffffffff808211156146ee576146ee61466e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156147345761473461466e565b8160405283815286602085880101111561474c575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f81360360e081121561477c575f80fd5b61478461469b565b6080821215614791575f80fd5b61479961469b565b9150833582526020840135602083015260408401356040830152606084013560608301528181526080840135602082015260a0840135915067ffffffffffffffff808311156147e6575f80fd5b6147f2368487016146c4565b604083015260c085013592508083111561480a575f80fd5b50614817368386016146c4565b60608201529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610cc457610cc4614823565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401525086604083015285606083015284608083015260c060a08301526148f560c083018486614863565b9998505050505050505050565b80820180821115610cc457610cc4614823565b818382375f9101908152919050565b8082028115828204841417610cc457610cc4614823565b5f6020828403121561494b575f80fd5b8135614126816141a3565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614989575f80fd5b83018035915067ffffffffffffffff8211156149a3575f80fd5b602001915036819003821315614233575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126149ea575f80fd5b83018035915067ffffffffffffffff821115614a04575f80fd5b6020019150600581901b3603821315614233575f80fd5b5f60208284031215614a2b575f80fd5b813563ffffffff81168114614126575f80fd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a6e57614a6e614823565b5060010190565b858152846020820152836040820152608060608201525f614a9a608083018486614863565b979650505050505050565b5f5b83811015614abf578181015183820152602001614aa7565b50505f910152565b8581528460208201528360408201525f8351614aea816060850160208801614aa5565b835190830190614b01816060840160208801614aa5565b01606001979650505050505050565b5f8251614664818460208701614aa5565b604081525f614b34604083018587614863565b8281036020848101919091528451808352858201928201905f5b81811015614b6a57845183529383019391830191600101614b4e565b509098975050505050505050565b5f60208284031215614b88575f80fd5b81518015158114614126575f80fd5b5f82614bca577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f8351614c06816017850160208801614aa5565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614c43816028840160208801614aa5565b01602801949350505050565b602081525f8251806020840152614c6d816040850160208701614aa5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b5f81614cad57614cad614823565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220e76faa7ccb401aa8ec924d7d6bf63bcf46c2847cf7bb3f1ec1063972b83db33564736f6c63430008180033", - "deployedBytecode": "0x6080604052600436106103b3575f3560e01c80637d1e8c55116101e9578063b837dbe911610108578063d05d9c3d1161009d578063e196fb5d1161006d578063e196fb5d14610b42578063e97a1e9e14610b61578063f5b541a614610bd3578063f93e985714610c06575f80fd5b8063d05d9c3d14610abb578063d547741f14610ada578063d5d4b83514610af9578063d84f91e814610b0f575f80fd5b8063c1dc0f07116100d8578063c1dc0f0714610a43578063c211697414610a58578063cc5782f614610a77578063cd9b9e9a14610aa5575f80fd5b8063b837dbe9146109b8578063bc61e733146109cd578063bf3e7505146109fb578063c0729ab114610a2e575f80fd5b80639f3ce55a1161017e578063ac1eff681161014e578063ac1eff6814610939578063ad422ff01461097b578063aea4f74514610990578063b4a5a4b7146109a4575f80fd5b80639f3ce55a146108e0578063a217fddf146108f3578063abd6230d14610906578063abffac321461091a575f80fd5b806391d14854116101b957806391d148541461085a578063921b278e146108ab578063986fcddd146107d05780639ee8b211146108c1575f80fd5b80637d1e8c55146107d05780638116d995146107e35780638be745d114610802578063914e57eb1461082e575f80fd5b80635355420e116102d557806363a283931161026a578063695378f51161023a578063695378f5146107875780636a637967146105835780636e6738431461079d57806373bd07b714610430575f80fd5b806363a28393146106e45780636463fb2a1461070357806366f96e981461072257806367e404ce1461074e575f80fd5b80635c721a0c116102a55780635c721a0c146106355780635ed73ceb146106605780636078bfd81461068c57806360e83cf3146106b8575f80fd5b80635355420e146105e2578063557eac731461060157806358794456146106205780635b7eb4bd14610583575f80fd5b80632c70645c1161034b57806342fbe8421161031b57806342fbe8421461056457806348922ab714610583578063491e0936146105975780634cdd389b146105b6575f80fd5b80632c70645c146104e55780632f2ff15d146104fb57806336568abe1461051a5780633fc08b6514610539575f80fd5b80631e2ff94f116103865780631e2ff94f146104565780631f443da01461046c578063248a9ca31461049857806328958174146104c6575f80fd5b806301ffc9a7146103b757806305861180146103eb5780631065a3991461040f57806311314d0f14610430575b5f80fd5b3480156103c2575f80fd5b506103d66103d136600461412d565b610c32565b60405190151581526020015b60405180910390f35b3480156103f6575f80fd5b506104016101bb5481565b6040519081526020016103e2565b34801561041a575f80fd5b5061042e61042936600461416c565b610cca565b005b34801561043b575f80fd5b50610444600281565b60405160ff90911681526020016103e2565b348015610461575f80fd5b506104016101185481565b348015610477575f80fd5b5061040161048636600461418c565b6101b96020525f908152604090205481565b3480156104a3575f80fd5b506104016104b236600461418c565b5f9081526065602052604090206001015490565b3480156104d1575f80fd5b5061042e6104e036600461418c565b610da2565b3480156104f0575f80fd5b506104016101835481565b348015610506575f80fd5b5061042e6105153660046141c4565b610e62565b348015610525575f80fd5b5061042e6105343660046141c4565b610e8b565b348015610544575f80fd5b5061040161055336600461418c565b60a56020525f908152604090205481565b34801561056f575f80fd5b5061042e61057e36600461423a565b610f3e565b34801561058e575f80fd5b50610444600181565b3480156105a2575f80fd5b5061042e6105b13660046142c5565b611209565b3480156105c1575f80fd5b506104016105d036600461418c565b6101b76020525f908152604090205481565b3480156105ed575f80fd5b5061042e6105fc366004614355565b611531565b34801561060c575f80fd5b5061042e61061b36600461418c565b611968565b34801561062b575f80fd5b5061040160995481565b348015610640575f80fd5b5061040161064f36600461418c565b60a66020525f908152604090205481565b34801561066b575f80fd5b5061040161067a36600461418c565b6101ba6020525f908152604090205481565b348015610697575f80fd5b506104016106a636600461418c565b6101b66020525f908152604090205481565b3480156106c3575f80fd5b506104016106d236600461418c565b6101506020525f908152604090205481565b3480156106ef575f80fd5b5061042e6106fe3660046143fa565b611a2e565b34801561070e575f80fd5b5061042e61071d366004614434565b611a57565b34801561072d575f80fd5b5061040161073c36600461418c565b6101b86020525f908152604090205481565b348015610759575f80fd5b50610762611f3f565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103e2565b348015610792575f80fd5b506104016101195481565b3480156107a8575f80fd5b506104017f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c81565b3480156107db575f80fd5b506104445f81565b3480156107ee575f80fd5b5061042e6107fd36600461446c565b611f77565b34801561080d575f80fd5b5061040161081c36600461418c565b61011a6020525f908152604090205481565b348015610839575f80fd5b5061040161084836600461418c565b61014e6020525f908152604090205481565b348015610865575f80fd5b506103d66108743660046141c4565b5f91825260656020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156108b6575f80fd5b506104016101bf5481565b3480156108cc575f80fd5b506103d66108db36600461418c565b61217c565b61042e6108ee3660046144d3565b61219f565b3480156108fe575f80fd5b506104015f81565b348015610911575f80fd5b50610444600381565b348015610925575f80fd5b5061042e61093436600461451f565b61230c565b348015610944575f80fd5b5061076261095336600461418c565b61011b6020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610986575f80fd5b5061040160985481565b34801561099b575f80fd5b5061042e61244b565b3480156109af575f80fd5b50610444600481565b3480156109c3575f80fd5b5061040160e45481565b3480156109d8575f80fd5b506103d66109e736600461416c565b60da54600160ff9092169190911b16151590565b348015610a06575f80fd5b506104017f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d8281565b348015610a39575f80fd5b50610401609a5481565b348015610a4e575f80fd5b5061040160975481565b348015610a63575f80fd5b5061042e610a7236600461458d565b6124a6565b348015610a82575f80fd5b506103d6610a9136600461418c565b60d96020525f908152604090205460ff1681565b348015610ab0575f80fd5b506104016101bd5481565b348015610ac6575f80fd5b5061042e610ad53660046145b7565b6125d3565b348015610ae5575f80fd5b5061042e610af43660046141c4565b612808565b348015610b04575f80fd5b506104016101bc5481565b348015610b1a575f80fd5b506104017f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a2681565b348015610b4d575f80fd5b5061042e610b5c36600461416c565b61282c565b348015610b6c575f80fd5b50610401604080515f602082018190529181018290527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608201526080810182905260a081019190915260c0016040516020818303038152906040528051906020012081565b348015610bde575f80fd5b506104017f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92981565b348015610c11575f80fd5b50610401610c2036600461418c565b6101be6020525f908152604090205481565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610cc457507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b7f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a26610cf4816128d7565b60da54600160ff84161b16610d3f576040517fb015579f00000000000000000000000000000000000000000000000000000000815260ff831660048201526024015b60405180910390fd5b60da8054600160ff851690811b199091169091557fef04ba2036ccaeab3a59717b51d2b9146b0b0904077177f1148a5418bf1eae23335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a25050565b7f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c610dcc816128d7565b5f82815261011b6020908152604080832054905173ffffffffffffffffffffffffffffffffffffffff90911681523392859290917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b5f82815260656020526040902060010154610e7c816128d7565b610e8683836128e1565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610f30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610d36565b610f3a82826129d3565b5050565b6004610f4981612a8c565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929610f73816128d7565b845f819003610fae576040517fb1504a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610119545f908190610ffa60408051610100810182525f6080820181815260a0830182905260c0830182905260e083018290528252602082015260609181018290528181019190915290565b5f8981526101be60205260408120548a915b87811015611106578d8d8281811061102657611026614605565b90506020028101906110389190614632565b6110419061476b565b81499650935085611081576040517fc0e41e1d00000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b835161108e908387612b12565b8351606001515f90815260208790526040902096506110be86885f1c866020015187604001518860600151612c79565b83516060808201519151602080880151604080519889529188019490945286810191909152908501899052608085019190915260a0909320845190930151915060010161100c565b50818a1461114a576040517fd3664fb3000000000000000000000000000000000000000000000000000000008152600481018b905260248101839052604401610d36565b5f8281526101be602052604090205415611193576040517f0f06cd1500000000000000000000000000000000000000000000000000000000815260048101839052602401610d36565b5f8281526101be6020526040812082905581908e908e90816111b7576111b7614605565b90506020028101906111c99190614632565b6040516020909101359084907f52bd912b0041a6ec8554b0ffae3cc1cb7b137bade0dc9e3f8f0b6758466d5df9905f90a450505050505050505050505050565b611211612e51565b85878484875f5a90506112246003612a8c565b61125861125260017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b8f612eee565b5f8e8e8e8e8b8e8e60405160200161127697969594939291906148aa565b60405160208183030381529060405280519060200120905061129781612ef5565b6112a96112a48d8f614902565b612f4f565b5f808f73ffffffffffffffffffffffffffffffffffffffff168e8d8d6040516112d3929190614915565b5f6040518083038185875af1925050503d805f811461130d576040519150601f19603f3d011682016040523d82523d5f602084013e611312565b606091505b50915091508161137c5780511561132c5780518082602001fd5b8f6040517f54613443000000000000000000000000000000000000000000000000000000008152600401610d36919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6113b06113aa60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b5f612eee565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a250508615905061151957855f84900361146857853b158015611466573a5a61140461bc7c86614902565b61140e9190614850565b6114189190614924565b9150818811156114625773ffffffffffffffffffffffffffffffffffffffff87166108fc611446848b614850565b6040518115909202915f818181858888f1935050505050611466565b8791505b505b5f73ffffffffffffffffffffffffffffffffffffffff84161561148b578361148d565b335b90505f8173ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050905080611515576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610d36565b5050505b505050505050611527612fc4565b5050505050505050565b5f54610100900460ff161580801561154f57505f54600160ff909116105b806115685750303b15801561156857505f5460ff166001145b6115f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610d36565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015611650575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b73ffffffffffffffffffffffffffffffffffffffff881661169d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5b85811015611774575f8787838181106116ba576116ba614605565b90506020020160208101906116cf919061493b565b73ffffffffffffffffffffffffffffffffffffffff160361171c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61176c7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92988888481811061175257611752614605565b9050602002016020810190611767919061493b565b6128e1565b60010161169f565b5061177f5f886128e1565b6117a97f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c886128e1565b6117b587888686612ff2565b7f033d11f27e62ab919708ec716731da80d261a6e4253259b7acde9bf89d28ec1880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a161790556101198990555f89815261011a602090815260408083208d905580518083018490528082018490527f072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd60608083018290526080830186905260a08084018790528451808503909101815260c08401855280519086012086526101be85528386208f905560e08301869052610100830186905261012083019190915261014082018590526101608083018690528351808403909101815261018083019384905280519401939093206101bd558382526101a08101939093526101c090920184905290206101bf55801561195c575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050505050565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d82611992816128d7565b5f805f4260995410156119b7576097546119ac9042614902565b6099555060016119c9565b609a548510156119c957849250600191505b609885905580806119d75750815b156119e257609a8390555b60408051868152831515602082015282151581830152905133917fbc3dc0cb5c15c51c81316450d44048838bb478b9809447d01c766a06f3e9f2c8919081900360600190a25050505050565b6001611a39816131a3565b5f611a43816128d7565b611a5183610119545f6131ea565b50505050565b611a5f612e51565b60a08101803590611a73906080840161493b565b611a81610120840184614956565b611a92610100860160e0870161493b565b5f5a9050611aa06003612a8c565b6101008701355f908152610150602052604081205490819003611aef576040517f4e68667500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611af988806149b7565b90508114611b485780611b0c89806149b7565b6040517f5e3fd6ad0000000000000000000000000000000000000000000000000000000081526004810193909352602483015250604401610d36565b611b5588602001356134df565b611b6a6112a460c08a013560a08b0135614902565b5f611b7b60808a0160608b0161493b565b611b8b60a08b0160808c0161493b565b60a08b013560c08c013560208d0135611ba86101208f018f614956565b604051602001611bbe97969594939291906148aa565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209050611c1f81611c048b806149b7565b611c1460608e0160408f01614a1b565b8d6101000135613557565b611c55576040517fb05e92fa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c98611c8360017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b611c9360808c0160608d0161493b565b612eee565b5f80611caa60a08c0160808d0161493b565b73ffffffffffffffffffffffffffffffffffffffff1660c08c0135611cd36101208e018e614956565b604051611ce1929190614915565b5f6040518083038185875af1925050503d805f8114611d1b576040519150601f19603f3d011682016040523d82523d5f602084013e611d20565b606091505b509150915081611d9557805115611d3a5780518082602001fd5b611d4a60a08c0160808d0161493b565b6040517f5461344300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610d36565b611dc36113aa60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b60405183907fa4c827e719e911e8f19393ccdb85b5102f08f0910604d340ba38390b7ff2ab0e905f90a2505050505f861115611f2e57855f849003611e7d57853b158015611e7b573a5a611e1961bc7c86614902565b611e239190614850565b611e2d9190614924565b915081881115611e775773ffffffffffffffffffffffffffffffffffffffff87166108fc611e5b848b614850565b6040518115909202915f818181858888f1935050505050611e7b565b8791505b505b5f73ffffffffffffffffffffffffffffffffffffffff841615611ea05783611ea2565b335b90505f8173ffffffffffffffffffffffffffffffffffffffff166108fc8490811502906040515f60405180830381858888f19350505050905080611f2a576040517fa57c4df400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610d36565b5050505b505050505050611f3c612fc4565b50565b5f611f72611f6e60017f3095e8dc547eeb8bf90020768c67e29e974614469d8f71638ac29f39b96e4893614850565b5c90565b905090565b5f54600590610100900460ff16158015611f9757505f5460ff8083169116105b612023576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610d36565b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100179055838214612096576040517f2526f1080000000000000000000000000000000000000000000000000000000081526004810185905260248101839052604401610d36565b5f5b848110156120f0578383828181106120b2576120b2614605565b905060200201356101be5f8888858181106120cf576120cf614605565b602090810292909201358352508101919091526040015f2055600101612098565b506101bb546101bc546101185460408051938452602084019290925290820152606090206101bf555f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b600881901c5f90815261014f6020526040812054600160ff84161b161515610cc4565b60026121aa81612a8c565b73ffffffffffffffffffffffffffffffffffffffff85166121f7576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34841115612231576040517fb03b693200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e480545f918261224183614a3e565b9091555090505f6122528634614850565b90505f33888884868a8a60405160200161227297969594939291906148aa565b60405160208183030381529060405280519060200120905061229483826135eb565b808873ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fe856c2b8bd4eb0027ce32eeaf595c21b0b6b4644b326e5b7bd80a1cf8db72e6c8a86888c8c6040516122fa959493929190614a75565b60405180910390a45050505050505050565b600461231781612a8c565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929612341816128d7565b5f85900361237b576040517f7907d79b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610119545f81815261011a60205260409020548435146123c7576040517fead4c30e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101bd5460208501358114612415576040517f2f22b98a0000000000000000000000000000000000000000000000000000000081526004810182905260208601356024820152604401610d36565b5f612422868460016131ea565b90505f61243187848487613667565b905061195c81898c8c8b3560408d013560a08e01356136ef565b7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d82612475816128d7565b5f609a81905560405133917fba88c025b0cbb77022c0c487beef24f759f1e4be2f51a205bc427cee19c2eaa691a250565b7f32937fd5162e282df7e9a14a5073a2425321c7966eaf70ed6c838a1006d84c4c6124d0816128d7565b73ffffffffffffffffffffffffffffffffffffffff831661251d576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f82815261011b602090815260409182902054915173ffffffffffffffffffffffffffffffffffffffff928316815233928592908716917f4a29db3fc6b42bda201e4b4d69ce8d575eeeba5f153509c0d0a342af0f1bd021910160405180910390a4505f90815261011b6020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60046125de81612a8c565b7f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929612608816128d7565b6126156080860186614956565b90505f0361264f576040517fc01eab5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051608080820183528735825260208089013590830152878301359282019290925260608088013590820152905f9061268c90880188614956565b60405161269a929190614915565b604051809103902090506126c4826101be5f8981526020019081526020015f205461011954612b12565b60608701355f90815260208290526040812090505f612727888a606001358b5f0135856127008e80608001906126fa9190614956565b896138a6565b604080519586526020860194909452928401919091526060830152608082015260a0902090565b905080871461276c576040517fd3664fb30000000000000000000000000000000000000000000000000000000081526004810188905260248101829052604401610d36565b5f8181526101be6020526040902054156127b5576040517f0f06cd1500000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b5f8181526101be60209081526040808320818d01359081905590519092918c01359184917f52bd912b0041a6ec8554b0ffae3cc1cb7b137bade0dc9e3f8f0b6758466d5df99190a4505050505050505050565b5f82815260656020526040902060010154612822816128d7565b610e8683836129d3565b7f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a26612856816128d7565b60da54600160ff84161b161561289d576040517fdb246dde00000000000000000000000000000000000000000000000000000000815260ff83166004820152602401610d36565b60da8054600160ff851690811b9091179091557fab40a374bc51de372200a8bc981af8c9ecdc08dfdaef0bb6e09f88f3c616ef3d33610d76565b611f3c81336139a7565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610f3a575f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556129753390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610f3a575f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60da54600160ff83161b811615612ad4576040517fdb246dde00000000000000000000000000000000000000000000000000000000815260ff83166004820152602401610d36565b6002811615610f3a576040517fdb246dde00000000000000000000000000000000000000000000000000000000815260016004820152602401610d36565b8251612b4a576040517f2898482a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060830151612b85576040517f7dc2487d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82602001518260010114612bd75760208301516040517fabefa5e80000000000000000000000000000000000000000000000000000000081526001840160048201526024810191909152604401610d36565b80836020015111612c245760208301516040517fa386ed70000000000000000000000000000000000000000000000000000000008152600481019190915260248101829052604401610d36565b826040015183602001511115610e8657602083015160408085015190517fcbbd795300000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610d36565b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001840693505f80600a73ffffffffffffffffffffffffffffffffffffffff168787878787604051602001612cd1959493929190614ac7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052612d0991614b10565b5f60405180830381855afa9150503d805f8114612d41576040519150601f19603f3d011682016040523d82523d5f602084013e612d46565b606091505b509150915081612d82576040517fa71194af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040815114612dca578051604080517ff75db381000000000000000000000000000000000000000000000000000000008152610d369290600401918252602082015260400190565b6020810151604082015161100082141580612e0557507f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018114155b15612e46576040517f68dcad5f0000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610d36565b505050505050505050565b5f612e80611f6e60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614850565b14612eb7576040517f37ed32e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612eec612ee560017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614850565b6001612eee565b565b80825d5050565b5f81815260a66020526040902054600114612f3f576040517f992d87c300000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b5f90815260a66020526040812055565b5f426099541015612f7157609754612f679042614902565b6099555080612f82565b81609a54612f7f9190614902565b90505b609854811115612fbe576040517fa74c1c5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b609a5550565b612eec6113aa60017f084edf88d5959696dcc7aab5c8674a33a1ef78f37dda21b782ed03bddb22ade5614850565b5f54610100900460ff16613088576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610d36565b73ffffffffffffffffffffffffffffffffffffffff84166130d5576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8316613122576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61312a613a60565b613132613a60565b61313a613a60565b6131448282613af6565b61316e7f1185e52d62bfbbea270e57d3d09733d221b53ab7a18bae82bb3c6c74bab16d82856128e1565b6131987f356a809dfdea9198dd76fb76bf6d403ecf13ea675eb89e1eda2db2c4a4676a26846128e1565b5050600160e4555050565b60da54600160ff83161b1615611f3c576040517fdb246dde00000000000000000000000000000000000000000000000000000000815260ff82166004820152602401610d36565b5f8284604001351161323557604080517f7061440500000000000000000000000000000000000000000000000000000000815290850135600482015260248101849052604401610d36565b613249846101a00135856101600135613c63565b6101bf5460408051610180870135815261014087013560208201526101008701359181019190915260609020146132e157604080516101808601358152610140860135602082015261010086013591810191909152606090206101bf546040517fbc5aad1100000000000000000000000000000000000000000000000000000000815260048101929092526024820152604401610d36565b428461012001351061332c576040517fbf81c6e00000000000000000000000000000000000000000000000000000000081526101208501356004820152426024820152604401610d36565b60a0840135613367576040517f2898482a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516060868101358252608080880135602084015260a0808901359484019490945260c08801359183019190915260e087013590820152205f8181526101be6020526040908190205491925085013514613409575f8181526101be6020526040908190205481517ffb4cd6ef0000000000000000000000000000000000000000000000000000000081529186013560048301526024820152604401610d36565b61342561341a6101e08601866149b7565b866101c00135613d30565b61343c613436610200860186614956565b85613e36565b6040808501355f81815261011a6020529190912060a08601359055610119556101bd8190556134906101a0850135610160860135610120870135604080519384526020840192909252908201526060902090565b6101bf5560408051831515815260a08601359186359190870135907f1335f1a2b3ff25f07f5fef07dd35d8fb4312c3c73b138e2fad9347b3319ab53c9060200160405180910390a49392505050565b600881901c5f90815261014f6020526040902054600160ff83161b1615613535576040517f335a4a9000000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b600881901c5f90815261014f602052604090208054600160ff84161b17905550565b5f85815b858110156135de57600163ffffffff8616821c811690036135a8576135a187878381811061358b5761358b614605565b90506020020135835f9182526020526040902090565b91506135d6565b6135d3828888848181106135be576135be614605565b905060200201355f9182526020526040902090565b91505b60010161355b565b5090911495945050505050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015f90815261014e60208181526040808420548452848252808420868552929091528083208290555190918391839186917fea3b023b4c8680d4b4824f0143132c95476359a2bb70a81d6c5a36f6918f63399190a4505050565b5f60405184815283602082015260406101008701604083013782608082015260206040870160a083013760a0610140870160c083013761018081016102208701356020810261024089018337602002902061016082015261018090207f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001900695945050505050565b6040805160018082528183019092525f916020808301908036833701905050905087815f8151811061372357613723614605565b6020908102919091018101919091525f88815261011b909152604090205473ffffffffffffffffffffffffffffffffffffffff168061378e576040517f69ed70ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f7e4f7a8a0000000000000000000000000000000000000000000000000000000081525f9073ffffffffffffffffffffffffffffffffffffffff831690637e4f7a8a906137e6908b908b908890600401614b21565b6020604051808303815f875af1158015613802573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138269190614b78565b90508061385f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518781526020810186905286917f5c885a794662ebe3b08ae0874fc2c88b5343b0223ba9cd2cad92b69c0d0c901f910160405180910390a250505050505050505050565b5f6138b2602084614b97565b156138e9576040517f6426c6c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f729eebce00000000000000000000000000000000000000000000000000000000835b801561399e57602081039050808601357fff0000000000000000000000000000000000000000000000000000000000000081161561394f57604051838152600481fd5b7f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001817f73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff000000018787090893505061390c565b50509392505050565b5f82815260656020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610f3a576139e681613eca565b6139f1836020613ee9565b604051602001613a02929190614bcf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610d3691600401614c4f565b5f54610100900460ff16612eec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610d36565b5f54610100900460ff16613b8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610d36565b815f03613bc5576040517fb5ed5a3b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805f03613bfe576040517fd10d72bb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60978290556098819055613c128242614902565b60998190556097546098546040805192835260208301919091528101919091527f8f805c372b66240792580418b7328c0c554ae235f0932475c51b026887fe26a99060600160405180910390a15050565b815f03613ca5578015610f3a576040517f0c25659200000000000000000000000000000000000000000000000000000000815260048101829052602401610d36565b80613cdf576040517f5228f4c800000000000000000000000000000000000000000000000000000000815260048101839052602401610d36565b5f82815261014e60205260409020548114610f3a576040517f36459fa00000000000000000000000000000000000000000000000000000000081526004810183905260248101829052604401610d36565b5f5b82811015611a51576101505f858584818110613d5057613d50614605565b9050602002013581526020019081526020015f20545f14613db957838382818110613d7d57613d7d614605565b905060200201356040517fe5d14425000000000000000000000000000000000000000000000000000000008152600401610d3691815260200190565b816101505f868685818110613dd057613dd0614605565b9050602002013581526020019081526020015f208190555081848483818110613dfb57613dfb614605565b905060200201357f300e6f978eee6a4b0bba78dd8400dc64fd5652dbfc868a2258e16d0977be222b60405160405180910390a3600101613d32565b613e41600283614b97565b15613e7b576040517f0c91d77600000000000000000000000000000000000000000000000000000000815260048101839052602401610d36565b5f805b83811015613ec3576040518582013560f01c9250838301907f3c116827db9db3a30c1a25db8b0ee4bab9d2b223560209cfd839601b621c726d905f90a2600201613e7e565b5050505050565b6060610cc473ffffffffffffffffffffffffffffffffffffffff831660145b60605f613ef7836002614924565b613f02906002614902565b67ffffffffffffffff811115613f1a57613f1a61466e565b6040519080825280601f01601f191660200182016040528015613f44576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000815f81518110613f7a57613f7a614605565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110613fdc57613fdc614605565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505f614016846002614924565b614021906001614902565b90505b60018111156140bd577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061406257614062614605565b1a60f81b82828151811061407857614078614605565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060049490941c936140b681614c9f565b9050614024565b508315614126576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d36565b9392505050565b5f6020828403121561413d575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114614126575f80fd5b5f6020828403121561417c575f80fd5b813560ff81168114614126575f80fd5b5f6020828403121561419c575f80fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611f3c575f80fd5b5f80604083850312156141d5575f80fd5b8235915060208301356141e7816141a3565b809150509250929050565b5f8083601f840112614202575f80fd5b50813567ffffffffffffffff811115614219575f80fd5b6020830191508360208260051b8501011115614233575f80fd5b9250929050565b5f805f806060858703121561424d575f80fd5b843567ffffffffffffffff811115614263575f80fd5b61426f878288016141f2565b90989097506020870135966040013595509350505050565b5f8083601f840112614297575f80fd5b50813567ffffffffffffffff8111156142ae575f80fd5b602083019150836020828501011115614233575f80fd5b5f805f805f805f8060e0898b0312156142dc575f80fd5b88356142e7816141a3565b975060208901356142f7816141a3565b965060408901359550606089013594506080890135614315816141a3565b935060a089013567ffffffffffffffff811115614330575f80fd5b61433c8b828c01614287565b999c989b50969995989497949560c00135949350505050565b5f805f805f805f805f6101008a8c03121561436e575f80fd5b8935985060208a0135975060408a0135614387816141a3565b965060608a0135614397816141a3565b955060808a013567ffffffffffffffff8111156143b2575f80fd5b6143be8c828d016141f2565b9a9d999c50979a9699979860a08801359760c0810135975060e0013595509350505050565b5f61022082840312156143f4575f80fd5b50919050565b5f6020828403121561440a575f80fd5b813567ffffffffffffffff811115614420575f80fd5b61442c848285016143e3565b949350505050565b5f60208284031215614444575f80fd5b813567ffffffffffffffff81111561445a575f80fd5b82016101408185031215614126575f80fd5b5f805f806040858703121561447f575f80fd5b843567ffffffffffffffff80821115614496575f80fd5b6144a2888389016141f2565b909650945060208701359150808211156144ba575f80fd5b506144c7878288016141f2565b95989497509550505050565b5f805f80606085870312156144e6575f80fd5b84356144f1816141a3565b935060208501359250604085013567ffffffffffffffff811115614513575f80fd5b6144c787828801614287565b5f805f8060608587031215614532575f80fd5b843567ffffffffffffffff80821115614549575f80fd5b61455588838901614287565b9096509450602087013593506040870135915080821115614574575f80fd5b50614581878288016143e3565b91505092959194509250565b5f806040838503121561459e575f80fd5b82356145a9816141a3565b946020939093013593505050565b5f805f606084860312156145c9575f80fd5b833567ffffffffffffffff8111156145df575f80fd5b840160a081870312156145f0575f80fd5b95602085013595506040909401359392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff21833603018112614664575f80fd5b9190910192915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516080810167ffffffffffffffff811182821017156146be576146be61466e565b60405290565b5f82601f8301126146d3575f80fd5b813567ffffffffffffffff808211156146ee576146ee61466e565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156147345761473461466e565b8160405283815286602085880101111561474c575f80fd5b836020870160208301375f602085830101528094505050505092915050565b5f81360360e081121561477c575f80fd5b61478461469b565b6080821215614791575f80fd5b61479961469b565b9150833582526020840135602083015260408401356040830152606084013560608301528181526080840135602082015260a0840135915067ffffffffffffffff808311156147e6575f80fd5b6147f2368487016146c4565b604083015260c085013592508083111561480a575f80fd5b50614817368386016146c4565b60608201529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610cc457610cc4614823565b81835281816020850137505f602082840101525f60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff808a16835280891660208401525086604083015285606083015284608083015260c060a08301526148f560c083018486614863565b9998505050505050505050565b80820180821115610cc457610cc4614823565b818382375f9101908152919050565b8082028115828204841417610cc457610cc4614823565b5f6020828403121561494b575f80fd5b8135614126816141a3565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614989575f80fd5b83018035915067ffffffffffffffff8211156149a3575f80fd5b602001915036819003821315614233575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126149ea575f80fd5b83018035915067ffffffffffffffff821115614a04575f80fd5b6020019150600581901b3603821315614233575f80fd5b5f60208284031215614a2b575f80fd5b813563ffffffff81168114614126575f80fd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614a6e57614a6e614823565b5060010190565b858152846020820152836040820152608060608201525f614a9a608083018486614863565b979650505050505050565b5f5b83811015614abf578181015183820152602001614aa7565b50505f910152565b8581528460208201528360408201525f8351614aea816060850160208801614aa5565b835190830190614b01816060840160208801614aa5565b01606001979650505050505050565b5f8251614664818460208701614aa5565b604081525f614b34604083018587614863565b8281036020848101919091528451808352858201928201905f5b81811015614b6a57845183529383019391830191600101614b4e565b509098975050505050505050565b5f60208284031215614b88575f80fd5b81518015158114614126575f80fd5b5f82614bca577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081525f8351614c06816017850160208801614aa5565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614c43816028840160208801614aa5565b01602801949350505050565b602081525f8251806020840152614c6d816040850160208701614aa5565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b5f81614cad57614cad614823565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220e76faa7ccb401aa8ec924d7d6bf63bcf46c2847cf7bb3f1ec1063972b83db33564736f6c63430008180033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/contracts/src/_testing/integration/LineaRollupV5.sol b/contracts/src/_testing/integration/LineaRollupV5.sol deleted file mode 100644 index cc40de92..00000000 --- a/contracts/src/_testing/integration/LineaRollupV5.sol +++ /dev/null @@ -1,3820 +0,0 @@ -// Sources flattened with hardhat v2.22.3 https://hardhat.org - -// SPDX-License-Identifier: AGPL-3.0 AND Apache-2.0 AND MIT - -// File @openzeppelin/contracts-upgradeable/access/IAccessControlUpgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) - -pragma solidity ^0.8.0; - -/** - * @dev External interface of AccessControl declared to support ERC165 detection. - */ -interface IAccessControlUpgradeable { - /** - * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` - * - * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite - * {RoleAdminChanged} not being emitted signaling this. - * - * _Available since v3.1._ - */ - event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); - - /** - * @dev Emitted when `account` is granted `role`. - * - * `sender` is the account that originated the contract call, an admin role - * bearer except when using {AccessControl-_setupRole}. - */ - event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Emitted when `account` is revoked `role`. - * - * `sender` is the account that originated the contract call: - * - if using `revokeRole`, it is the admin role bearer - * - if using `renounceRole`, it is the role bearer (i.e. `account`) - */ - event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); - - /** - * @dev Returns `true` if `account` has been granted `role`. - */ - function hasRole(bytes32 role, address account) external view returns (bool); - - /** - * @dev Returns the admin role that controls `role`. See {grantRole} and - * {revokeRole}. - * - * To change a role's admin, use {AccessControl-_setRoleAdmin}. - */ - function getRoleAdmin(bytes32 role) external view returns (bytes32); - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function grantRole(bytes32 role, address account) external; - - /** - * @dev Revokes `role` from `account`. - * - * If `account` had been granted `role`, emits a {RoleRevoked} event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - */ - function revokeRole(bytes32 role, address account) external; - - /** - * @dev Revokes `role` from the calling account. - * - * Roles are often managed via {grantRole} and {revokeRole}: this function's - * purpose is to provide a mechanism for accounts to lose their privileges - * if they are compromised (such as when a trusted device is misplaced). - * - * If the calling account had been granted `role`, emits a {RoleRevoked} - * event. - * - * Requirements: - * - * - the caller must be `account`. - */ - function renounceRole(bytes32 role, address account) external; -} - -// File @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) - -pragma solidity ^0.8.1; - -/** - * @dev Collection of functions related to the address type - */ -library AddressUpgradeable { - /** - * @dev Returns true if `account` is a contract. - * - * [IMPORTANT] - * ==== - * It is unsafe to assume that an address for which this function returns - * false is an externally-owned account (EOA) and not a contract. - * - * Among others, `isContract` will return false for the following - * types of addresses: - * - * - an externally-owned account - * - a contract in construction - * - an address where a contract will be created - * - an address where a contract lived, but was destroyed - * - * Furthermore, `isContract` will also return true if the target contract within - * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, - * which only has an effect at the end of a transaction. - * ==== - * - * [IMPORTANT] - * ==== - * You shouldn't rely on `isContract` to protect against flash loan attacks! - * - * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets - * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract - * constructor. - * ==== - */ - function isContract(address account) internal view returns (bool) { - // This method relies on extcodesize/address.code.length, which returns 0 - // for contracts in construction, since the code is only stored at the end - // of the constructor execution. - - return account.code.length > 0; - } - - /** - * @dev Replacement for Solidity's `transfer`: sends `amount` wei to - * `recipient`, forwarding all available gas and reverting on errors. - * - * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost - * of certain opcodes, possibly making contracts go over the 2300 gas limit - * imposed by `transfer`, making them unable to receive funds via - * `transfer`. {sendValue} removes this limitation. - * - * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. - * - * IMPORTANT: because control is transferred to `recipient`, care must be - * taken to not create reentrancy vulnerabilities. Consider using - * {ReentrancyGuard} or the - * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. - */ - function sendValue(address payable recipient, uint256 amount) internal { - require(address(this).balance >= amount, "Address: insufficient balance"); - - (bool success, ) = recipient.call{ value: amount }(""); - require(success, "Address: unable to send value, recipient may have reverted"); - } - - /** - * @dev Performs a Solidity function call using a low level `call`. A - * plain `call` is an unsafe replacement for a function call: use this - * function instead. - * - * If `target` reverts with a revert reason, it is bubbled up by this - * function (like regular Solidity function calls). - * - * Returns the raw returned data. To convert to the expected return value, - * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. - * - * Requirements: - * - * - `target` must be a contract. - * - calling `target` with `data` must not revert. - * - * _Available since v3.1._ - */ - function functionCall(address target, bytes memory data) internal returns (bytes memory) { - return functionCallWithValue(target, data, 0, "Address: low-level call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with - * `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { - return functionCallWithValue(target, data, 0, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but also transferring `value` wei to `target`. - * - * Requirements: - * - * - the calling contract must have an ETH balance of at least `value`. - * - the called Solidity function must be `payable`. - * - * _Available since v3.1._ - */ - function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { - return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); - } - - /** - * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but - * with `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCallWithValue( - address target, - bytes memory data, - uint256 value, - string memory errorMessage - ) internal returns (bytes memory) { - require(address(this).balance >= value, "Address: insufficient balance for call"); - (bool success, bytes memory returndata) = target.call{ value: value }(data); - return verifyCallResultFromTarget(target, success, returndata, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but performing a static call. - * - * _Available since v3.3._ - */ - function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { - return functionStaticCall(target, data, "Address: low-level static call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], - * but performing a static call. - * - * _Available since v3.3._ - */ - function functionStaticCall( - address target, - bytes memory data, - string memory errorMessage - ) internal view returns (bytes memory) { - (bool success, bytes memory returndata) = target.staticcall(data); - return verifyCallResultFromTarget(target, success, returndata, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but performing a delegate call. - * - * _Available since v3.4._ - */ - function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { - return functionDelegateCall(target, data, "Address: low-level delegate call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], - * but performing a delegate call. - * - * _Available since v3.4._ - */ - function functionDelegateCall( - address target, - bytes memory data, - string memory errorMessage - ) internal returns (bytes memory) { - (bool success, bytes memory returndata) = target.delegatecall(data); - return verifyCallResultFromTarget(target, success, returndata, errorMessage); - } - - /** - * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling - * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. - * - * _Available since v4.8._ - */ - function verifyCallResultFromTarget( - address target, - bool success, - bytes memory returndata, - string memory errorMessage - ) internal view returns (bytes memory) { - if (success) { - if (returndata.length == 0) { - // only check isContract if the call was successful and the return data is empty - // otherwise we already know that it was a contract - require(isContract(target), "Address: call to non-contract"); - } - return returndata; - } else { - _revert(returndata, errorMessage); - } - } - - /** - * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the - * revert reason or using the provided one. - * - * _Available since v4.3._ - */ - function verifyCallResult( - bool success, - bytes memory returndata, - string memory errorMessage - ) internal pure returns (bytes memory) { - if (success) { - return returndata; - } else { - _revert(returndata, errorMessage); - } - } - - function _revert(bytes memory returndata, string memory errorMessage) private pure { - // Look for revert reason and bubble it up if present - if (returndata.length > 0) { - // The easiest way to bubble the revert reason is using memory via assembly - /// @solidity memory-safe-assembly - assembly { - let returndata_size := mload(returndata) - revert(add(32, returndata), returndata_size) - } - } else { - revert(errorMessage); - } - } -} - -// File @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) - -pragma solidity ^0.8.2; - -/** - * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed - * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an - * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer - * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. - * - * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be - * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in - * case an upgrade adds a module that needs to be initialized. - * - * For example: - * - * [.hljs-theme-light.nopadding] - * ```solidity - * contract MyToken is ERC20Upgradeable { - * function initialize() initializer public { - * __ERC20_init("MyToken", "MTK"); - * } - * } - * - * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { - * function initializeV2() reinitializer(2) public { - * __ERC20Permit_init("MyToken"); - * } - * } - * ``` - * - * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as - * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. - * - * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure - * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. - * - * [CAUTION] - * ==== - * Avoid leaving a contract uninitialized. - * - * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation - * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke - * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: - * - * [.hljs-theme-light.nopadding] - * ``` - * /// @custom:oz-upgrades-unsafe-allow constructor - * constructor() { - * _disableInitializers(); - * } - * ``` - * ==== - */ -abstract contract Initializable { - /** - * @dev Indicates that the contract has been initialized. - * @custom:oz-retyped-from bool - */ - uint8 private _initialized; - - /** - * @dev Indicates that the contract is in the process of being initialized. - */ - bool private _initializing; - - /** - * @dev Triggered when the contract has been initialized or reinitialized. - */ - event Initialized(uint8 version); - - /** - * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, - * `onlyInitializing` functions can be used to initialize parent contracts. - * - * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a - * constructor. - * - * Emits an {Initialized} event. - */ - modifier initializer() { - bool isTopLevelCall = !_initializing; - require( - (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), - "Initializable: contract is already initialized" - ); - _initialized = 1; - if (isTopLevelCall) { - _initializing = true; - } - _; - if (isTopLevelCall) { - _initializing = false; - emit Initialized(1); - } - } - - /** - * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the - * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be - * used to initialize parent contracts. - * - * A reinitializer may be used after the original initialization step. This is essential to configure modules that - * are added through upgrades and that require initialization. - * - * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` - * cannot be nested. If one is invoked in the context of another, execution will revert. - * - * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in - * a contract, executing them in the right order is up to the developer or operator. - * - * WARNING: setting the version to 255 will prevent any future reinitialization. - * - * Emits an {Initialized} event. - */ - modifier reinitializer(uint8 version) { - require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); - _initialized = version; - _initializing = true; - _; - _initializing = false; - emit Initialized(version); - } - - /** - * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the - * {initializer} and {reinitializer} modifiers, directly or indirectly. - */ - modifier onlyInitializing() { - require(_initializing, "Initializable: contract is not initializing"); - _; - } - - /** - * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. - * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized - * to any version. It is recommended to use this to lock implementation contracts that are designed to be called - * through proxies. - * - * Emits an {Initialized} event the first time it is successfully executed. - */ - function _disableInitializers() internal virtual { - require(!_initializing, "Initializable: contract is initializing"); - if (_initialized != type(uint8).max) { - _initialized = type(uint8).max; - emit Initialized(type(uint8).max); - } - } - - /** - * @dev Returns the highest version that has been initialized. See {reinitializer}. - */ - function _getInitializedVersion() internal view returns (uint8) { - return _initialized; - } - - /** - * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. - */ - function _isInitializing() internal view returns (bool) { - return _initializing; - } -} - -// File @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Provides information about the current execution context, including the - * sender of the transaction and its data. While these are generally available - * via msg.sender and msg.data, they should not be accessed in such a direct - * manner, since when dealing with meta-transactions the account sending and - * paying for execution may not be the actual sender (as far as an application - * is concerned). - * - * This contract is only required for intermediate, library-like contracts. - */ -abstract contract ContextUpgradeable is Initializable { - function __Context_init() internal onlyInitializing {} - - function __Context_init_unchained() internal onlyInitializing {} - function _msgSender() internal view virtual returns (address) { - return msg.sender; - } - - function _msgData() internal view virtual returns (bytes calldata) { - return msg.data; - } - - function _contextSuffixLength() internal view virtual returns (uint256) { - return 0; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -// File @openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Interface of the ERC165 standard, as defined in the - * https://eips.ethereum.org/EIPS/eip-165[EIP]. - * - * Implementers can declare support of contract interfaces, which can then be - * queried by others ({ERC165Checker}). - * - * For an implementation, see {ERC165}. - */ -interface IERC165Upgradeable { - /** - * @dev Returns true if this contract implements the interface defined by - * `interfaceId`. See the corresponding - * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] - * to learn more about how these ids are created. - * - * This function call must use less than 30 000 gas. - */ - function supportsInterface(bytes4 interfaceId) external view returns (bool); -} - -// File @openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Implementation of the {IERC165} interface. - * - * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check - * for the additional interface id that will be supported. For example: - * - * ```solidity - * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); - * } - * ``` - * - * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. - */ -abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { - function __ERC165_init() internal onlyInitializing {} - - function __ERC165_init_unchained() internal onlyInitializing {} - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IERC165Upgradeable).interfaceId; - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[50] private __gap; -} - -// File @openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Standard math utilities missing in the Solidity language. - */ -library MathUpgradeable { - enum Rounding { - Down, // Toward negative infinity - Up, // Toward infinity - Zero // Toward zero - } - - /** - * @dev Returns the largest of two numbers. - */ - function max(uint256 a, uint256 b) internal pure returns (uint256) { - return a > b ? a : b; - } - - /** - * @dev Returns the smallest of two numbers. - */ - function min(uint256 a, uint256 b) internal pure returns (uint256) { - return a < b ? a : b; - } - - /** - * @dev Returns the average of two numbers. The result is rounded towards - * zero. - */ - function average(uint256 a, uint256 b) internal pure returns (uint256) { - // (a + b) / 2 can overflow. - return (a & b) + (a ^ b) / 2; - } - - /** - * @dev Returns the ceiling of the division of two numbers. - * - * This differs from standard division with `/` in that it rounds up instead - * of rounding down. - */ - function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { - // (a + b - 1) / b can overflow on addition, so we distribute. - return a == 0 ? 0 : (a - 1) / b + 1; - } - - /** - * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 - * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) - * with further edits by Uniswap Labs also under MIT license. - */ - function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { - unchecked { - // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use - // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 - // variables such that product = prod1 * 2^256 + prod0. - uint256 prod0; // Least significant 256 bits of the product - uint256 prod1; // Most significant 256 bits of the product - assembly { - let mm := mulmod(x, y, not(0)) - prod0 := mul(x, y) - prod1 := sub(sub(mm, prod0), lt(mm, prod0)) - } - - // Handle non-overflow cases, 256 by 256 division. - if (prod1 == 0) { - // Solidity will revert if denominator == 0, unlike the div opcode on its own. - // The surrounding unchecked block does not change this fact. - // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. - return prod0 / denominator; - } - - // Make sure the result is less than 2^256. Also prevents denominator == 0. - require(denominator > prod1, "Math: mulDiv overflow"); - - /////////////////////////////////////////////// - // 512 by 256 division. - /////////////////////////////////////////////// - - // Make division exact by subtracting the remainder from [prod1 prod0]. - uint256 remainder; - assembly { - // Compute remainder using mulmod. - remainder := mulmod(x, y, denominator) - - // Subtract 256 bit number from 512 bit number. - prod1 := sub(prod1, gt(remainder, prod0)) - prod0 := sub(prod0, remainder) - } - - // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. - // See https://cs.stackexchange.com/q/138556/92363. - - // Does not overflow because the denominator cannot be zero at this stage in the function. - uint256 twos = denominator & (~denominator + 1); - assembly { - // Divide denominator by twos. - denominator := div(denominator, twos) - - // Divide [prod1 prod0] by twos. - prod0 := div(prod0, twos) - - // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. - twos := add(div(sub(0, twos), twos), 1) - } - - // Shift in bits from prod1 into prod0. - prod0 |= prod1 * twos; - - // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such - // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for - // four bits. That is, denominator * inv = 1 mod 2^4. - uint256 inverse = (3 * denominator) ^ 2; - - // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works - // in modular arithmetic, doubling the correct bits in each step. - inverse *= 2 - denominator * inverse; // inverse mod 2^8 - inverse *= 2 - denominator * inverse; // inverse mod 2^16 - inverse *= 2 - denominator * inverse; // inverse mod 2^32 - inverse *= 2 - denominator * inverse; // inverse mod 2^64 - inverse *= 2 - denominator * inverse; // inverse mod 2^128 - inverse *= 2 - denominator * inverse; // inverse mod 2^256 - - // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. - // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is - // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 - // is no longer required. - result = prod0 * inverse; - return result; - } - } - - /** - * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. - */ - function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { - uint256 result = mulDiv(x, y, denominator); - if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { - result += 1; - } - return result; - } - - /** - * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. - * - * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). - */ - function sqrt(uint256 a) internal pure returns (uint256) { - if (a == 0) { - return 0; - } - - // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. - // - // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have - // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. - // - // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` - // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` - // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` - // - // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. - uint256 result = 1 << (log2(a) >> 1); - - // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, - // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at - // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision - // into the expected uint128 result. - unchecked { - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - result = (result + a / result) >> 1; - return min(result, a / result); - } - } - - /** - * @notice Calculates sqrt(a), following the selected rounding direction. - */ - function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { - unchecked { - uint256 result = sqrt(a); - return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); - } - } - - /** - * @dev Return the log in base 2, rounded down, of a positive value. - * Returns 0 if given 0. - */ - function log2(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - unchecked { - if (value >> 128 > 0) { - value >>= 128; - result += 128; - } - if (value >> 64 > 0) { - value >>= 64; - result += 64; - } - if (value >> 32 > 0) { - value >>= 32; - result += 32; - } - if (value >> 16 > 0) { - value >>= 16; - result += 16; - } - if (value >> 8 > 0) { - value >>= 8; - result += 8; - } - if (value >> 4 > 0) { - value >>= 4; - result += 4; - } - if (value >> 2 > 0) { - value >>= 2; - result += 2; - } - if (value >> 1 > 0) { - result += 1; - } - } - return result; - } - - /** - * @dev Return the log in base 2, following the selected rounding direction, of a positive value. - * Returns 0 if given 0. - */ - function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { - unchecked { - uint256 result = log2(value); - return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); - } - } - - /** - * @dev Return the log in base 10, rounded down, of a positive value. - * Returns 0 if given 0. - */ - function log10(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - unchecked { - if (value >= 10 ** 64) { - value /= 10 ** 64; - result += 64; - } - if (value >= 10 ** 32) { - value /= 10 ** 32; - result += 32; - } - if (value >= 10 ** 16) { - value /= 10 ** 16; - result += 16; - } - if (value >= 10 ** 8) { - value /= 10 ** 8; - result += 8; - } - if (value >= 10 ** 4) { - value /= 10 ** 4; - result += 4; - } - if (value >= 10 ** 2) { - value /= 10 ** 2; - result += 2; - } - if (value >= 10 ** 1) { - result += 1; - } - } - return result; - } - - /** - * @dev Return the log in base 10, following the selected rounding direction, of a positive value. - * Returns 0 if given 0. - */ - function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { - unchecked { - uint256 result = log10(value); - return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); - } - } - - /** - * @dev Return the log in base 256, rounded down, of a positive value. - * Returns 0 if given 0. - * - * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. - */ - function log256(uint256 value) internal pure returns (uint256) { - uint256 result = 0; - unchecked { - if (value >> 128 > 0) { - value >>= 128; - result += 16; - } - if (value >> 64 > 0) { - value >>= 64; - result += 8; - } - if (value >> 32 > 0) { - value >>= 32; - result += 4; - } - if (value >> 16 > 0) { - value >>= 16; - result += 2; - } - if (value >> 8 > 0) { - result += 1; - } - } - return result; - } - - /** - * @dev Return the log in base 256, following the selected rounding direction, of a positive value. - * Returns 0 if given 0. - */ - function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { - unchecked { - uint256 result = log256(value); - return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); - } - } -} - -// File @openzeppelin/contracts-upgradeable/utils/math/SignedMathUpgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Standard signed math utilities missing in the Solidity language. - */ -library SignedMathUpgradeable { - /** - * @dev Returns the largest of two signed numbers. - */ - function max(int256 a, int256 b) internal pure returns (int256) { - return a > b ? a : b; - } - - /** - * @dev Returns the smallest of two signed numbers. - */ - function min(int256 a, int256 b) internal pure returns (int256) { - return a < b ? a : b; - } - - /** - * @dev Returns the average of two signed numbers without overflow. - * The result is rounded towards zero. - */ - function average(int256 a, int256 b) internal pure returns (int256) { - // Formula from the book "Hacker's Delight" - int256 x = (a & b) + ((a ^ b) >> 1); - return x + (int256(uint256(x) >> 255) & (a ^ b)); - } - - /** - * @dev Returns the absolute unsigned value of a signed value. - */ - function abs(int256 n) internal pure returns (uint256) { - unchecked { - // must be unchecked in order to support `n = type(int256).min` - return uint256(n >= 0 ? n : -n); - } - } -} - -// File @openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) - -pragma solidity ^0.8.0; - -/** - * @dev String operations. - */ -library StringsUpgradeable { - bytes16 private constant _SYMBOLS = "0123456789abcdef"; - uint8 private constant _ADDRESS_LENGTH = 20; - - /** - * @dev Converts a `uint256` to its ASCII `string` decimal representation. - */ - function toString(uint256 value) internal pure returns (string memory) { - unchecked { - uint256 length = MathUpgradeable.log10(value) + 1; - string memory buffer = new string(length); - uint256 ptr; - /// @solidity memory-safe-assembly - assembly { - ptr := add(buffer, add(32, length)) - } - while (true) { - ptr--; - /// @solidity memory-safe-assembly - assembly { - mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) - } - value /= 10; - if (value == 0) break; - } - return buffer; - } - } - - /** - * @dev Converts a `int256` to its ASCII `string` decimal representation. - */ - function toString(int256 value) internal pure returns (string memory) { - return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value)))); - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. - */ - function toHexString(uint256 value) internal pure returns (string memory) { - unchecked { - return toHexString(value, MathUpgradeable.log256(value) + 1); - } - } - - /** - * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. - */ - function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { - bytes memory buffer = new bytes(2 * length + 2); - buffer[0] = "0"; - buffer[1] = "x"; - for (uint256 i = 2 * length + 1; i > 1; --i) { - buffer[i] = _SYMBOLS[value & 0xf]; - value >>= 4; - } - require(value == 0, "Strings: hex length insufficient"); - return string(buffer); - } - - /** - * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. - */ - function toHexString(address addr) internal pure returns (string memory) { - return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); - } - - /** - * @dev Returns true if the two strings are equal. - */ - function equal(string memory a, string memory b) internal pure returns (bool) { - return keccak256(bytes(a)) == keccak256(bytes(b)); - } -} - -// File @openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) - -pragma solidity ^0.8.0; - -/** - * @dev Contract module that allows children to implement role-based access - * control mechanisms. This is a lightweight version that doesn't allow enumerating role - * members except through off-chain means by accessing the contract event logs. Some - * applications may benefit from on-chain enumerability, for those cases see - * {AccessControlEnumerable}. - * - * Roles are referred to by their `bytes32` identifier. These should be exposed - * in the external API and be unique. The best way to achieve this is by - * using `public constant` hash digests: - * - * ```solidity - * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); - * ``` - * - * Roles can be used to represent a set of permissions. To restrict access to a - * function call, use {hasRole}: - * - * ```solidity - * function foo() public { - * require(hasRole(MY_ROLE, msg.sender)); - * ... - * } - * ``` - * - * Roles can be granted and revoked dynamically via the {grantRole} and - * {revokeRole} functions. Each role has an associated admin role, and only - * accounts that have a role's admin role can call {grantRole} and {revokeRole}. - * - * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means - * that only accounts with this role will be able to grant or revoke other - * roles. More complex role relationships can be created by using - * {_setRoleAdmin}. - * - * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to - * grant and revoke this role. Extra precautions should be taken to secure - * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} - * to enforce additional security measures for this role. - */ -abstract contract AccessControlUpgradeable is - Initializable, - ContextUpgradeable, - IAccessControlUpgradeable, - ERC165Upgradeable -{ - struct RoleData { - mapping(address => bool) members; - bytes32 adminRole; - } - - mapping(bytes32 => RoleData) private _roles; - - bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; - - /** - * @dev Modifier that checks that an account has a specific role. Reverts - * with a standardized message including the required role. - * - * The format of the revert reason is given by the following regular expression: - * - * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ - * - * _Available since v4.1._ - */ - modifier onlyRole(bytes32 role) { - _checkRole(role); - _; - } - - function __AccessControl_init() internal onlyInitializing {} - - function __AccessControl_init_unchained() internal onlyInitializing {} - /** - * @dev See {IERC165-supportsInterface}. - */ - function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { - return interfaceId == type(IAccessControlUpgradeable).interfaceId || super.supportsInterface(interfaceId); - } - - /** - * @dev Returns `true` if `account` has been granted `role`. - */ - function hasRole(bytes32 role, address account) public view virtual override returns (bool) { - return _roles[role].members[account]; - } - - /** - * @dev Revert with a standard message if `_msgSender()` is missing `role`. - * Overriding this function changes the behavior of the {onlyRole} modifier. - * - * Format of the revert message is described in {_checkRole}. - * - * _Available since v4.6._ - */ - function _checkRole(bytes32 role) internal view virtual { - _checkRole(role, _msgSender()); - } - - /** - * @dev Revert with a standard message if `account` is missing `role`. - * - * The format of the revert reason is given by the following regular expression: - * - * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ - */ - function _checkRole(bytes32 role, address account) internal view virtual { - if (!hasRole(role, account)) { - revert( - string( - abi.encodePacked( - "AccessControl: account ", - StringsUpgradeable.toHexString(account), - " is missing role ", - StringsUpgradeable.toHexString(uint256(role), 32) - ) - ) - ); - } - } - - /** - * @dev Returns the admin role that controls `role`. See {grantRole} and - * {revokeRole}. - * - * To change a role's admin, use {_setRoleAdmin}. - */ - function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { - return _roles[role].adminRole; - } - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - * - * May emit a {RoleGranted} event. - */ - function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { - _grantRole(role, account); - } - - /** - * @dev Revokes `role` from `account`. - * - * If `account` had been granted `role`, emits a {RoleRevoked} event. - * - * Requirements: - * - * - the caller must have ``role``'s admin role. - * - * May emit a {RoleRevoked} event. - */ - function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { - _revokeRole(role, account); - } - - /** - * @dev Revokes `role` from the calling account. - * - * Roles are often managed via {grantRole} and {revokeRole}: this function's - * purpose is to provide a mechanism for accounts to lose their privileges - * if they are compromised (such as when a trusted device is misplaced). - * - * If the calling account had been revoked `role`, emits a {RoleRevoked} - * event. - * - * Requirements: - * - * - the caller must be `account`. - * - * May emit a {RoleRevoked} event. - */ - function renounceRole(bytes32 role, address account) public virtual override { - require(account == _msgSender(), "AccessControl: can only renounce roles for self"); - - _revokeRole(role, account); - } - - /** - * @dev Grants `role` to `account`. - * - * If `account` had not been already granted `role`, emits a {RoleGranted} - * event. Note that unlike {grantRole}, this function doesn't perform any - * checks on the calling account. - * - * May emit a {RoleGranted} event. - * - * [WARNING] - * ==== - * This function should only be called from the constructor when setting - * up the initial roles for the system. - * - * Using this function in any other way is effectively circumventing the admin - * system imposed by {AccessControl}. - * ==== - * - * NOTE: This function is deprecated in favor of {_grantRole}. - */ - function _setupRole(bytes32 role, address account) internal virtual { - _grantRole(role, account); - } - - /** - * @dev Sets `adminRole` as ``role``'s admin role. - * - * Emits a {RoleAdminChanged} event. - */ - function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { - bytes32 previousAdminRole = getRoleAdmin(role); - _roles[role].adminRole = adminRole; - emit RoleAdminChanged(role, previousAdminRole, adminRole); - } - - /** - * @dev Grants `role` to `account`. - * - * Internal function without access restriction. - * - * May emit a {RoleGranted} event. - */ - function _grantRole(bytes32 role, address account) internal virtual { - if (!hasRole(role, account)) { - _roles[role].members[account] = true; - emit RoleGranted(role, account, _msgSender()); - } - } - - /** - * @dev Revokes `role` from `account`. - * - * Internal function without access restriction. - * - * May emit a {RoleRevoked} event. - */ - function _revokeRole(bytes32 role, address account) internal virtual { - if (hasRole(role, account)) { - _roles[role].members[account] = false; - emit RoleRevoked(role, account, _msgSender()); - } - } - - /** - * @dev This empty reserved space is put in place to allow future versions to add new - * variables without shifting down storage in the inheritance chain. - * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps - */ - uint256[49] private __gap; -} - -// File contracts/interfaces/l1/ILineaRollupV5.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity 0.8.24; - -/** - * @title LineaRollup interface for current functions, events and errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface ILineaRollupV5 { - /** - * @notice Supporting data for compressed calldata submission including compressed data. - * @dev finalStateRootHash is used to set state root at the end of the data. - * @dev firstBlockInData is the first block that is included in the data submitted. - * @dev finalBlockInData is the last block that is included in the data submitted. - * @dev snarkHash is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. - * @dev compressedData is the compressed transaction data. It contains ordered data for each L2 block - l2Timestamps, the encoded txData. - */ - struct SubmissionDataV2 { - bytes32 finalStateRootHash; - uint256 firstBlockInData; - uint256 finalBlockInData; - bytes32 snarkHash; - bytes compressedData; - } - - /** - * @notice Supporting data for compressed blob data submission. - * @dev finalStateRootHash is used to set state root at the end of the data. - * @dev firstBlockInData is the first block that is included in the data submitted. - * @dev finalBlockInData is the last block that is included in the data submitted. - * @dev snarkHash is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. - */ - struct SupportingSubmissionDataV2 { - bytes32 finalStateRootHash; - uint256 firstBlockInData; - uint256 finalBlockInData; - bytes32 snarkHash; - } - - /** - * @notice Shnarf data for validating a shnarf. - * @dev parentShnarf is the parent computed shnarf. - * @dev snarkHash is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. - * @dev finalStateRootHash is the final state root hash. - * @dev dataEvaluationPoint is the data evaluation point. - * @dev dataEvaluationClaim is the data evaluation claim. - */ - struct ShnarfData { - bytes32 parentShnarf; - bytes32 snarkHash; - bytes32 finalStateRootHash; - bytes32 dataEvaluationPoint; - bytes32 dataEvaluationClaim; - } - - /** - * @notice Data structure for compressed blob data submission. - * @dev submissionData The supporting data for blob data submission excluding the compressed data. - * @dev dataEvaluationClaim The data evaluation claim. - * @dev kzgCommitment The blob KZG commitment. - * @dev kzgProof The blob KZG point proof. - */ - struct BlobSubmissionData { - SupportingSubmissionDataV2 submissionData; - uint256 dataEvaluationClaim; - bytes kzgCommitment; - bytes kzgProof; - } - - /** - * @notice Supporting data for finalization with or without proof. - * @dev NB: the dynamic sized fields are placed last on purpose for efficient keccaking on public input. - * @dev parentStateRootHash is the expected last state root hash finalized. - * @dev lastFinalizedShnarf is the last finalized shnarf for proof continuity checks. - * @dev finalBlockInData is the final block finalizing until. - * @dev shnarfData contains data about the last data submission's shnarf used in finalization. - * @dev lastFinalizedTimestamp is the expected last finalized block's timestamp. - * @dev finalTimestamp is the timestamp of the last block being finalized. - * @dev lastFinalizedL1RollingHash is the last stored L2 computed rolling hash used in finalization. - * @dev l1RollingHash is the calculated rolling hash on L2 that is expected to match L1 at l1RollingHashMessageNumber. - * This value will be used along with the stored last finalized L2 calculated rolling hash in the public input. - * @dev lastFinalizedL1RollingHashMessageNumber is the last stored L2 computed message number used in finalization. - * @dev l1RollingHashMessageNumber is the calculated message number on L2 that is expected to match the existing L1 rolling hash. - * This value will be used along with the stored last finalized L2 calculated message number in the public input. - * @dev l2MerkleTreesDepth is the depth of all l2MerkleRoots. - * @dev l2MerkleRoots is an array of L2 message merkle roots of depth l2MerkleTreesDepth between last finalized block and finalSubmissionData.finalBlockInData. - * @dev l2MessagingBlocksOffsets indicates by offset from currentL2BlockNumber which L2 blocks contain MessageSent events. - */ - struct FinalizationDataV2 { - bytes32 parentStateRootHash; - bytes32 lastFinalizedShnarf; - uint256 finalBlockInData; - ShnarfData shnarfData; - uint256 lastFinalizedTimestamp; - uint256 finalTimestamp; - bytes32 lastFinalizedL1RollingHash; - bytes32 l1RollingHash; - uint256 lastFinalizedL1RollingHashMessageNumber; - uint256 l1RollingHashMessageNumber; - uint256 l2MerkleTreesDepth; - bytes32[] l2MerkleRoots; - bytes l2MessagingBlocksOffsets; - } - - /** - * @notice Emitted when a verifier is set for a particular proof type. - * @param verifierAddress The indexed new verifier address being set. - * @param proofType The indexed proof type/index that the verifier is mapped to. - * @param verifierSetBy The index address who set the verifier at the mapping. - * @param oldVerifierAddress Indicates the previous address mapped to the proof type. - * @dev The verifier will be set by an account with the VERIFIER_SETTER_ROLE. Typically the Safe. - * @dev The oldVerifierAddress can be the zero address. - */ - event VerifierAddressChanged( - address indexed verifierAddress, - uint256 indexed proofType, - address indexed verifierSetBy, - address oldVerifierAddress - ); - - /** - * @notice Emitted when compressed data is being submitted and verified succesfully on L1. - * @param shnarf The indexed shnarf for the data being submitted. - * @param startBlock The indexed L2 block number indicating which block the data starts from. - * @param endBlock The indexed L2 block number indicating which block the data ends on. - * @dev Please note, shnarf was previously dataHash and points to the shnarfFinalBlockNumbers mapping. - */ - event DataSubmittedV2(bytes32 indexed shnarf, uint256 indexed startBlock, uint256 indexed endBlock); - - /** - * @notice Emitted when L2 blocks have been finalized on L1. - * @param lastBlockFinalized The indexed last L2 block that is finalized in the finalization. - * @param startingRootHash The indexed initial (also last finalized) L2 state root hash that the finalization is from. - * @param finalRootHash The indexed L2 state root hash that the current finalization is up until. - * @param withProof Indicates if the finalization is proven or not. - */ - event DataFinalized( - uint256 indexed lastBlockFinalized, - bytes32 indexed startingRootHash, - bytes32 indexed finalRootHash, - bool withProof - ); - - /** - * @dev Thrown when the point evaluation precompile call return data field(s) are wrong. - */ - error PointEvaluationResponseInvalid(uint256 fieldElements, uint256 blsCurveModulus); - - /** - * @dev Thrown when the point evaluation precompile call return data length is wrong. - */ - error PrecompileReturnDataLengthWrong(uint256 expected, uint256 actual); - - /** - * @dev Thrown when the point evaluation precompile call returns false. - */ - error PointEvaluationFailed(); - - /** - * @dev Thrown when the blobhash equals to the zero hash. - */ - error EmptyBlobData(); - - /** - * @dev Thrown when the blobhash at an index equals to the zero hash. - */ - error EmptyBlobDataAtIndex(uint256 index); - - /** - * @dev Thrown when the data for multiple blobs' submission has length zero. - */ - error BlobSubmissionDataIsMissing(); - - /** - * @dev Thrown when the starting block in the data item is out of sequence with the last block number. - */ - error DataStartingBlockDoesNotMatch(uint256 expected, uint256 actual); - - /** - * @dev Thrown when the current data was already submitted. - */ - error DataAlreadySubmitted(bytes32 currentDataHash); - - /** - * @dev Thrown when the last finalized shnarf does not match the parent finalizing from. - */ - error LastFinalizedShnarfWrong(bytes32 expected, bytes32 actual); - - /** - * @dev Thrown when submissionData is empty. - */ - error EmptySubmissionData(); - - /** - * @dev Thrown when finalizationData.l1RollingHash does not exist on L1 (Feedback loop). - */ - error L1RollingHashDoesNotExistOnL1(uint256 messageNumber, bytes32 rollingHash); - - /** - * @dev Thrown when finalization state does not match. - */ - error FinalizationStateIncorrect(bytes32 expected, bytes32 value); - - /** - * @dev Thrown when the first block is greater than final block in submission data. - */ - error FirstBlockGreaterThanFinalBlock(uint256 firstBlockNumber, uint256 finalBlockNumber); - - /** - * @dev Thrown when the first block in data is less than or equal to the last finalized block during data submission. - */ - error FirstBlockLessThanOrEqualToLastFinalizedBlock(uint256 firstBlockNumber, uint256 lastFinalizedBlock); - - /** - * @dev Thrown when the final block number in finalization data is less than or equal to the last finalized block during finalization. - */ - error FinalBlockNumberLessThanOrEqualToLastFinalizedBlock(uint256 finalBlockNumber, uint256 lastFinalizedBlock); - - /** - * @dev Thrown when the final block state equals the zero hash during finalization. - */ - error FinalBlockStateEqualsZeroHash(); - - /** - * @dev Thrown when final l2 block timestamp higher than current block.timestamp during finalization. - */ - error FinalizationInTheFuture(uint256 l2BlockTimestamp, uint256 currentBlockTimestamp); - - /** - * @dev Thrown when a rolling hash is provided without a corresponding message number. - */ - error MissingMessageNumberForRollingHash(bytes32 rollingHash); - - /** - * @dev Thrown when a message number is provided without a corresponding rolling hash. - */ - error MissingRollingHashForMessageNumber(uint256 messageNumber); - - /** - * @dev Thrown when the first byte is not zero. - * @dev This is used explicitly with the four bytes in assembly 0x729eebce. - */ - error FirstByteIsNotZero(); - - /** - * @dev Thrown when bytes length is not a multiple of 32. - */ - error BytesLengthNotMultipleOf32(); - - /** - * @dev Thrown when the snarkhash is the zero hash. - */ - error SnarkHashIsZeroHash(); - - /** - * @dev Thrown when parent stateRootHash does not match. - */ - error ParentStateRootHashInvalid(bytes32 expected, bytes32 actual); - - /** - * @dev Thrown when the block being finalized until does not match that of the shnarf data. - */ - error FinalBlockDoesNotMatchShnarfFinalBlock(uint256 expected, uint256 actual); - - /** - * @dev Thrown when the lengths of the shnarfs array and final block numbers array don't match. - */ - error ShnarfAndFinalBlockNumberLengthsMismatched(uint256 shnarfsLength, uint256 finalBlockNumbers); - - /** - * @dev Thrown when the computed shnarf does not match what is expected. - */ - error FinalShnarfWrong(bytes32 expected, bytes32 value); - - /** - * @notice Adds or updated the verifier contract address for a proof type. - * @dev VERIFIER_SETTER_ROLE is required to execute. - * @param _newVerifierAddress The address for the verifier contract. - * @param _proofType The proof type being set/updated. - */ - function setVerifierAddress(address _newVerifierAddress, uint256 _proofType) external; - - /** - * @notice Unset the verifier contract address for a proof type. - * @dev VERIFIER_SETTER_ROLE is required to execute. - * @param _proofType The proof type being set/updated. - */ - function unsetVerifierAddress(uint256 _proofType) external; - - /** - * @notice Submit one or more EIP-4844 blobs. - * @dev OPERATOR_ROLE is required to execute. - * @dev This should be a blob carrying transaction. - * @param _blobSubmissionData The data for blob submission including proofs and required polynomials. - * @param _parentShnarf The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. - * @param _finalBlobShnarf The expected final shnarf post computation of all the blob shnarfs. - */ - function submitBlobs( - BlobSubmissionData[] calldata _blobSubmissionData, - bytes32 _parentShnarf, - bytes32 _finalBlobShnarf - ) external; - - /** - * @notice Submit blobs using compressed data via calldata. - * @dev OPERATOR_ROLE is required to execute. - * @param _submissionData The supporting data for compressed data submission including compressed data. - * @param _parentShnarf The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. - * @param _expectedShnarf The expected shnarf post computation of all the submission. - */ - function submitDataAsCalldata( - SubmissionDataV2 calldata _submissionData, - bytes32 _parentShnarf, - bytes32 _expectedShnarf - ) external; - - /** - * @notice Finalize compressed blocks without proof. - * @dev DEFAULT_ADMIN_ROLE is required to execute. - * @param _finalizationData The full finalization data. - */ - function finalizeBlocksWithoutProof(FinalizationDataV2 calldata _finalizationData) external; - - /** - * @notice Finalize compressed blocks with proof. - * @dev OPERATOR_ROLE is required to execute. - * @param _aggregatedProof The aggregated proof. - * @param _proofType The proof type. - * @param _finalizationData The full finalization data. - */ - function finalizeBlocksWithProof( - bytes calldata _aggregatedProof, - uint256 _proofType, - FinalizationDataV2 calldata _finalizationData - ) external; -} - -// File contracts/lib/Utils.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity >=0.8.19 <=0.8.24; - -library Utils { - /** - * @notice Performs a gas optimized keccak hash. - * @param _left Left value. - * @param _right Right value. - */ - function _efficientKeccak(bytes32 _left, bytes32 _right) internal pure returns (bytes32 value) { - /// @solidity memory-safe-assembly - assembly { - mstore(0x00, _left) - mstore(0x20, _right) - value := keccak256(0x00, 0x40) - } - } -} - -// File contracts/interfaces/IGenericErrors.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity >=0.8.19 <=0.8.24; - -/** - * @title Interface declaring generic errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface IGenericErrors { - /** - * @dev Thrown when a parameter is the zero address. - */ - error ZeroAddressNotAllowed(); -} - -// File contracts/interfaces/l1/IL1MessageService.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity 0.8.24; - -/** - * @title L1 Message Service interface for pre-existing functions, events and errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ - -interface IL1MessageService { - /** - * @param proof The proof array related to the claimed message. - * @param messageNumber The message number of the claimed message. - * @param leafIndex The leaf index related to the merkle proof of the message. - * @param from The address of the original sender. - * @param to The address the message is intended for. - * @param fee The fee being paid for the message delivery. - * @param value The value to be transferred to the destination address. - * @param feeRecipient The recipient for the fee. - * @param merkleRoot The merkle root of the claimed message. - * @param data The calldata to pass to the recipient. - */ - struct ClaimMessageWithProofParams { - bytes32[] proof; - uint256 messageNumber; - uint32 leafIndex; - address from; - address to; - uint256 fee; - uint256 value; - address payable feeRecipient; - bytes32 merkleRoot; - bytes data; - } - - /** - * @notice Emitted when initializing Linea Rollup contract with a system migration block. - */ - event SystemMigrationBlockInitialized(uint256 systemMigrationBlock); - /** - * @dev Thrown when L2 merkle root does not exist. - */ - error L2MerkleRootDoesNotExist(); - - /** - * @dev Thrown when the merkle proof is invalid. - */ - error InvalidMerkleProof(); - - /** - * @dev Thrown when merkle depth doesn't match proof length. - */ - error ProofLengthDifferentThanMerkleDepth(uint256 actual, uint256 expected); -} - -// File @openzeppelin/contracts/utils/structs/BitMaps.sol@v4.9.6 - -// Original license: SPDX_License_Identifier: MIT -// OpenZeppelin Contracts (last updated v4.9.0) (utils/structs/BitMaps.sol) -pragma solidity ^0.8.0; - -/** - * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential. - * Largely inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor]. - */ -library BitMaps { - struct BitMap { - mapping(uint256 => uint256) _data; - } - - /** - * @dev Returns whether the bit at `index` is set. - */ - function get(BitMap storage bitmap, uint256 index) internal view returns (bool) { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - return bitmap._data[bucket] & mask != 0; - } - - /** - * @dev Sets the bit at `index` to the boolean `value`. - */ - function setTo(BitMap storage bitmap, uint256 index, bool value) internal { - if (value) { - set(bitmap, index); - } else { - unset(bitmap, index); - } - } - - /** - * @dev Sets the bit at `index`. - */ - function set(BitMap storage bitmap, uint256 index) internal { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - bitmap._data[bucket] |= mask; - } - - /** - * @dev Unsets the bit at `index`. - */ - function unset(BitMap storage bitmap, uint256 index) internal { - uint256 bucket = index >> 8; - uint256 mask = 1 << (index & 0xff); - bitmap._data[bucket] &= ~mask; - } -} - -// File contracts/interfaces/l1/IL1MessageManager.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title L1 Message manager interface for current functions, events and errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface IL1MessageManager { - /** - * @notice Emitted when a new message is sent and the rolling hash updated. - * @param messageNumber The unique indexed message number for the message. - * @param rollingHash The indexed rolling hash computed for the current message number. - * @param messageHash The indexed hash of the message parameters. - */ - event RollingHashUpdated(uint256 indexed messageNumber, bytes32 indexed rollingHash, bytes32 indexed messageHash); - - /** - * @notice Emitted when the L2 merkle root has been anchored on L1. - * @param l2MerkleRoot The indexed L2 Merkle root that has been anchored on L1 Ethereum. - * @param treeDepth The indexed tree depth of the Merkle root. - * @dev There may be more than one of these in a finalization depending on the amount of L2->L1 messages in the finalization. - */ - event L2MerkleRootAdded(bytes32 indexed l2MerkleRoot, uint256 indexed treeDepth); - - /** - * @notice Emitted when the l2 block contains L2 messages during finalization. - * @param l2Block The indexed L2 block containing L2 to L1 messages. - * @dev This is used externally in the logic for determining which messages belong to which Merkle root when claiming. - */ - event L2MessagingBlockAnchored(uint256 indexed l2Block); - - /** - * @dev Thrown when the message has already been claimed. - */ - error MessageAlreadyClaimed(uint256 messageIndex); - - /** - * @dev Thrown when the L2 merkle root has already been anchored on L1. - */ - error L2MerkleRootAlreadyAnchored(bytes32 merkleRoot); - - /** - * @dev Thrown when the L2 messaging blocks offsets bytes length is not a multiple of 2. - */ - error BytesLengthNotMultipleOfTwo(uint256 bytesLength); - - /** - * @notice Check if the L2->L1 message is claimed or not. - * @param _messageNumber The message number on L2. - */ - function isMessageClaimed(uint256 _messageNumber) external view returns (bool); -} - -// File contracts/interfaces/l1/IL1MessageManagerV1.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity 0.8.24; - -/** - * @title L1 Message manager V1 interface for pre-existing functions, events and errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface IL1MessageManagerV1 { - /** - * @notice Emitted when L2->L1 message hashes have been added to L1 storage. - * @param messageHash The indexed hash of the message parameters. - * @dev DEPRECATED - This is kept for backwards compatability for external consumers. - */ - event L2L1MessageHashAddedToInbox(bytes32 indexed messageHash); - - /** - * @notice Emitted when L1->L2 messages have been anchored on L2 and updated on L1. - * @param messageHashes The collection of hashes indicating which messages were added on L2. of the message parameters. - * @dev DEPRECATED - This is kept for backwards compatability for external consumers. - */ - event L1L2MessagesReceivedOnL2(bytes32[] messageHashes); - - /** - * @dev Thrown when the message has already been claimed. - */ - error MessageDoesNotExistOrHasAlreadyBeenClaimed(bytes32 messageHash); -} - -// File contracts/messageService/l1/v1/L1MessageManagerV1.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Contract to manage cross-chain message hashes storage and status on L1. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -abstract contract L1MessageManagerV1 is IL1MessageManagerV1 { - uint8 public constant INBOX_STATUS_UNKNOWN = 0; - uint8 public constant INBOX_STATUS_RECEIVED = 1; - - uint8 public constant OUTBOX_STATUS_UNKNOWN = 0; - uint8 public constant OUTBOX_STATUS_SENT = 1; - uint8 public constant OUTBOX_STATUS_RECEIVED = 2; - - /// @dev Mapping to store L1->L2 message hashes status. - /// @dev messageHash => messageStatus (0: unknown, 1: sent, 2: received). - mapping(bytes32 messageHash => uint256 messageStatus) public outboxL1L2MessageStatus; - - /// @dev Mapping to store L2->L1 message hashes status. - /// @dev messageHash => messageStatus (0: unknown, 1: received). - mapping(bytes32 messageHash => uint256 messageStatus) public inboxL2L1MessageStatus; - - /// @dev Keep free storage slots for future implementation updates to avoid storage collision. - // ******************************************************************************************* - // NB: THIS GAP HAS BEEN PUSHED OUT IN FAVOUR OF THE GAP INSIDE THE REENTRANCY CODE - //uint256[50] private __gap; - // NB: DO NOT USE THIS GAP - // ******************************************************************************************* - - /// @dev Total contract storage is 2 slots. - - /** - * @notice Update the status of L2->L1 message when a user claims a message on L1. - * @dev The L2->L1 message is removed from storage. - * @dev Due to the nature of the rollup, we should not get a second entry of this. - * @param _messageHash Hash of the message. - */ - function _updateL2L1MessageStatusToClaimed(bytes32 _messageHash) internal { - if (inboxL2L1MessageStatus[_messageHash] != INBOX_STATUS_RECEIVED) { - revert MessageDoesNotExistOrHasAlreadyBeenClaimed(_messageHash); - } - - delete inboxL2L1MessageStatus[_messageHash]; - } -} - -// File contracts/messageService/l1/L1MessageManager.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Contract to manage cross-chain message rolling hash computation and storage on L1. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -abstract contract L1MessageManager is L1MessageManagerV1, IL1MessageManager { - using BitMaps for BitMaps.BitMap; - using Utils for *; - - mapping(uint256 messageNumber => bytes32 rollingHash) public rollingHashes; - BitMaps.BitMap internal _messageClaimedBitMap; - mapping(bytes32 merkleRoot => uint256 treeDepth) public l2MerkleRootsDepths; - - /// @dev Total contract storage is 53 slots including the gap below. - /// @dev Keep 50 free storage slots for future implementation updates to avoid storage collision. - uint256[50] private __gap_L1MessageManager; - - /** - * @notice Take an existing message hash, calculates the rolling hash and stores at the message number. - * @param _messageNumber The current message number being sent. - * @param _messageHash The hash of the message being sent. - */ - function _addRollingHash(uint256 _messageNumber, bytes32 _messageHash) internal { - unchecked { - bytes32 newRollingHash = Utils._efficientKeccak(rollingHashes[_messageNumber - 1], _messageHash); - - rollingHashes[_messageNumber] = newRollingHash; - emit RollingHashUpdated(_messageNumber, newRollingHash, _messageHash); - } - } - - /** - * @notice Set the L2->L1 message as claimed when a user claims a message on L1. - * @param _messageNumber The message number on L2. - */ - function _setL2L1MessageToClaimed(uint256 _messageNumber) internal { - if (_messageClaimedBitMap.get(_messageNumber)) { - revert MessageAlreadyClaimed(_messageNumber); - } - _messageClaimedBitMap.set(_messageNumber); - } - - /** - * @notice Add the L2 merkle roots to the storage. - * @dev This function is called during block finalization. - * @dev The _treeDepth does not need to be checked to be non-zero as it is, - * already enforced to be non-zero in the circuit, and used in the proof's public input. - * @param _newRoots New L2 merkle roots. - */ - function _addL2MerkleRoots(bytes32[] calldata _newRoots, uint256 _treeDepth) internal { - for (uint256 i; i < _newRoots.length; ++i) { - if (l2MerkleRootsDepths[_newRoots[i]] != 0) { - revert L2MerkleRootAlreadyAnchored(_newRoots[i]); - } - - l2MerkleRootsDepths[_newRoots[i]] = _treeDepth; - - emit L2MerkleRootAdded(_newRoots[i], _treeDepth); - } - } - - /** - * @notice Emit an event for each L2 block containing L2->L1 messages. - * @dev This function is called during block finalization. - * @param _l2MessagingBlocksOffsets Is a sequence of uint16 values, where each value plus the last finalized L2 block number. - * indicates which L2 blocks have L2->L1 messages. - * @param _currentL2BlockNumber Last L2 block number finalized on L1. - */ - function _anchorL2MessagingBlocks(bytes calldata _l2MessagingBlocksOffsets, uint256 _currentL2BlockNumber) internal { - if (_l2MessagingBlocksOffsets.length % 2 != 0) { - revert BytesLengthNotMultipleOfTwo(_l2MessagingBlocksOffsets.length); - } - - uint256 l2BlockOffset; - unchecked { - for (uint256 i; i < _l2MessagingBlocksOffsets.length; ) { - assembly { - l2BlockOffset := shr(240, calldataload(add(_l2MessagingBlocksOffsets.offset, i))) - } - emit L2MessagingBlockAnchored(_currentL2BlockNumber + l2BlockOffset); - i += 2; - } - } - } - - /** - * @notice Check if the L2->L1 message is claimed or not. - * @param _messageNumber The message number on L2. - */ - function isMessageClaimed(uint256 _messageNumber) external view returns (bool) { - return _messageClaimedBitMap.get(_messageNumber); - } -} - -// File contracts/interfaces/IMessageService.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity >=0.8.19 <=0.8.24; - -/** - * @title Interface declaring pre-existing cross-chain messaging functions, events and errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface IMessageService { - /** - * @notice Emitted when a message is sent. - * @param _from The indexed sender address of the message (msg.sender). - * @param _to The indexed intended recipient address of the message on the other layer. - * @param _fee The fee being being paid to deliver the message to the recipient in Wei. - * @param _value The value being sent to the recipient in Wei. - * @param _nonce The unique message number. - * @param _calldata The calldata being passed to the intended recipient when being called on claiming. - * @param _messageHash The indexed hash of the message parameters. - * @dev _calldata has the _ because calldata is a reserved word. - * @dev We include the message hash to save hashing costs on the rollup. - * @dev This event is used on both L1 and L2. - */ - event MessageSent( - address indexed _from, - address indexed _to, - uint256 _fee, - uint256 _value, - uint256 _nonce, - bytes _calldata, - bytes32 indexed _messageHash - ); - - /** - * @notice Emitted when a message is claimed. - * @param _messageHash The indexed hash of the message that was claimed. - */ - event MessageClaimed(bytes32 indexed _messageHash); - - /** - * @dev Thrown when fees are lower than the minimum fee. - */ - error FeeTooLow(); - - /** - * @dev Thrown when the value sent is less than the fee. - * @dev Value to forward on is msg.value - _fee. - */ - error ValueSentTooLow(); - - /** - * @dev Thrown when the destination address reverts. - */ - error MessageSendingFailed(address destination); - - /** - * @dev Thrown when the recipient address reverts. - */ - error FeePaymentFailed(address recipient); - - /** - * @notice Sends a message for transporting from the given chain. - * @dev This function should be called with a msg.value = _value + _fee. The fee will be paid on the destination chain. - * @param _to The destination address on the destination chain. - * @param _fee The message service fee on the origin chain. - * @param _calldata The calldata used by the destination message service to call the destination contract. - */ - function sendMessage(address _to, uint256 _fee, bytes calldata _calldata) external payable; - - /** - * @notice Deliver a message to the destination chain. - * @notice Is called by the Postman, dApp or end user. - * @param _from The msg.sender calling the origin message service. - * @param _to The destination address on the destination chain. - * @param _value The value to be transferred to the destination address. - * @param _fee The message service fee on the origin chain. - * @param _feeRecipient Address that will receive the fees. - * @param _calldata The calldata used by the destination message service to call/forward to the destination contract. - * @param _nonce Unique message number. - */ - function claimMessage( - address _from, - address _to, - uint256 _fee, - uint256 _value, - address payable _feeRecipient, - bytes calldata _calldata, - uint256 _nonce - ) external; - - /** - * @notice Returns the original sender of the message on the origin layer. - * @return The original sender of the message on the origin layer. - */ - function sender() external view returns (address); -} - -// File contracts/messageService/lib/TransientStorageHelpers.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Library that provides helper functions to interact with transient storage. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -library TransientStorageHelpers { - /** - * @notice Internal function that stores a uint256 value at a given key in the EVM's transient storage using the `tstore` opcode. - * @param _key The key in the EVM transient storage where the value should be stored. - * @param _value The uint256 value to be stored at the specified key in the EVM transient storage. - */ - function tstoreUint256(bytes32 _key, uint256 _value) internal { - assembly { - tstore(_key, _value) - } - } - - /** - * @notice Internal function that retrieves a uint256 value from the EVM's transient storage using the `tload` opcode. - * @param _key The key in the EVM transient storage from which the value should be retrieved. - * @return value The uint256 value retrieved from the specified key in the EVM transient storage. - */ - function tloadUint256(bytes32 _key) internal view returns (uint256 value) { - assembly { - value := tload(_key) - } - } - - /** - * @notice Internal function that stores an address at a given key in the EVM's transient storage using the `tstore` opcode. - * @param _key The key in the EVM transient storage where the value should be stored. - * @param _addr The address to be stored at the specified key in the EVM transient storage. - */ - function tstoreAddress(bytes32 _key, address _addr) internal { - assembly { - tstore(_key, _addr) - } - } - - /** - * @notice Internal function that retrieves an address from the EVM's transient storage using the `tload` opcode. - * @param _key The key in the EVM transient storage from which the value should be retrieved. - * @return addr The address retrieved from the specified key in the EVM transient storage. - */ - function tloadAddress(bytes32 _key) internal view returns (address addr) { - assembly { - addr := tload(_key) - } - } -} - -// File contracts/messageService/l1/TransientStorageReentrancyGuardUpgradeable.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Contract that helps prevent reentrant calls. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -abstract contract TransientStorageReentrancyGuardUpgradeable { - using TransientStorageHelpers for *; - - bytes32 private constant REENTRANCY_GUARD_TRANSIENT_KEY = - bytes32(uint256(keccak256("eip1967.reentrancy.guard.transient.key")) - 1); - - uint256 private constant NOT_ENTERED = 0; - uint256 private constant ENTERED = 1; - - error ReentrantCall(); - - /// @dev This gap is used to not shift down the storage layout after removing the OpenZeppelin ReentrancyGuardUpgradeable contract. - uint256[50] private __gap_ReentrancyGuardUpgradeable; - - modifier nonReentrant() { - _nonReentrantBefore(); - _; - _nonReentrantAfter(); - } - - /** - * @notice Checks reentrancy and if not reentrant sets the transient reentry flag. - * @dev This uses the TransientStorageHelpers library and REENTRANCY_GUARD_TRANSIENT_KEY. - */ - function _nonReentrantBefore() private { - if (TransientStorageHelpers.tloadUint256(REENTRANCY_GUARD_TRANSIENT_KEY) != NOT_ENTERED) { - revert ReentrantCall(); - } - - TransientStorageHelpers.tstoreUint256(REENTRANCY_GUARD_TRANSIENT_KEY, ENTERED); - } - - /** - * @notice Clears reentry transient storage flag. - * @dev This uses the TransientStorageHelpers library and REENTRANCY_GUARD_TRANSIENT_KEY. - */ - function _nonReentrantAfter() private { - TransientStorageHelpers.tstoreUint256(REENTRANCY_GUARD_TRANSIENT_KEY, NOT_ENTERED); - } -} - -// File contracts/interfaces/IPauseManager.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity >=0.8.19 <=0.8.24; - -/** - * @title Interface declaring pre-existing pausing functions, events and errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface IPauseManager { - /** - * @notice Emitted when a pause type is paused. - * @param messageSender The address performing the pause. - * @param pauseType The indexed pause type that was paused. - */ - event Paused(address messageSender, uint256 indexed pauseType); - - /** - * @notice Emitted when a pause type is unpaused. - * @param messageSender The address performing the unpause. - * @param pauseType The indexed pause type that was unpaused. - */ - event UnPaused(address messageSender, uint256 indexed pauseType); - - /** - * @dev Thrown when a specific pause type is paused. - */ - error IsPaused(uint256 pauseType); - - /** - * @dev Thrown when a specific pause type is not paused and expected to be. - */ - error IsNotPaused(uint256 pauseType); -} - -// File contracts/messageService/lib/PauseManager.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity >=0.8.19 <=0.8.24; - -/** - * @title Contract to manage cross-chain function pausing. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -abstract contract PauseManager is Initializable, IPauseManager, AccessControlUpgradeable { - bytes32 public constant PAUSE_MANAGER_ROLE = keccak256("PAUSE_MANAGER_ROLE"); - - uint8 public constant GENERAL_PAUSE_TYPE = 1; - uint8 public constant L1_L2_PAUSE_TYPE = 2; - uint8 public constant L2_L1_PAUSE_TYPE = 3; - uint8 public constant PROVING_SYSTEM_PAUSE_TYPE = 4; - - // @dev DEPRECATED. USE _pauseTypeStatusesBitMap INSTEAD - mapping(bytes32 pauseType => bool pauseStatus) public pauseTypeStatuses; - - uint256 private _pauseTypeStatusesBitMap; - - /// @dev Total contract storage is 11 slots with the gap below. - /// @dev Keep 9 free storage slots for future implementation updates to avoid storage collision. - /// @dev Note: This was reduced previously to cater for new functionality. - uint256[9] private __gap; - - /** - * @dev Modifier to make a function callable only when the specific and general types are not paused. - * @param _pauseType The pause type value being checked. - * Requirements: - * - * - The type must not be paused. - */ - modifier whenTypeAndGeneralNotPaused(uint8 _pauseType) { - _requireTypeAndGeneralNotPaused(_pauseType); - _; - } - - /** - * @dev Modifier to make a function callable only when the type is not paused. - * @param _pauseType The pause type value being checked. - * Requirements: - * - * - The type must not be paused. - */ - modifier whenTypeNotPaused(uint8 _pauseType) { - _requireTypeNotPaused(_pauseType); - _; - } - - /** - * @dev Throws if the specific or general types are paused. - * @dev Checks the specific and general pause types. - * @param _pauseType The pause type value being checked. - */ - function _requireTypeAndGeneralNotPaused(uint8 _pauseType) internal view virtual { - uint256 pauseBitMap = _pauseTypeStatusesBitMap; - - if (pauseBitMap & (1 << uint256(_pauseType)) != 0) { - revert IsPaused(_pauseType); - } - - if (pauseBitMap & (1 << uint256(GENERAL_PAUSE_TYPE)) != 0) { - revert IsPaused(GENERAL_PAUSE_TYPE); - } - } - - /** - * @dev Throws if the type is paused. - * @dev Checks the specific pause type. - * @param _pauseType The pause type value being checked. - */ - function _requireTypeNotPaused(uint8 _pauseType) internal view virtual { - if (isPaused(_pauseType)) { - revert IsPaused(_pauseType); - } - } - - /** - * @notice Pauses functionality by specific type. - * @dev Requires PAUSE_MANAGER_ROLE. - * @param _pauseType The pause type value. - */ - function pauseByType(uint8 _pauseType) external onlyRole(PAUSE_MANAGER_ROLE) { - if (isPaused(_pauseType)) { - revert IsPaused(_pauseType); - } - - _pauseTypeStatusesBitMap |= 1 << uint256(_pauseType); - emit Paused(_msgSender(), _pauseType); - } - - /** - * @notice Unpauses functionality by specific type. - * @dev Requires PAUSE_MANAGER_ROLE. - * @param _pauseType The pause type value. - */ - function unPauseByType(uint8 _pauseType) external onlyRole(PAUSE_MANAGER_ROLE) { - if (!isPaused(_pauseType)) { - revert IsNotPaused(_pauseType); - } - - _pauseTypeStatusesBitMap &= ~(1 << uint256(_pauseType)); - emit UnPaused(_msgSender(), _pauseType); - } - - /** - * @notice Check if a pause type is enabled. - * @param _pauseType The pause type value. - * @return boolean True if the pause type if enabled, false otherwise. - */ - function isPaused(uint8 _pauseType) public view returns (bool) { - return (_pauseTypeStatusesBitMap & (1 << uint256(_pauseType))) != 0; - } -} - -// File contracts/interfaces/IRateLimiter.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity >=0.8.19 <=0.8.24; - -/** - * @title Interface declaring rate limiting messaging functions, events and errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface IRateLimiter { - /** - * @notice Emitted when the Rate Limit is initialized. - * @param periodInSeconds The time period in seconds the rate limiter has been initialized to. - * @param limitInWei The limit in Wei the rate limiter has been initialized to. - * @param currentPeriodEnd The time the current rate limit period will end. - */ - event RateLimitInitialized(uint256 periodInSeconds, uint256 limitInWei, uint256 currentPeriodEnd); - - /** - * @notice Emitted when the amount in the period is reset to zero. - * @param resettingAddress The indexed address of who reset the used amount back to zero. - */ - event AmountUsedInPeriodReset(address indexed resettingAddress); - - /** - * @notice Emitted when the limit is changed. - * @param amountChangeBy The indexed address of who changed the rate limit. - * @param amount The rate limited amount in Wei that was set. - * @param amountUsedLoweredToLimit Indicates if the amount used was lowered to the limit to avoid confusion. - * @param usedAmountResetToZero Indicates if the amount used was set to zero because of the current period expiring. - * @dev If the current used amount is higher than the new limit, the used amount is lowered to the limit. - * @dev amountUsedLoweredToLimit and usedAmountResetToZero cannot be true at the same time. - */ - event LimitAmountChanged( - address indexed amountChangeBy, - uint256 amount, - bool amountUsedLoweredToLimit, - bool usedAmountResetToZero - ); - - /** - * @dev Thrown when an amount breaches the limit in the period. - */ - error RateLimitExceeded(); - - /** - * @dev Thrown when the period is initialised to zero. - */ - error PeriodIsZero(); - - /** - * @dev Thrown when the limit is initialised to zero. - */ - error LimitIsZero(); - - /** - * @notice Resets the rate limit amount to the amount specified. - * @param _amount sets the new limit amount. - */ - function resetRateLimitAmount(uint256 _amount) external; - - /** - * @notice Resets the amount used in the period to zero. - */ - function resetAmountUsedInPeriod() external; -} - -// File contracts/messageService/lib/RateLimiter.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity >=0.8.19 <=0.8.24; - -/** - * @title Rate Limiter by period and amount using the block timestamp. - * @author ConsenSys Software Inc. - * @notice You can use this control numeric limits over a period using timestamp. - * @custom:security-contact security-report@linea.build - */ -contract RateLimiter is Initializable, IRateLimiter, AccessControlUpgradeable { - bytes32 public constant RATE_LIMIT_SETTER_ROLE = keccak256("RATE_LIMIT_SETTER_ROLE"); - - uint256 public periodInSeconds; // how much time before limit resets. - uint256 public limitInWei; // max ether to withdraw per period. - - /// @dev Public for ease of consumption. - /// @notice The time at which the current period ends at. - uint256 public currentPeriodEnd; - - /// @dev Public for ease of consumption. - /// @notice Amounts already withdrawn this period. - uint256 public currentPeriodAmountInWei; - - /// @dev Total contract storage is 14 slots with the gap below. - /// @dev Keep 10 free storage slots for future implementation updates to avoid storage collision. - uint256[10] private __gap; - - /** - * @notice Initialises the limits and period for the rate limiter. - * @param _periodInSeconds The length of the period in seconds. - * @param _limitInWei The limit allowed in the period in Wei. - */ - function __RateLimiter_init(uint256 _periodInSeconds, uint256 _limitInWei) internal onlyInitializing { - if (_periodInSeconds == 0) { - revert PeriodIsZero(); - } - - if (_limitInWei == 0) { - revert LimitIsZero(); - } - - periodInSeconds = _periodInSeconds; - limitInWei = _limitInWei; - currentPeriodEnd = block.timestamp + _periodInSeconds; - - emit RateLimitInitialized(periodInSeconds, limitInWei, currentPeriodEnd); - } - - /** - * @notice Increments the amount used in the period. - * @dev The amount determining logic is external to this (e.g. fees are included when calling here). - * @dev Reverts if the limit is breached. - * @param _usedAmount The amount used to be added. - */ - function _addUsedAmount(uint256 _usedAmount) internal { - uint256 currentPeriodAmountTemp; - - if (currentPeriodEnd < block.timestamp) { - currentPeriodEnd = block.timestamp + periodInSeconds; - currentPeriodAmountTemp = _usedAmount; - } else { - currentPeriodAmountTemp = currentPeriodAmountInWei + _usedAmount; - } - - if (currentPeriodAmountTemp > limitInWei) { - revert RateLimitExceeded(); - } - - currentPeriodAmountInWei = currentPeriodAmountTemp; - } - - /** - * @notice Resets the rate limit amount. - * @dev If the used amount is higher, it is set to the limit to avoid confusion/issues. - * @dev Only the RATE_LIMIT_SETTER_ROLE is allowed to execute this function. - * @dev Emits the LimitAmountChanged event. - * @dev usedLimitAmountToSet will use the default value of zero if period has expired - * @param _amount The amount to reset the limit to. - */ - function resetRateLimitAmount(uint256 _amount) external onlyRole(RATE_LIMIT_SETTER_ROLE) { - uint256 usedLimitAmountToSet; - bool amountUsedLoweredToLimit; - bool usedAmountResetToZero; - - if (currentPeriodEnd < block.timestamp) { - currentPeriodEnd = block.timestamp + periodInSeconds; - usedAmountResetToZero = true; - } else { - if (_amount < currentPeriodAmountInWei) { - usedLimitAmountToSet = _amount; - amountUsedLoweredToLimit = true; - } - } - - limitInWei = _amount; - - if (usedAmountResetToZero || amountUsedLoweredToLimit) { - currentPeriodAmountInWei = usedLimitAmountToSet; - } - - emit LimitAmountChanged(_msgSender(), _amount, amountUsedLoweredToLimit, usedAmountResetToZero); - } - - /** - * @notice Resets the amount used to zero. - * @dev Only the RATE_LIMIT_SETTER_ROLE is allowed to execute this function. - * @dev Emits the AmountUsedInPeriodReset event. - */ - function resetAmountUsedInPeriod() external onlyRole(RATE_LIMIT_SETTER_ROLE) { - currentPeriodAmountInWei = 0; - - emit AmountUsedInPeriodReset(_msgSender()); - } -} - -// File contracts/messageService/l1/v1/L1MessageServiceV1.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Contract to manage cross-chain messaging on L1. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -abstract contract L1MessageServiceV1 is - Initializable, - RateLimiter, - L1MessageManagerV1, - TransientStorageReentrancyGuardUpgradeable, - PauseManager, - IMessageService -{ - // @dev This is initialised to save user cost with existing slot. - uint256 public nextMessageNumber; - - /// @dev DEPRECATED in favor of new transient storage with `MESSAGE_SENDER_TRANSIENT_KEY` key. - address internal _messageSender; - - /// @dev Total contract storage is 52 slots including the gap below. - /// @dev Keep 50 free storage slots for future implementation updates to avoid storage collision. - uint256[50] private __gap; - - /// @dev adding these should not affect storage as they are constants and are stored in bytecode. - uint256 internal constant REFUND_OVERHEAD_IN_GAS = 48252; - - bytes32 internal constant MESSAGE_SENDER_TRANSIENT_KEY = - bytes32(uint256(keccak256("eip1967.message.sender.transient.key")) - 1); - - address internal constant DEFAULT_MESSAGE_SENDER_TRANSIENT_VALUE = address(0); - - /** - * @notice The unspent fee is refunded if applicable. - * @param _feeInWei The fee paid for delivery in Wei. - * @param _to The recipient of the message and gas refund. - * @param _calldata The calldata of the message. - */ - modifier distributeFees( - uint256 _feeInWei, - address _to, - bytes calldata _calldata, - address _feeRecipient - ) { - //pre-execution - uint256 startingGas = gasleft(); - _; - //post-execution - - // we have a fee - if (_feeInWei > 0) { - // default postman fee - uint256 deliveryFee = _feeInWei; - - // do we have empty calldata? - if (_calldata.length == 0) { - bool isDestinationEOA; - - assembly { - isDestinationEOA := iszero(extcodesize(_to)) - } - - // are we calling an EOA - if (isDestinationEOA) { - // initial + cost to call and refund minus gasleft - deliveryFee = (startingGas + REFUND_OVERHEAD_IN_GAS - gasleft()) * tx.gasprice; - - if (_feeInWei > deliveryFee) { - payable(_to).send(_feeInWei - deliveryFee); - } else { - deliveryFee = _feeInWei; - } - } - } - - address feeReceiver = _feeRecipient == address(0) ? msg.sender : _feeRecipient; - - bool callSuccess = payable(feeReceiver).send(deliveryFee); - if (!callSuccess) { - revert FeePaymentFailed(feeReceiver); - } - } - } - - /** - * @notice Claims and delivers a cross-chain message. - * @dev _feeRecipient can be set to address(0) to receive as msg.sender. - * @dev _messageSender is set temporarily when claiming and reset post. Used in sender(). - * @dev _messageSender is reset to DEFAULT_SENDER_ADDRESS to be more gas efficient. - * @param _from The address of the original sender. - * @param _to The address the message is intended for. - * @param _fee The fee being paid for the message delivery. - * @param _value The value to be transferred to the destination address. - * @param _feeRecipient The recipient for the fee. - * @param _calldata The calldata to pass to the recipient. - * @param _nonce The unique auto generated nonce used when sending the message. - */ - function claimMessage( - address _from, - address _to, - uint256 _fee, - uint256 _value, - address payable _feeRecipient, - bytes calldata _calldata, - uint256 _nonce - ) external nonReentrant distributeFees(_fee, _to, _calldata, _feeRecipient) { - _requireTypeAndGeneralNotPaused(L2_L1_PAUSE_TYPE); - - /// @dev This is placed earlier to fix the stack issue by using these two earlier on. - TransientStorageHelpers.tstoreAddress(MESSAGE_SENDER_TRANSIENT_KEY, _from); - - bytes32 messageHash = keccak256(abi.encode(_from, _to, _fee, _value, _nonce, _calldata)); - - // @dev Status check and revert is in the message manager. - _updateL2L1MessageStatusToClaimed(messageHash); - - _addUsedAmount(_fee + _value); - - (bool callSuccess, bytes memory returnData) = _to.call{ value: _value }(_calldata); - if (!callSuccess) { - if (returnData.length > 0) { - assembly { - let data_size := mload(returnData) - revert(add(32, returnData), data_size) - } - } else { - revert MessageSendingFailed(_to); - } - } - - TransientStorageHelpers.tstoreAddress(MESSAGE_SENDER_TRANSIENT_KEY, DEFAULT_MESSAGE_SENDER_TRANSIENT_VALUE); - - emit MessageClaimed(messageHash); - } -} - -// File contracts/messageService/lib/SparseMerkleTreeVerifier.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Library to verify sparse merkle proofs and to get the leaf hash value - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -library SparseMerkleTreeVerifier { - /** - * @notice Verify merkle proof - * @param _leafHash Leaf hash. - * @param _proof Sparse merkle tree proof. - * @param _leafIndex Index of the leaf. - * @param _root Merkle root. - */ - function _verifyMerkleProof( - bytes32 _leafHash, - bytes32[] calldata _proof, - uint32 _leafIndex, - bytes32 _root - ) internal pure returns (bool) { - bytes32 node = _leafHash; - - for (uint256 height; height < _proof.length; ++height) { - if (((_leafIndex >> height) & 1) == 1) { - node = _efficientKeccak(_proof[height], node); - } else { - node = _efficientKeccak(node, _proof[height]); - } - } - return node == _root; - } - - /** - * @notice Performs a gas optimized keccak hash - * @param _left Left value. - * @param _right Right value. - */ - function _efficientKeccak(bytes32 _left, bytes32 _right) internal pure returns (bytes32 value) { - assembly { - mstore(0x00, _left) - mstore(0x20, _right) - value := keccak256(0x00, 0x40) - } - } -} - -// File contracts/messageService/l1/L1MessageService.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Contract to manage cross-chain messaging on L1. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -abstract contract L1MessageService is - AccessControlUpgradeable, - L1MessageServiceV1, - L1MessageManager, - IL1MessageService, - IGenericErrors -{ - using SparseMerkleTreeVerifier for *; - using TransientStorageHelpers for *; - - /// @dev This is currently not in use, but is reserved for future upgrades. - uint256 public systemMigrationBlock; - - /// @dev Total contract storage is 51 slots including the gap below. - /// @dev Keep 50 free storage slots for future implementation updates to avoid storage collision. - uint256[50] private __gap_L1MessageService; - - /** - * @notice Initialises underlying message service dependencies. - * @dev _messageSender is initialised to a non-zero value for gas efficiency on claiming. - * @param _limitManagerAddress The address owning the rate limiting management role. - * @param _pauseManagerAddress The address owning the pause management role. - * @param _rateLimitPeriod The period to rate limit against. - * @param _rateLimitAmount The limit allowed for withdrawing the period. - */ - function __MessageService_init( - address _limitManagerAddress, - address _pauseManagerAddress, - uint256 _rateLimitPeriod, - uint256 _rateLimitAmount - ) internal onlyInitializing { - if (_limitManagerAddress == address(0)) { - revert ZeroAddressNotAllowed(); - } - - if (_pauseManagerAddress == address(0)) { - revert ZeroAddressNotAllowed(); - } - - __ERC165_init(); - __Context_init(); - __AccessControl_init(); - __RateLimiter_init(_rateLimitPeriod, _rateLimitAmount); - - _grantRole(RATE_LIMIT_SETTER_ROLE, _limitManagerAddress); - _grantRole(PAUSE_MANAGER_ROLE, _pauseManagerAddress); - - nextMessageNumber = 1; - } - - /** - * @notice Adds a message for sending cross-chain and emits MessageSent. - * @dev The message number is preset (nextMessageNumber) and only incremented at the end if successful for the next caller. - * @dev This function should be called with a msg.value = _value + _fee. The fee will be paid on the destination chain. - * @param _to The address the message is intended for. - * @param _fee The fee being paid for the message delivery. - * @param _calldata The calldata to pass to the recipient. - */ - function sendMessage( - address _to, - uint256 _fee, - bytes calldata _calldata - ) external payable whenTypeAndGeneralNotPaused(L1_L2_PAUSE_TYPE) { - if (_to == address(0)) { - revert ZeroAddressNotAllowed(); - } - - if (_fee > msg.value) { - revert ValueSentTooLow(); - } - - uint256 messageNumber = nextMessageNumber++; - uint256 valueSent = msg.value - _fee; - - bytes32 messageHash = keccak256(abi.encode(msg.sender, _to, _fee, valueSent, messageNumber, _calldata)); - - _addRollingHash(messageNumber, messageHash); - - emit MessageSent(msg.sender, _to, _fee, valueSent, messageNumber, _calldata, messageHash); - } - - /** - * @notice Claims and delivers a cross-chain message using merkle proof. - * @dev if merkle depth is empty, it will revert with L2MerkleRootDoesNotExist. - * @dev if merkle depth is different than proof size, it will revert with ProofLengthDifferentThanMerkleDepth. - * @param _params Collection of claim data with proof and supporting data. - */ - function claimMessageWithProof( - ClaimMessageWithProofParams calldata _params - ) external nonReentrant distributeFees(_params.fee, _params.to, _params.data, _params.feeRecipient) { - _requireTypeAndGeneralNotPaused(L2_L1_PAUSE_TYPE); - - uint256 merkleDepth = l2MerkleRootsDepths[_params.merkleRoot]; - - if (merkleDepth == 0) { - revert L2MerkleRootDoesNotExist(); - } - - if (merkleDepth != _params.proof.length) { - revert ProofLengthDifferentThanMerkleDepth(merkleDepth, _params.proof.length); - } - - _setL2L1MessageToClaimed(_params.messageNumber); - - _addUsedAmount(_params.fee + _params.value); - - bytes32 messageLeafHash = keccak256( - abi.encode(_params.from, _params.to, _params.fee, _params.value, _params.messageNumber, _params.data) - ); - - if ( - !SparseMerkleTreeVerifier._verifyMerkleProof( - messageLeafHash, - _params.proof, - _params.leafIndex, - _params.merkleRoot - ) - ) { - revert InvalidMerkleProof(); - } - - TransientStorageHelpers.tstoreAddress(MESSAGE_SENDER_TRANSIENT_KEY, _params.from); - - (bool callSuccess, bytes memory returnData) = _params.to.call{ value: _params.value }(_params.data); - if (!callSuccess) { - if (returnData.length > 0) { - assembly { - let data_size := mload(returnData) - revert(add(32, returnData), data_size) - } - } else { - revert MessageSendingFailed(_params.to); - } - } - - TransientStorageHelpers.tstoreAddress(MESSAGE_SENDER_TRANSIENT_KEY, DEFAULT_MESSAGE_SENDER_TRANSIENT_VALUE); - - emit MessageClaimed(messageLeafHash); - } - - /** - * @notice Claims and delivers a cross-chain message. - * @dev The message sender address is set temporarily in the transient storage when claiming. - * @return addr The message sender address that is stored temporarily in the transient storage when claiming. - */ - function sender() external view returns (address addr) { - return TransientStorageHelpers.tloadAddress(MESSAGE_SENDER_TRANSIENT_KEY); - } -} - -// File contracts/interfaces/l1/IPlonkVerifier.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity 0.8.24; - -/** - * @title Interface declaring verifier functions. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface IPlonkVerifier { - /** - * @notice Interface for verifier contracts. - * @param _proof The proof used to verify. - * @param _public_inputs The computed public inputs for the proof verification. - */ - function Verify(bytes calldata _proof, uint256[] calldata _public_inputs) external returns (bool); -} - -// File contracts/interfaces/l1/IZkEvmV2.sol - -// Original license: SPDX_License_Identifier: Apache-2.0 -pragma solidity 0.8.24; - -/** - * @title ZkEvm rollup interface for pre-existing functions, events and errors. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -interface IZkEvmV2 { - /** - * @notice Emitted when a L2 block has been finalized on L1. - * @param blockNumber The indexed L2 block number that is finalized in the finalization. - * @param stateRootHash The indexed state root hash for the L2 block. - * @param finalizedWithProof Indicates if the L2 block in the finalization is proven or not. - * @dev DEPRECATED. This has been left for existing consumers. - */ - event BlockFinalized(uint256 indexed blockNumber, bytes32 indexed stateRootHash, bool indexed finalizedWithProof); - - /** - * @notice Emitted when a L2 blocks have been finalized on L1. - * @param lastBlockFinalized The indexed L2 block number the finalization is up until. - * @param startingRootHash The state root hash the finalization started from. This is the last finalized block's state root. - * @param finalRootHash The L2 block state root hash the finalization ended on. - */ - event BlocksVerificationDone(uint256 indexed lastBlockFinalized, bytes32 startingRootHash, bytes32 finalRootHash); - - /** - * @dev Thrown when the starting rootHash does not match the existing state - */ - error StartingRootHashDoesNotMatch(); - - /** - * @dev Thrown when zk proof is empty bytes - */ - error ProofIsEmpty(); - - /** - * @dev Thrown when zk proof type is invalid - */ - error InvalidProofType(); - - /** - * @dev Thrown when zk proof is invalid - */ - error InvalidProof(); -} - -// File contracts/ZkEvmV2.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Contract to manage cross-chain messaging on L1 and rollup proving. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -abstract contract ZkEvmV2 is Initializable, AccessControlUpgradeable, L1MessageServiceV1, IZkEvmV2 { - uint256 internal constant MODULO_R = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE"); - - /// @dev DEPRECATED in favor of currentFinalizedState hash. - uint256 public currentTimestamp; - - uint256 public currentL2BlockNumber; - - mapping(uint256 blockNumber => bytes32 stateRootHash) public stateRootHashes; - mapping(uint256 proofType => address verifierAddress) public verifiers; - - /// @dev Total contract storage is 54 slots with the gap below. - /// @dev Keep 50 free storage slots for future implementation updates to avoid storage collision. - uint256[50] private __gap; - - /** - * @notice Verifies the proof with locally computed public inputs. - * @dev If the verifier based on proof type is not found, it reverts with InvalidProofType. - * @param _publicInputHash The full BlockData collection - block, transaction and log data. - * @param _proofType The proof type to determine which verifier contract to use. - * @param _proof The proof to be verified with the proof type verifier contract. - * @param _parentStateRootHash The beginning roothash to start with. - * @param _finalizedL2BlockNumber The final L2 block number being finalized. - * @param _finalStateRootHash The state root finalized up until. - */ - function _verifyProof( - uint256 _publicInputHash, - uint256 _proofType, - bytes calldata _proof, - bytes32 _parentStateRootHash, - uint256 _finalizedL2BlockNumber, - bytes32 _finalStateRootHash - ) internal { - uint256[] memory input = new uint256[](1); - input[0] = _publicInputHash; - - address verifierToUse = verifiers[_proofType]; - - if (verifierToUse == address(0)) { - revert InvalidProofType(); - } - - bool success = IPlonkVerifier(verifierToUse).Verify(_proof, input); - if (!success) { - revert InvalidProof(); - } - - emit BlocksVerificationDone(_finalizedL2BlockNumber, _parentStateRootHash, _finalStateRootHash); - } -} - -// File contracts/LineaRollupV5.sol - -// Original license: SPDX_License_Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -/** - * @title Contract to manage cross-chain messaging on L1, L2 data submission, and rollup proof verification. - * @author ConsenSys Software Inc. - * @custom:security-contact security-report@linea.build - */ -contract LineaRollupV5 is AccessControlUpgradeable, ZkEvmV2, L1MessageService, ILineaRollupV5 { - using Utils for *; - - bytes32 public constant VERIFIER_SETTER_ROLE = keccak256("VERIFIER_SETTER_ROLE"); - bytes32 public constant GENESIS_SHNARF = - keccak256( - abi.encode( - EMPTY_HASH, - EMPTY_HASH, - 0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd, - EMPTY_HASH, - EMPTY_HASH - ) - ); - - bytes32 internal constant EMPTY_HASH = 0x0; - uint256 internal constant BLS_CURVE_MODULUS = - 52435875175126190479447740508185965837690552500527637822603658699938581184513; - address internal constant POINT_EVALUATION_PRECOMPILE_ADDRESS = address(0x0a); - uint256 internal constant POINT_EVALUATION_RETURN_DATA_LENGTH = 64; - uint256 internal constant POINT_EVALUATION_FIELD_ELEMENTS_LENGTH = 4096; - - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. - mapping(bytes32 dataHash => bytes32 finalStateRootHash) public dataFinalStateRootHashes; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. - mapping(bytes32 dataHash => bytes32 parentHash) public dataParents; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. - mapping(bytes32 dataHash => bytes32 shnarfHash) public dataShnarfHashes; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. - mapping(bytes32 dataHash => uint256 startingBlock) public dataStartingBlock; - /// @dev DEPRECATED in favor of the single shnarfFinalBlockNumbers mapping. - mapping(bytes32 dataHash => uint256 endingBlock) public dataEndingBlock; - - /// @dev DEPRECATED in favor of currentFinalizedState hash. - uint256 public currentL2StoredL1MessageNumber; - /// @dev DEPRECATED in favor of currentFinalizedState hash. - bytes32 public currentL2StoredL1RollingHash; - - bytes32 public currentFinalizedShnarf; - - /** - * @dev NB: THIS IS THE ONLY MAPPING BEING USED FOR DATA SUBMISSION TRACKING. - */ - mapping(bytes32 shnarf => uint256 finalBlockNumber) public shnarfFinalBlockNumbers; - - /// @dev Hash of the L2 computed L1 message number, rolling hash and finalized timestamp. - bytes32 public currentFinalizedState; - - /// @dev Total contract storage is 10 slots. - - /// @custom:oz-upgrades-unsafe-allow constructor - constructor() { - _disableInitializers(); - } - - /** - * @notice Initializes LineaRollup and underlying service dependencies - used for new networks only. - * @dev DEFAULT_ADMIN_ROLE is set for the security council. - * @dev OPERATOR_ROLE is set for operators. - * @dev Note: This is used for new testnets and local/CI testing, and will not replace existing proxy based contracts. - * @param _initialStateRootHash The initial hash at migration used for proof verification. - * @param _initialL2BlockNumber The initial block number at migration. - * @param _defaultVerifier The default verifier for rollup proofs. - * @param _securityCouncil The address for the security council performing admin operations. - * @param _operators The allowed rollup operators at initialization. - * @param _rateLimitPeriodInSeconds The period in which withdrawal amounts and fees will be accumulated. - * @param _rateLimitAmountInWei The limit allowed for withdrawing in the rate limit period. - * @param _genesisTimestamp The L2 genesis timestamp for first finalization. - */ - function initialize( - bytes32 _initialStateRootHash, - uint256 _initialL2BlockNumber, - address _defaultVerifier, - address _securityCouncil, - address[] calldata _operators, - uint256 _rateLimitPeriodInSeconds, - uint256 _rateLimitAmountInWei, - uint256 _genesisTimestamp - ) external initializer { - if (_defaultVerifier == address(0)) { - revert ZeroAddressNotAllowed(); - } - - for (uint256 i; i < _operators.length; ++i) { - if (_operators[i] == address(0)) { - revert ZeroAddressNotAllowed(); - } - _grantRole(OPERATOR_ROLE, _operators[i]); - } - - _grantRole(DEFAULT_ADMIN_ROLE, _securityCouncil); - _grantRole(VERIFIER_SETTER_ROLE, _securityCouncil); - - __MessageService_init(_securityCouncil, _securityCouncil, _rateLimitPeriodInSeconds, _rateLimitAmountInWei); - - verifiers[0] = _defaultVerifier; - - currentL2BlockNumber = _initialL2BlockNumber; - stateRootHashes[_initialL2BlockNumber] = _initialStateRootHash; - - shnarfFinalBlockNumbers[GENESIS_SHNARF] = _initialL2BlockNumber; - - currentFinalizedShnarf = GENESIS_SHNARF; - currentFinalizedState = _computeLastFinalizedState(0, EMPTY_HASH, _genesisTimestamp); - } - - /** - * @notice Initializes LineaRollup, sets the expected shnarfFinalBlockNumbers final block number(s) and sets finalization state. - * @dev The initialization will only do the last finalized shnarf and the unfinalized shnarfs of unfinalized data submissions. - * @dev Data submission and finalization will be paused temporarily to avoid missing submissions. - * @dev currentFinalizedState will also be initialized with existing storage values. - * @param _shnarfs The shnarfs to reset. - * @param _finalBlockNumbers The final blocks number to reset 1:1 with the shnarfs. - */ - function initializeParentShnarfsAndFinalizedState( - bytes32[] calldata _shnarfs, - uint256[] calldata _finalBlockNumbers - ) external reinitializer(5) { - if (_shnarfs.length != _finalBlockNumbers.length) { - revert ShnarfAndFinalBlockNumberLengthsMismatched(_shnarfs.length, _finalBlockNumbers.length); - } - - for (uint256 i; i < _shnarfs.length; i++) { - shnarfFinalBlockNumbers[_shnarfs[i]] = _finalBlockNumbers[i]; - } - - currentFinalizedState = _computeLastFinalizedState( - currentL2StoredL1MessageNumber, - currentL2StoredL1RollingHash, - currentTimestamp - ); - } - - /** - * @notice Adds or updates the verifier contract address for a proof type. - * @dev VERIFIER_SETTER_ROLE is required to execute. - * @param _newVerifierAddress The address for the verifier contract. - * @param _proofType The proof type being set/updated. - */ - function setVerifierAddress(address _newVerifierAddress, uint256 _proofType) external onlyRole(VERIFIER_SETTER_ROLE) { - if (_newVerifierAddress == address(0)) { - revert ZeroAddressNotAllowed(); - } - - emit VerifierAddressChanged(_newVerifierAddress, _proofType, msg.sender, verifiers[_proofType]); - - verifiers[_proofType] = _newVerifierAddress; - } - - /** - * @notice Unset the verifier contract address for a proof type. - * @dev VERIFIER_SETTER_ROLE is required to execute. - * @param _proofType The proof type being set/updated. - */ - function unsetVerifierAddress(uint256 _proofType) external onlyRole(VERIFIER_SETTER_ROLE) { - emit VerifierAddressChanged(address(0), _proofType, msg.sender, verifiers[_proofType]); - - delete verifiers[_proofType]; - } - - /** - * @notice Submit one or more EIP-4844 blobs. - * @dev OPERATOR_ROLE is required to execute. - * @dev This should be a blob carrying transaction. - * @param _blobSubmissionData The data for blob submission including proofs and required polynomials. - * @param _parentShnarf The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. - * @param _finalBlobShnarf The expected final shnarf post computation of all the blob shnarfs. - */ - function submitBlobs( - BlobSubmissionData[] calldata _blobSubmissionData, - bytes32 _parentShnarf, - bytes32 _finalBlobShnarf - ) external whenTypeAndGeneralNotPaused(PROVING_SYSTEM_PAUSE_TYPE) onlyRole(OPERATOR_ROLE) { - uint256 blobSubmissionLength = _blobSubmissionData.length; - - if (blobSubmissionLength == 0) { - revert BlobSubmissionDataIsMissing(); - } - - bytes32 currentDataEvaluationPoint; - bytes32 currentDataHash; - uint256 lastFinalizedBlockNumber = currentL2BlockNumber; - - /// @dev Assigning in memory saves a lot of gas vs. calldata reading. - BlobSubmissionData memory blobSubmissionData; - - bytes32 computedShnarf = _parentShnarf; - - uint256 blobFinalBlockNumber = shnarfFinalBlockNumbers[computedShnarf]; - - for (uint256 i; i < blobSubmissionLength; i++) { - blobSubmissionData = _blobSubmissionData[i]; - - currentDataHash = blobhash(i); - - if (currentDataHash == EMPTY_HASH) { - revert EmptyBlobDataAtIndex(i); - } - - _validateSubmissionData(blobSubmissionData.submissionData, blobFinalBlockNumber, lastFinalizedBlockNumber); - - currentDataEvaluationPoint = Utils._efficientKeccak(blobSubmissionData.submissionData.snarkHash, currentDataHash); - - _verifyPointEvaluation( - currentDataHash, - uint256(currentDataEvaluationPoint), - blobSubmissionData.dataEvaluationClaim, - blobSubmissionData.kzgCommitment, - blobSubmissionData.kzgProof - ); - - computedShnarf = _computeShnarf( - computedShnarf, - blobSubmissionData.submissionData.snarkHash, - blobSubmissionData.submissionData.finalStateRootHash, - currentDataEvaluationPoint, - bytes32(blobSubmissionData.dataEvaluationClaim) - ); - - blobFinalBlockNumber = blobSubmissionData.submissionData.finalBlockInData; - } - - if (_finalBlobShnarf != computedShnarf) { - revert FinalShnarfWrong(_finalBlobShnarf, computedShnarf); - } - - /** - * @dev validate we haven't submitted the last shnarf. - * Note: As only the last shnarf is stored, we don't need to validate shnarfs, - * computed for any previous blobs in the submission (if multiple are submitted). - */ - if (shnarfFinalBlockNumbers[computedShnarf] != 0) { - revert DataAlreadySubmitted(computedShnarf); - } - - /// @dev use the last shnarf as the submission to store as technically it becomes the next parent shnarf. - shnarfFinalBlockNumbers[computedShnarf] = blobFinalBlockNumber; - - emit DataSubmittedV2(computedShnarf, _blobSubmissionData[0].submissionData.firstBlockInData, blobFinalBlockNumber); - } - - /** - * @notice Submit blobs using compressed data via calldata. - * @dev OPERATOR_ROLE is required to execute. - * @param _submissionData The supporting data for compressed data submission including compressed data. - * @param _parentShnarf The parent shnarf used in continuity checks as it includes the parentStateRootHash in its computation. - * @param _expectedShnarf The expected shnarf post computation of all the submission. - */ - function submitDataAsCalldata( - SubmissionDataV2 calldata _submissionData, - bytes32 _parentShnarf, - bytes32 _expectedShnarf - ) external whenTypeAndGeneralNotPaused(PROVING_SYSTEM_PAUSE_TYPE) onlyRole(OPERATOR_ROLE) { - if (_submissionData.compressedData.length == 0) { - revert EmptySubmissionData(); - } - - SupportingSubmissionDataV2 memory submissionData = SupportingSubmissionDataV2({ - finalStateRootHash: _submissionData.finalStateRootHash, - firstBlockInData: _submissionData.firstBlockInData, - finalBlockInData: _submissionData.finalBlockInData, - snarkHash: _submissionData.snarkHash - }); - - bytes32 currentDataHash = keccak256(_submissionData.compressedData); - - _validateSubmissionData(submissionData, shnarfFinalBlockNumbers[_parentShnarf], currentL2BlockNumber); - - bytes32 dataEvaluationPoint = Utils._efficientKeccak(_submissionData.snarkHash, currentDataHash); - bytes32 computedShnarf = _computeShnarf( - _parentShnarf, - _submissionData.snarkHash, - _submissionData.finalStateRootHash, - dataEvaluationPoint, - _calculateY(_submissionData.compressedData, dataEvaluationPoint) - ); - - if (_expectedShnarf != computedShnarf) { - revert FinalShnarfWrong(_expectedShnarf, computedShnarf); - } - - if (shnarfFinalBlockNumbers[computedShnarf] != 0) { - revert DataAlreadySubmitted(computedShnarf); - } - - shnarfFinalBlockNumbers[computedShnarf] = _submissionData.finalBlockInData; - - emit DataSubmittedV2(computedShnarf, _submissionData.firstBlockInData, _submissionData.finalBlockInData); - } - - /** - * @notice Internal function to validate submission data. - * @param _submissionData The supporting data for compressed data submission excluding compressed data. - * @param _parentFinalBlockNumber The final block number for the parent blob. - * @param _lastFinalizedBlockNumber The last finalized block number. - */ - function _validateSubmissionData( - SupportingSubmissionDataV2 memory _submissionData, - uint256 _parentFinalBlockNumber, - uint256 _lastFinalizedBlockNumber - ) internal pure { - if (_submissionData.finalStateRootHash == EMPTY_HASH) { - revert FinalBlockStateEqualsZeroHash(); - } - - if (_submissionData.snarkHash == EMPTY_HASH) { - revert SnarkHashIsZeroHash(); - } - - // for it to be equal the number would have to wrap round twice in overflow.. - unchecked { - if (_parentFinalBlockNumber + 1 != _submissionData.firstBlockInData) { - revert DataStartingBlockDoesNotMatch(_parentFinalBlockNumber + 1, _submissionData.firstBlockInData); - } - } - - if (_submissionData.firstBlockInData <= _lastFinalizedBlockNumber) { - revert FirstBlockLessThanOrEqualToLastFinalizedBlock(_submissionData.firstBlockInData, _lastFinalizedBlockNumber); - } - - if (_submissionData.firstBlockInData > _submissionData.finalBlockInData) { - revert FirstBlockGreaterThanFinalBlock(_submissionData.firstBlockInData, _submissionData.finalBlockInData); - } - } - - /** - * @notice Internal function to compute and save the finalization state. - * @dev Using assembly this way is cheaper gas wise. - * @param _messageNumber Is the last L2 computed L1 message number in the finalization. - * @param _rollingHash Is the last L2 computed L1 rolling hash in the finalization. - * @param _timestamp The final timestamp in the finalization. - */ - function _computeLastFinalizedState( - uint256 _messageNumber, - bytes32 _rollingHash, - uint256 _timestamp - ) internal pure returns (bytes32 hashedFinalizationState) { - assembly { - let mPtr := mload(0x40) - mstore(mPtr, _messageNumber) - mstore(add(mPtr, 0x20), _rollingHash) - mstore(add(mPtr, 0x40), _timestamp) - hashedFinalizationState := keccak256(mPtr, 0x60) - } - } - - /** - * @notice Internal function to compute the shnarf more efficiently. - * @dev Using assembly this way is cheaper gas wise. - * @param _parentShnarf The shnarf of the parent data item. - * @param _snarkHash Is the computed hash for compressed data (using a SNARK-friendly hash function) that aggregates per data submission to be used in public input. - * @param _finalStateRootHash The final state root hash of the data being submitted. - * @param _dataEvaluationPoint The data evaluation point. - * @param _dataEvaluationClaim The data evaluation claim. - */ - function _computeShnarf( - bytes32 _parentShnarf, - bytes32 _snarkHash, - bytes32 _finalStateRootHash, - bytes32 _dataEvaluationPoint, - bytes32 _dataEvaluationClaim - ) internal pure returns (bytes32 shnarf) { - assembly { - let mPtr := mload(0x40) - mstore(mPtr, _parentShnarf) - mstore(add(mPtr, 0x20), _snarkHash) - mstore(add(mPtr, 0x40), _finalStateRootHash) - mstore(add(mPtr, 0x60), _dataEvaluationPoint) - mstore(add(mPtr, 0x80), _dataEvaluationClaim) - shnarf := keccak256(mPtr, 0xA0) - } - } - - /** - * @notice Performs point evaluation for the compressed blob. - * @dev _dataEvaluationPoint is modular reduced to be lower than the BLS_CURVE_MODULUS for precompile checks. - * @param _currentDataHash The current blob versioned hash. - * @param _dataEvaluationPoint The data evaluation point. - * @param _dataEvaluationClaim The data evaluation claim. - * @param _kzgCommitment The blob KZG commitment. - * @param _kzgProof The blob KZG point proof. - */ - function _verifyPointEvaluation( - bytes32 _currentDataHash, - uint256 _dataEvaluationPoint, - uint256 _dataEvaluationClaim, - bytes memory _kzgCommitment, - bytes memory _kzgProof - ) internal view { - assembly { - _dataEvaluationPoint := mod(_dataEvaluationPoint, BLS_CURVE_MODULUS) - } - - (bool success, bytes memory returnData) = POINT_EVALUATION_PRECOMPILE_ADDRESS.staticcall( - abi.encodePacked(_currentDataHash, _dataEvaluationPoint, _dataEvaluationClaim, _kzgCommitment, _kzgProof) - ); - - if (!success) { - revert PointEvaluationFailed(); - } - - if (returnData.length != POINT_EVALUATION_RETURN_DATA_LENGTH) { - revert PrecompileReturnDataLengthWrong(POINT_EVALUATION_RETURN_DATA_LENGTH, returnData.length); - } - - uint256 fieldElements; - uint256 blsCurveModulus; - assembly { - fieldElements := mload(add(returnData, 32)) - blsCurveModulus := mload(add(returnData, POINT_EVALUATION_RETURN_DATA_LENGTH)) - } - if (fieldElements != POINT_EVALUATION_FIELD_ELEMENTS_LENGTH || blsCurveModulus != BLS_CURVE_MODULUS) { - revert PointEvaluationResponseInvalid(fieldElements, blsCurveModulus); - } - } - - /** - * @notice Finalize compressed blocks with proof. - * @dev OPERATOR_ROLE is required to execute. - * @param _aggregatedProof The aggregated proof. - * @param _proofType The proof type. - * @param _finalizationData The full finalization data. - */ - function finalizeBlocksWithProof( - bytes calldata _aggregatedProof, - uint256 _proofType, - FinalizationDataV2 calldata _finalizationData - ) external whenTypeAndGeneralNotPaused(PROVING_SYSTEM_PAUSE_TYPE) onlyRole(OPERATOR_ROLE) { - if (_aggregatedProof.length == 0) { - revert ProofIsEmpty(); - } - - uint256 lastFinalizedBlockNumber = currentL2BlockNumber; - - if (stateRootHashes[lastFinalizedBlockNumber] != _finalizationData.parentStateRootHash) { - revert StartingRootHashDoesNotMatch(); - } - - bytes32 lastFinalizedShnarf = currentFinalizedShnarf; - - if (_finalizationData.lastFinalizedShnarf != lastFinalizedShnarf) { - revert LastFinalizedShnarfWrong(lastFinalizedShnarf, _finalizationData.lastFinalizedShnarf); - } - - bytes32 finalShnarf = _finalizeBlocks(_finalizationData, lastFinalizedBlockNumber, true); - - uint256 publicInput = _computePublicInput( - _finalizationData, - lastFinalizedShnarf, - finalShnarf, - lastFinalizedBlockNumber - ); - - _verifyProof( - publicInput, - _proofType, - _aggregatedProof, - _finalizationData.parentStateRootHash, - _finalizationData.finalBlockInData, - _finalizationData.shnarfData.finalStateRootHash - ); - } - - /** - * @notice Finalize compressed blocks without proof. - * @dev DEFAULT_ADMIN_ROLE is required to execute. - * @param _finalizationData The full finalization data. - */ - function finalizeBlocksWithoutProof( - FinalizationDataV2 calldata _finalizationData - ) external whenTypeNotPaused(GENERAL_PAUSE_TYPE) onlyRole(DEFAULT_ADMIN_ROLE) { - _finalizeBlocks(_finalizationData, currentL2BlockNumber, false); - } - - /** - * @notice Internal function to finalize compressed blocks. - * @param _finalizationData The full finalization data. - * @param _lastFinalizedBlock The last finalized block. - * @param _withProof If we are finalizing with a proof. - * @return finalShnarf The final computed shnarf in finalizing. - */ - function _finalizeBlocks( - FinalizationDataV2 calldata _finalizationData, - uint256 _lastFinalizedBlock, - bool _withProof - ) internal returns (bytes32 finalShnarf) { - if (_finalizationData.finalBlockInData <= _lastFinalizedBlock) { - revert FinalBlockNumberLessThanOrEqualToLastFinalizedBlock( - _finalizationData.finalBlockInData, - _lastFinalizedBlock - ); - } - - _validateL2ComputedRollingHash(_finalizationData.l1RollingHashMessageNumber, _finalizationData.l1RollingHash); - - if ( - _computeLastFinalizedState( - _finalizationData.lastFinalizedL1RollingHashMessageNumber, - _finalizationData.lastFinalizedL1RollingHash, - _finalizationData.lastFinalizedTimestamp - ) != currentFinalizedState - ) { - revert FinalizationStateIncorrect( - _computeLastFinalizedState( - _finalizationData.lastFinalizedL1RollingHashMessageNumber, - _finalizationData.lastFinalizedL1RollingHash, - _finalizationData.lastFinalizedTimestamp - ), - currentFinalizedState - ); - } - - if (_finalizationData.finalTimestamp >= block.timestamp) { - revert FinalizationInTheFuture(_finalizationData.finalTimestamp, block.timestamp); - } - - if (_finalizationData.shnarfData.finalStateRootHash == EMPTY_HASH) { - revert FinalBlockStateEqualsZeroHash(); - } - - finalShnarf = _computeShnarf( - _finalizationData.shnarfData.parentShnarf, - _finalizationData.shnarfData.snarkHash, - _finalizationData.shnarfData.finalStateRootHash, - _finalizationData.shnarfData.dataEvaluationPoint, - _finalizationData.shnarfData.dataEvaluationClaim - ); - - if (shnarfFinalBlockNumbers[finalShnarf] != _finalizationData.finalBlockInData) { - revert FinalBlockDoesNotMatchShnarfFinalBlock( - _finalizationData.finalBlockInData, - shnarfFinalBlockNumbers[finalShnarf] - ); - } - - _addL2MerkleRoots(_finalizationData.l2MerkleRoots, _finalizationData.l2MerkleTreesDepth); - _anchorL2MessagingBlocks(_finalizationData.l2MessagingBlocksOffsets, _lastFinalizedBlock); - - stateRootHashes[_finalizationData.finalBlockInData] = _finalizationData.shnarfData.finalStateRootHash; - - currentL2BlockNumber = _finalizationData.finalBlockInData; - - currentFinalizedShnarf = finalShnarf; - - currentFinalizedState = _computeLastFinalizedState( - _finalizationData.l1RollingHashMessageNumber, - _finalizationData.l1RollingHash, - _finalizationData.finalTimestamp - ); - - emit DataFinalized( - _finalizationData.finalBlockInData, - _finalizationData.parentStateRootHash, - _finalizationData.shnarfData.finalStateRootHash, - _withProof - ); - } - - /** - * @notice Internal function to validate l1 rolling hash. - * @param _rollingHashMessageNumber Message number associated with the rolling hash as computed on L2. - * @param _rollingHash L1 rolling hash as computed on L2. - */ - function _validateL2ComputedRollingHash(uint256 _rollingHashMessageNumber, bytes32 _rollingHash) internal view { - if (_rollingHashMessageNumber == 0) { - if (_rollingHash != EMPTY_HASH) { - revert MissingMessageNumberForRollingHash(_rollingHash); - } - } else { - if (_rollingHash == EMPTY_HASH) { - revert MissingRollingHashForMessageNumber(_rollingHashMessageNumber); - } - if (rollingHashes[_rollingHashMessageNumber] != _rollingHash) { - revert L1RollingHashDoesNotExistOnL1(_rollingHashMessageNumber, _rollingHash); - } - } - } - - /** - * @notice Internal function to calculate Y for public input generation. - * @param _data Compressed data from submission data. - * @param _dataEvaluationPoint The data evaluation point. - * @dev Each chunk of 32 bytes must start with a 0 byte. - * @dev The dataEvaluationPoint value is modulo-ed down during the computation and scalar field checking is not needed. - * @dev There is a hard constraint in the circuit to enforce the polynomial degree limit (4096), which will also be enforced with EIP-4844. - * @return compressedDataComputedY The Y calculated value using the Horner method. - */ - function _calculateY( - bytes calldata _data, - bytes32 _dataEvaluationPoint - ) internal pure returns (bytes32 compressedDataComputedY) { - if (_data.length % 0x20 != 0) { - revert BytesLengthNotMultipleOf32(); - } - - bytes4 errorSelector = ILineaRollupV5.FirstByteIsNotZero.selector; - assembly { - for { - let i := _data.length - } gt(i, 0) { - - } { - i := sub(i, 0x20) - let chunk := calldataload(add(_data.offset, i)) - if iszero(iszero(and(chunk, 0xFF00000000000000000000000000000000000000000000000000000000000000))) { - let ptr := mload(0x40) - mstore(ptr, errorSelector) - revert(ptr, 0x4) - } - compressedDataComputedY := addmod( - mulmod(compressedDataComputedY, _dataEvaluationPoint, BLS_CURVE_MODULUS), - chunk, - BLS_CURVE_MODULUS - ) - } - } - } - - /** - * @notice Compute the public input. - * @dev Using assembly this way is cheaper gas wise. - * @dev NB: the dynamic sized fields are placed last in _finalizationData on purpose to optimise hashing ranges. - * @dev Computing the public input as the following: - * keccak256( - * abi.encode( - * _lastFinalizedShnarf, - * _finalShnarf, - * _finalizationData.lastFinalizedTimestamp, - * _finalizationData.finalTimestamp, - * _lastFinalizedBlockNumber, - * _finalizationData.finalBlockInData, - * _finalizationData.lastFinalizedL1RollingHash, - * _finalizationData.l1RollingHash, - * _finalizationData.lastFinalizedL1RollingHashMessageNumber, - * _finalizationData.l1RollingHashMessageNumber, - * _finalizationData.l2MerkleTreesDepth, - * keccak256( - * abi.encodePacked(_finalizationData.l2MerkleRoots) - * ) - * ) - * ) - * Data is found at the following offsets: - * 0x00 parentStateRootHash - * 0x20 lastFinalizedShnarf - * 0x40 finalBlockInData - * 0x60 shnarfData.parentShnarf - * 0x80 shnarfData.snarkHash - * 0xa0 shnarfData.finalStateRootHash - * 0xc0 shnarfData.dataEvaluationPoint - * 0xe0 shnarfData.dataEvaluationClaim - * 0x100 lastFinalizedTimestamp - * 0x120 finalTimestamp - * 0x140 lastFinalizedL1RollingHash - * 0x160 l1RollingHash - * 0x180 lastFinalizedL1RollingHashMessageNumber - * 0x1a0 l1RollingHashMessageNumber - * 0x1c0 l2MerkleTreesDepth - * 0x1e0 l2MerkleRootsLengthLocation - * 0x200 l2MessagingBlocksOffsetsLengthLocation - * 0x220 l2MerkleRootsLength - * 0x240 l2MerkleRoots - * Dynamic l2MessagingBlocksOffsetsLength (location depends on where l2MerkleRoots ends) - * Dynamic l2MessagingBlocksOffsets (location depends on where l2MerkleRoots ends) - * @param _finalizationData The full finalization data. - * @param _lastFinalizedShnarf The last finalized shnarf. - * @param _finalShnarf The final shnarf in the finalization. - * @param _lastFinalizedBlockNumber The last finalized block number. - */ - function _computePublicInput( - FinalizationDataV2 calldata _finalizationData, - bytes32 _lastFinalizedShnarf, - bytes32 _finalShnarf, - uint256 _lastFinalizedBlockNumber - ) private pure returns (uint256 publicInput) { - assembly { - let mPtr := mload(0x40) - mstore(mPtr, _lastFinalizedShnarf) - mstore(add(mPtr, 0x20), _finalShnarf) - - /** - * _finalizationData.lastFinalizedTimestamp - * _finalizationData.finalTimestamp - */ - calldatacopy(add(mPtr, 0x40), add(_finalizationData, 0x100), 0x40) - - mstore(add(mPtr, 0x80), _lastFinalizedBlockNumber) - - // _finalizationData.finalBlockInData - calldatacopy(add(mPtr, 0xA0), add(_finalizationData, 0x40), 0x20) - - /** - * _finalizationData.lastFinalizedL1RollingHash - * _finalizationData.l1RollingHash - * _finalizationData.lastFinalizedL1RollingHashMessageNumber - * _finalizationData.l1RollingHashMessageNumber - * _finalizationData.l2MerkleTreesDepth - */ - calldatacopy(add(mPtr, 0xC0), add(_finalizationData, 0x140), 0xA0) - - /** - * @dev Note the following in hashing the _finalizationData.l2MerkleRoots array: - * The second memory pointer and free pointer are offset by 0x20 to temporarily hash the array outside the scope of working memory, - * as we need the space left for the array hash to be stored at 0x160. - */ - let mPtrMerkleRoot := add(mPtr, 0x180) - let merkleRootsLen := calldataload(add(_finalizationData, 0x220)) - calldatacopy(mPtrMerkleRoot, add(_finalizationData, 0x240), mul(merkleRootsLen, 0x20)) - let l2MerkleRootsHash := keccak256(mPtrMerkleRoot, mul(merkleRootsLen, 0x20)) - mstore(add(mPtr, 0x160), l2MerkleRootsHash) - - publicInput := mod(keccak256(mPtr, 0x180), MODULO_R) - } - } -} diff --git a/contracts/src/_testing/unit/rollup/TestLineaRollupV5.sol b/contracts/src/_testing/unit/rollup/TestLineaRollupV5.sol deleted file mode 100644 index 6388810b..00000000 --- a/contracts/src/_testing/unit/rollup/TestLineaRollupV5.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.24; - -import { LineaRollupV5 } from "../../integration/LineaRollupV5.sol"; - -contract TestLineaRollupV5 is LineaRollupV5 { - function setDefaultShnarfExistValue(bytes32 _shnarf) external { - shnarfFinalBlockNumbers[_shnarf] = 1; - } - - function setRollingHash(uint256 _messageNumber, bytes32 _rollingHash) external { - rollingHashes[_messageNumber] = _rollingHash; - } -} diff --git a/contracts/src/_testing/unit/verifiers/TestPlonkVerifierForDataAggregation.sol b/contracts/src/_testing/unit/verifiers/TestPlonkVerifierForDataAggregation.sol index 6619555d..586ebc21 100644 --- a/contracts/src/_testing/unit/verifiers/TestPlonkVerifierForDataAggregation.sol +++ b/contracts/src/_testing/unit/verifiers/TestPlonkVerifierForDataAggregation.sol @@ -19,28 +19,29 @@ pragma solidity 0.8.26; contract TestPlonkVerifierForDataAggregation { - uint256 private constant R_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - uint256 private constant R_MOD_MINUS_ONE = 21888242871839275222246405745257275088548364400416034343698204186575808495616; + uint256 private constant R_MOD_MINUS_ONE = + 21888242871839275222246405745257275088548364400416034343698204186575808495616; uint256 private constant P_MOD = 21888242871839275222246405745257275088696311157297823662689037894645226208583; - + uint256 private constant G2_SRS_0_X_0 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 private constant G2_SRS_0_X_1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 private constant G2_SRS_0_Y_0 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 private constant G2_SRS_0_Y_1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; - + uint256 private constant G2_SRS_1_X_0 = 15805639136721018565402881920352193254830339253282065586954346329754995870280; uint256 private constant G2_SRS_1_X_1 = 19089565590083334368588890253123139704298730990782503769911324779715431555531; uint256 private constant G2_SRS_1_Y_0 = 9779648407879205346559610309258181044130619080926897934572699915909528404984; uint256 private constant G2_SRS_1_Y_1 = 6779728121489434657638426458390319301070371227460768374343986326751507916979; - + uint256 private constant G1_SRS_X = 14312776538779914388377568895031746459131577658076416373430523308756343304251; uint256 private constant G1_SRS_Y = 11763105256161367503191792604679297387056316997144156930871823008787082098465; // ----------------------- vk --------------------- uint256 private constant VK_NB_PUBLIC_INPUTS = 1; uint256 private constant VK_DOMAIN_SIZE = 16; - uint256 private constant VK_INV_DOMAIN_SIZE = 20520227692349320520856005386178695395514091625390032197217066424914820464641; + uint256 private constant VK_INV_DOMAIN_SIZE = + 20520227692349320520856005386178695395514091625390032197217066424914820464641; uint256 private constant VK_OMEGA = 14940766826517323942636479241147756311199852622225275649687664389641784935947; uint256 private constant VK_QL_COM_X = 3767637989833674092151354229632559107224950590673664856842061399469467338879; uint256 private constant VK_QL_COM_Y = 18545409996679466114224178746162553880737296402729089689774308937082946761979; @@ -52,23 +53,21 @@ contract TestPlonkVerifierForDataAggregation { uint256 private constant VK_QO_COM_Y = 10782414695040549646706468913781794882209258381887890407509684555513355143197; uint256 private constant VK_QK_COM_X = 309591480144351325314158474719361148480191595146291661238142838254651436989; uint256 private constant VK_QK_COM_Y = 12063173869829536468830946547606069911666129778788708678515573607390482939756; - + uint256 private constant VK_S1_COM_X = 12287072751694848944507699577006619791724925439540371477056092891137357229312; uint256 private constant VK_S1_COM_Y = 2469356406782415219782253630635766217009619642857495098799013714324696399305; - + uint256 private constant VK_S2_COM_X = 17261757720471042341269061128759148572672168808566386603388432325173708264418; uint256 private constant VK_S2_COM_Y = 20976565876611279190744172824963243461988367679364518747954008723085439460611; - + uint256 private constant VK_S3_COM_X = 18758025488249277181117376239193628449359868741625564388668468130204669284937; uint256 private constant VK_S3_COM_Y = 15566903578741238761792344329051427316196307361197991677131114502821508927172; - + uint256 private constant VK_COSET_SHIFT = 5; - - + uint256 private constant VK_QCP_0_X = 4559262075452024065272338216146989708834054079507534161096300708463935456394; uint256 private constant VK_QCP_0_Y = 1898950104727986554890445533779776634695458253078091580309593009754027486622; - - + uint256 private constant VK_INDEX_COMMIT_API_0 = 5; uint256 private constant VK_NB_CUSTOM_GATES = 1; @@ -78,7 +77,7 @@ contract TestPlonkVerifierForDataAggregation { uint256 private constant FIXED_PROOF_SIZE = 0x300; // offset proof - + uint256 private constant PROOF_L_COM_X = 0x0; uint256 private constant PROOF_L_COM_Y = 0x20; uint256 private constant PROOF_R_COM_X = 0x40; @@ -122,7 +121,7 @@ contract TestPlonkVerifierForDataAggregation { // -------- offset state // challenges to check the claimed quotient - + uint256 private constant STATE_ALPHA = 0x0; uint256 private constant STATE_BETA = 0x20; uint256 private constant STATE_GAMMA = 0x40; @@ -153,15 +152,13 @@ contract TestPlonkVerifierForDataAggregation { // -------- errors uint256 private constant ERROR_STRING_ID = 0x08c379a000000000000000000000000000000000000000000000000000000000; // selector for function Error(string) - // -------- utils (for hash_fr) - uint256 private constant HASH_FR_BB = 340282366920938463463374607431768211456; // 2**128 - uint256 private constant HASH_FR_ZERO_UINT256 = 0; - uint8 private constant HASH_FR_LEN_IN_BYTES = 48; - uint8 private constant HASH_FR_SIZE_DOMAIN = 11; - uint8 private constant HASH_FR_ONE = 1; - uint8 private constant HASH_FR_TWO = 2; - + uint256 private constant HASH_FR_BB = 340282366920938463463374607431768211456; // 2**128 + uint256 private constant HASH_FR_ZERO_UINT256 = 0; + uint8 private constant HASH_FR_LEN_IN_BYTES = 48; + uint8 private constant HASH_FR_SIZE_DOMAIN = 11; + uint8 private constant HASH_FR_ONE = 1; + uint8 private constant HASH_FR_TWO = 2; // -------- precompiles uint8 private constant SHA2 = 0x2; @@ -169,17 +166,14 @@ contract TestPlonkVerifierForDataAggregation { uint8 private constant EC_ADD = 0x6; uint8 private constant EC_MUL = 0x7; uint8 private constant EC_PAIR = 0x8; - + /// Verify a Plonk proof. /// Reverts if the proof or the public inputs are malformed. /// @param proof serialised plonk proof (using gnark's MarshalSolidity) /// @param public_inputs (must be reduced) /// @return success true if the proof passes false otherwise - function Verify(bytes calldata proof, uint256[] calldata public_inputs) - public view returns(bool success) { - + function Verify(bytes calldata proof, uint256[] calldata public_inputs) public view returns (bool success) { assembly { - let mem := mload(0x40) let freeMem := add(mem, STATE_LAST_MEM) @@ -311,20 +305,23 @@ contract TestPlonkVerifierForDataAggregation { // end errors ------------------------------------------------- // Beginning checks ------------------------------------------------- - + /// @param s actual number of public inputs function check_number_of_public_inputs(s) { if iszero(eq(s, VK_NB_PUBLIC_INPUTS)) { error_nb_public_inputs() } } - + /// Checks that the public inputs are < R_MOD. /// @param s number of public inputs /// @param p pointer to the public inputs array function check_inputs_size(s, p) { - for {let i} lt(i, s) {i:=add(i,1)} - { + for { + let i + } lt(i, s) { + i := add(i, 1) + } { if gt(calldataload(p), R_MOD_MINUS_ONE) { error_inputs_size() } @@ -335,17 +332,16 @@ contract TestPlonkVerifierForDataAggregation { /// Checks if the proof is of the correct size /// @param actual_proof_size size of the proof (not the expected size) function check_proof_size(actual_proof_size) { - let expected_proof_size := add(FIXED_PROOF_SIZE, mul(VK_NB_CUSTOM_GATES,0x60)) + let expected_proof_size := add(FIXED_PROOF_SIZE, mul(VK_NB_CUSTOM_GATES, 0x60)) if iszero(eq(actual_proof_size, expected_proof_size)) { - error_proof_size() + error_proof_size() } } - + /// Checks if the multiple openings of the polynomials are < R_MOD. /// @param aproof pointer to the beginning of the proof /// @dev the 'a' prepending proof is to have a local name function check_proof_openings_size(aproof) { - // PROOF_L_AT_ZETA let p := add(aproof, PROOF_L_AT_ZETA) if gt(calldataload(p), R_MOD_MINUS_ONE) { @@ -369,7 +365,7 @@ contract TestPlonkVerifierForDataAggregation { if gt(calldataload(p), R_MOD_MINUS_ONE) { error_proof_openings_size() } - + // PROOF_S2_AT_ZETA p := add(aproof, PROOF_S2_AT_ZETA) if gt(calldataload(p), R_MOD_MINUS_ONE) { @@ -383,16 +379,18 @@ contract TestPlonkVerifierForDataAggregation { } // PROOF_OPENING_QCP_AT_ZETA - + p := add(aproof, PROOF_OPENING_QCP_AT_ZETA) - for {let i:=0} lt(i, VK_NB_CUSTOM_GATES) {i:=add(i,1)} - { + for { + let i := 0 + } lt(i, VK_NB_CUSTOM_GATES) { + i := add(i, 1) + } { if gt(calldataload(p), R_MOD_MINUS_ONE) { error_proof_openings_size() } p := add(p, 0x20) } - } // end checks ------------------------------------------------- @@ -414,34 +412,32 @@ contract TestPlonkVerifierForDataAggregation { /// and is encoded as a uint256 number n. In basis b = 256, the number looks like this /// [0 0 0 .. 0x67 0x61 0x6d, 0x6d, 0x61]. The first non zero entry is at position 27=0x1b /// Gamma reduced (the actual challenge) is stored at add(state, state_gamma) - function derive_gamma(aproof, nb_pi, pi)->gamma_not_reduced { - + function derive_gamma(aproof, nb_pi, pi) -> gamma_not_reduced { let state := mload(0x40) let mPtr := add(state, STATE_LAST_MEM) mstore(mPtr, FS_GAMMA) // "gamma" - - mstore(add(mPtr, 0x20), VK_S1_COM_X) - mstore(add(mPtr, 0x40), VK_S1_COM_Y) - mstore(add(mPtr, 0x60), VK_S2_COM_X) - mstore(add(mPtr, 0x80), VK_S2_COM_Y) - mstore(add(mPtr, 0xa0), VK_S3_COM_X) - mstore(add(mPtr, 0xc0), VK_S3_COM_Y) - mstore(add(mPtr, 0xe0), VK_QL_COM_X) - mstore(add(mPtr, 0x100), VK_QL_COM_Y) - mstore(add(mPtr, 0x120), VK_QR_COM_X) - mstore(add(mPtr, 0x140), VK_QR_COM_Y) - mstore(add(mPtr, 0x160), VK_QM_COM_X) - mstore(add(mPtr, 0x180), VK_QM_COM_Y) - mstore(add(mPtr, 0x1a0), VK_QO_COM_X) - mstore(add(mPtr, 0x1c0), VK_QO_COM_Y) - mstore(add(mPtr, 0x1e0), VK_QK_COM_X) - mstore(add(mPtr, 0x200), VK_QK_COM_Y) - - mstore(add(mPtr, 0x220), VK_QCP_0_X) - mstore(add(mPtr, 0x240), VK_QCP_0_Y) - + mstore(add(mPtr, 0x20), VK_S1_COM_X) + mstore(add(mPtr, 0x40), VK_S1_COM_Y) + mstore(add(mPtr, 0x60), VK_S2_COM_X) + mstore(add(mPtr, 0x80), VK_S2_COM_Y) + mstore(add(mPtr, 0xa0), VK_S3_COM_X) + mstore(add(mPtr, 0xc0), VK_S3_COM_Y) + mstore(add(mPtr, 0xe0), VK_QL_COM_X) + mstore(add(mPtr, 0x100), VK_QL_COM_Y) + mstore(add(mPtr, 0x120), VK_QR_COM_X) + mstore(add(mPtr, 0x140), VK_QR_COM_Y) + mstore(add(mPtr, 0x160), VK_QM_COM_X) + mstore(add(mPtr, 0x180), VK_QM_COM_Y) + mstore(add(mPtr, 0x1a0), VK_QO_COM_X) + mstore(add(mPtr, 0x1c0), VK_QO_COM_Y) + mstore(add(mPtr, 0x1e0), VK_QK_COM_X) + mstore(add(mPtr, 0x200), VK_QK_COM_Y) + + mstore(add(mPtr, 0x220), VK_QCP_0_X) + mstore(add(mPtr, 0x240), VK_QCP_0_Y) + // public inputs let _mPtr := add(mPtr, 0x260) let size_pi_in_bytes := mul(nb_pi, 0x20) @@ -458,7 +454,7 @@ contract TestPlonkVerifierForDataAggregation { // + nb_public_inputs*0x20 // + nb_custom gates*0x40 let size := add(0x2c5, size_pi_in_bytes) - + size := add(size, mul(VK_NB_CUSTOM_GATES, 0x40)) let l_success := staticcall(gas(), SHA2, add(mPtr, 0x1b), size, mPtr, 0x20) //0x1b -> 000.."gamma" if iszero(l_success) { @@ -473,8 +469,7 @@ contract TestPlonkVerifierForDataAggregation { /// @return beta_not_reduced the next challenge, beta, not reduced /// @notice the transcript consists of the previous challenge only. /// The reduced version of beta is stored at add(state, state_beta) - function derive_beta(gamma_not_reduced)->beta_not_reduced{ - + function derive_beta(gamma_not_reduced) -> beta_not_reduced { let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) @@ -495,9 +490,8 @@ contract TestPlonkVerifierForDataAggregation { /// @return alpha_not_reduced the next challenge, alpha, not reduced /// @notice the transcript consists of the previous challenge (beta) /// not reduced, the commitments to the wires associated to the QCP_i, - /// and the commitment to the grand product polynomial - function derive_alpha(aproof, beta_not_reduced)->alpha_not_reduced { - + /// and the commitment to the grand product polynomial + function derive_alpha(aproof, beta_not_reduced) -> alpha_not_reduced { let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) let full_size := 0x65 // size("alpha") + 0x20 (previous challenge) @@ -507,14 +501,14 @@ contract TestPlonkVerifierForDataAggregation { let _mPtr := add(mPtr, 0x20) mstore(_mPtr, beta_not_reduced) _mPtr := add(_mPtr, 0x20) - + // Bsb22Commitments let proof_bsb_commitments := add(aproof, PROOF_BSB_COMMITMENTS) let size_bsb_commitments := mul(0x40, VK_NB_CUSTOM_GATES) calldatacopy(_mPtr, proof_bsb_commitments, size_bsb_commitments) _mPtr := add(_mPtr, size_bsb_commitments) full_size := add(full_size, size_bsb_commitments) - + // [Z], the commitment to the grand product polynomial calldatacopy(_mPtr, add(aproof, PROOF_GRAND_PRODUCT_COMMITMENT_X), 0x40) let l_success := staticcall(gas(), SHA2, add(mPtr, 0x1b), full_size, mPtr, 0x20) @@ -532,7 +526,6 @@ contract TestPlonkVerifierForDataAggregation { /// The transcript consists of the previous challenge and the commitment to /// the quotient polynomial h. function derive_zeta(aproof, alpha_not_reduced) { - let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) @@ -557,8 +550,7 @@ contract TestPlonkVerifierForDataAggregation { /// @param n number of public inputs /// @param mPtr free memory /// @return pi_wo_commit public inputs contribution (except the public inputs coming from the custom gate) - function sum_pi_wo_api_commit(ins, n, mPtr)->pi_wo_commit { - + function sum_pi_wo_api_commit(ins, n, mPtr) -> pi_wo_commit { let state := mload(0x40) let z := mload(add(state, STATE_ZETA)) let zpnmo := mload(add(state, STATE_ZETA_POWER_N_MINUS_ONE)) @@ -567,14 +559,16 @@ contract TestPlonkVerifierForDataAggregation { batch_compute_lagranges_at_z(z, zpnmo, n, li) let tmp := 0 - for {let i:=0} lt(i,n) {i:=add(i,1)} - { + for { + let i := 0 + } lt(i, n) { + i := add(i, 1) + } { tmp := mulmod(mload(li), calldataload(ins), R_MOD) pi_wo_commit := addmod(pi_wo_commit, tmp, R_MOD) li := add(li, 0x20) ins := add(ins, 0x20) } - } /// batch_compute_lagranges_at_z computes [L_0(z), .., L_{n-1}(z)] @@ -583,27 +577,32 @@ contract TestPlonkVerifierForDataAggregation { /// @param n_pub number of public inputs (number of Lagranges to compute) /// @param mPtr pointer to which the results are stored function batch_compute_lagranges_at_z(z, zpnmo, n_pub, mPtr) { - let zn := mulmod(zpnmo, VK_INV_DOMAIN_SIZE, R_MOD) // 1/n * (ζⁿ - 1) - + let _w := 1 let _mPtr := mPtr - for {let i:=0} lt(i,n_pub) {i:=add(i,1)} - { - mstore(_mPtr, addmod(z,sub(R_MOD, _w), R_MOD)) + for { + let i := 0 + } lt(i, n_pub) { + i := add(i, 1) + } { + mstore(_mPtr, addmod(z, sub(R_MOD, _w), R_MOD)) _w := mulmod(_w, VK_OMEGA, R_MOD) _mPtr := add(_mPtr, 0x20) } batch_invert(mPtr, n_pub, _mPtr) _mPtr := mPtr _w := 1 - for {let i:=0} lt(i,n_pub) {i:=add(i,1)} - { - mstore(_mPtr, mulmod(mulmod(mload(_mPtr), zn , R_MOD), _w, R_MOD)) + for { + let i := 0 + } lt(i, n_pub) { + i := add(i, 1) + } { + mstore(_mPtr, mulmod(mulmod(mload(_mPtr), zn, R_MOD), _w, R_MOD)) _mPtr := add(_mPtr, 0x20) _w := mulmod(_w, VK_OMEGA, R_MOD) } - } + } /// @notice Montgomery trick for batch inversion mod R_MOD /// @param ins pointer to the data to batch invert @@ -612,8 +611,11 @@ contract TestPlonkVerifierForDataAggregation { function batch_invert(ins, nb_ins, mPtr) { mstore(mPtr, 1) let offset := 0 - for {let i:=0} lt(i, nb_ins) {i:=add(i,1)} - { + for { + let i := 0 + } lt(i, nb_ins) { + i := add(i, 1) + } { let prev := mload(add(mPtr, offset)) let cur := mload(add(ins, offset)) cur := mulmod(prev, cur, R_MOD) @@ -622,9 +624,12 @@ contract TestPlonkVerifierForDataAggregation { } ins := add(ins, sub(offset, 0x20)) mPtr := add(mPtr, offset) - let inv := pow(mload(mPtr), sub(R_MOD,2), add(mPtr, 0x20)) - for {let i:=0} lt(i, nb_ins) {i:=add(i,1)} - { + let inv := pow(mload(mPtr), sub(R_MOD, 2), add(mPtr, 0x20)) + for { + let i := 0 + } lt(i, nb_ins) { + i := add(i, 1) + } { mPtr := sub(mPtr, 0x20) let tmp := mload(ins) let cur := mulmod(inv, mload(mPtr), R_MOD) @@ -634,14 +639,12 @@ contract TestPlonkVerifierForDataAggregation { } } - /// Public inputs (the ones coming from the custom gate) contribution /// @param aproof pointer to the proof /// @param nb_public_inputs number of public inputs /// @param mPtr pointer to free memory /// @return pi_commit custom gate public inputs contribution - function sum_pi_commit(aproof, nb_public_inputs, mPtr)->pi_commit { - + function sum_pi_commit(aproof, nb_public_inputs, mPtr) -> pi_commit { let state := mload(0x40) let z := mload(add(state, STATE_ZETA)) let zpnmo := mload(add(state, STATE_ZETA_POWER_N_MINUS_ONE)) @@ -649,14 +652,10 @@ contract TestPlonkVerifierForDataAggregation { let p := add(aproof, PROOF_BSB_COMMITMENTS) let h_fr, ith_lagrange - - + h_fr := hash_fr(calldataload(p), calldataload(add(p, 0x20)), mPtr) ith_lagrange := compute_ith_lagrange_at_z(z, zpnmo, add(nb_public_inputs, VK_INDEX_COMMIT_API_0), mPtr) pi_commit := addmod(pi_commit, mulmod(h_fr, ith_lagrange, R_MOD), R_MOD) - - - } /// Computes L_i(zeta) = ωⁱ/n * (ζⁿ-1)/(ζ-ωⁱ) where: @@ -664,16 +663,14 @@ contract TestPlonkVerifierForDataAggregation { /// @param zpmno ζⁿ-1 /// @param i i-th lagrange /// @param mPtr free memory - /// @return res = ωⁱ/n * (ζⁿ-1)/(ζ-ωⁱ) - function compute_ith_lagrange_at_z(z, zpnmo, i, mPtr)->res { - + /// @return res = ωⁱ/n * (ζⁿ-1)/(ζ-ωⁱ) + function compute_ith_lagrange_at_z(z, zpnmo, i, mPtr) -> res { let w := pow(VK_OMEGA, i, mPtr) // w**i i := addmod(z, sub(R_MOD, w), R_MOD) // z-w**i w := mulmod(w, VK_INV_DOMAIN_SIZE, R_MOD) // w**i/n - i := pow(i, sub(R_MOD,2), mPtr) // (z-w**i)**-1 + i := pow(i, sub(R_MOD, 2), mPtr) // (z-w**i)**-1 w := mulmod(w, i, R_MOD) // w**i/n*(z-w)**-1 res := mulmod(w, zpnmo, R_MOD) - } /// @dev https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 @@ -681,15 +678,14 @@ contract TestPlonkVerifierForDataAggregation { /// @param y y coordinate of a point on Bn254(𝔽_p) /// @param mPtr free memory /// @return res an element mod R_MOD - function hash_fr(x, y, mPtr)->res { - + function hash_fr(x, y, mPtr) -> res { // [0x00, .. , 0x00 || x, y, || 0, 48, 0, dst, HASH_FR_SIZE_DOMAIN] // <- 64 bytes -> <-64b -> <- 1 bytes each -> // [0x00, .., 0x00] 64 bytes of zero mstore(mPtr, HASH_FR_ZERO_UINT256) mstore(add(mPtr, 0x20), HASH_FR_ZERO_UINT256) - + // msg = x || y , both on 32 bytes mstore(add(mPtr, 0x40), x) mstore(add(mPtr, 0x60), y) @@ -725,7 +721,7 @@ contract TestPlonkVerifierForDataAggregation { // [b0 || one || dst || HASH_FR_SIZE_DOMAIN] // <-64bytes -> <- 1 byte each -> mstore8(add(mPtr, 0x20), HASH_FR_ONE) // 1 - + mstore8(add(mPtr, 0x21), 0x42) // dst mstore8(add(mPtr, 0x22), 0x53) mstore8(add(mPtr, 0x23), 0x42) @@ -777,9 +773,8 @@ contract TestPlonkVerifierForDataAggregation { res := mulmod(mload(mPtr), HASH_FR_BB, R_MOD) // <- res = 2**128 * mPtr[:32] let b1 := shr(128, mload(add(mPtr, 0x20))) // b1 <- [0, 0, .., 0 || b2[:16] ] res := addmod(res, b1, R_MOD) - } - + // END compute_pi ------------------------------------------------- /// @notice compute α² * 1/n * (ζ{n}-1)/(ζ - 1) where @@ -787,7 +782,7 @@ contract TestPlonkVerifierForDataAggregation { /// * n = vk_domain_size /// * ω = vk_omega (generator of the multiplicative cyclic group of order n in (ℤ/rℤ)*) /// * ζ = zeta (challenge derived with Fiat Shamir) - function compute_alpha_square_lagrange_0() { + function compute_alpha_square_lagrange_0() { let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) @@ -827,7 +822,7 @@ contract TestPlonkVerifierForDataAggregation { mstore(add(mPtr, 0x100), mload(add(state, STATE_ZETA))) mstore(add(mPtr, 0x120), mload(add(state, STATE_GAMMA_KZG))) let random := staticcall(gas(), SHA2, mPtr, 0x140, mPtr, 0x20) - if iszero(random){ + if iszero(random) { error_random_generation() } random := mod(mload(mPtr), R_MOD) // use the same variable as we are one variable away from getting stack-too-deep error... @@ -876,18 +871,18 @@ contract TestPlonkVerifierForDataAggregation { mstore(folded_quotients_y, sub(P_MOD, mload(folded_quotients_y))) mstore(mPtr, mload(folded_digests)) - - mstore(add(mPtr, 0x20), mload(add(folded_digests, 0x20))) - mstore(add(mPtr, 0x40), G2_SRS_0_X_0) // the 4 lines are the canonical G2 point on BN254 - mstore(add(mPtr, 0x60), G2_SRS_0_X_1) - mstore(add(mPtr, 0x80), G2_SRS_0_Y_0) - mstore(add(mPtr, 0xa0), G2_SRS_0_Y_1) - mstore(add(mPtr, 0xc0), mload(folded_quotients)) - mstore(add(mPtr, 0xe0), mload(add(folded_quotients, 0x20))) - mstore(add(mPtr, 0x100), G2_SRS_1_X_0) - mstore(add(mPtr, 0x120), G2_SRS_1_X_1) - mstore(add(mPtr, 0x140), G2_SRS_1_Y_0) - mstore(add(mPtr, 0x160), G2_SRS_1_Y_1) + + mstore(add(mPtr, 0x20), mload(add(folded_digests, 0x20))) + mstore(add(mPtr, 0x40), G2_SRS_0_X_0) // the 4 lines are the canonical G2 point on BN254 + mstore(add(mPtr, 0x60), G2_SRS_0_X_1) + mstore(add(mPtr, 0x80), G2_SRS_0_Y_0) + mstore(add(mPtr, 0xa0), G2_SRS_0_Y_1) + mstore(add(mPtr, 0xc0), mload(folded_quotients)) + mstore(add(mPtr, 0xe0), mload(add(folded_quotients, 0x20))) + mstore(add(mPtr, 0x100), G2_SRS_1_X_0) + mstore(add(mPtr, 0x120), G2_SRS_1_X_1) + mstore(add(mPtr, 0x140), G2_SRS_1_Y_0) + mstore(add(mPtr, 0x160), G2_SRS_1_Y_1) check_pairing_kzg(mPtr) } @@ -912,7 +907,6 @@ contract TestPlonkVerifierForDataAggregation { /// @param aproof pointer to the proof /// acc_gamma stores the γⁱ function fold_state(aproof) { - let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) let mPtr20 := add(mPtr, 0x20) @@ -949,15 +943,14 @@ contract TestPlonkVerifierForDataAggregation { point_acc_mul(state_folded_digests, mPtr, acc_gamma, mPtr40) fr_acc_mul_calldata(add(state, STATE_FOLDED_CLAIMED_VALUES), add(aproof, PROOF_S2_AT_ZETA), acc_gamma) let poqaz := add(aproof, PROOF_OPENING_QCP_AT_ZETA) - + acc_gamma := mulmod(acc_gamma, l_gamma_kzg, R_MOD) mstore(mPtr, VK_QCP_0_X) mstore(mPtr20, VK_QCP_0_Y) point_acc_mul(state_folded_digests, mPtr, acc_gamma, mPtr40) fr_acc_mul_calldata(add(state, STATE_FOLDED_CLAIMED_VALUES), poqaz, acc_gamma) poqaz := add(poqaz, 0x20) - - } + } /// @notice generate the challenge (using Fiat Shamir) to fold the opening proofs /// at ζ. @@ -975,23 +968,22 @@ contract TestPlonkVerifierForDataAggregation { /// * Z(ζω) /// @param aproof pointer to the proof function compute_gamma_kzg(aproof) { - let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) mstore(mPtr, FS_GAMMA_KZG) // "gamma" mstore(add(mPtr, 0x20), mload(add(state, STATE_ZETA))) - mstore(add(mPtr,0x40), mload(add(state, STATE_LINEARISED_POLYNOMIAL_X))) - mstore(add(mPtr,0x60), mload(add(state, STATE_LINEARISED_POLYNOMIAL_Y))) + mstore(add(mPtr, 0x40), mload(add(state, STATE_LINEARISED_POLYNOMIAL_X))) + mstore(add(mPtr, 0x60), mload(add(state, STATE_LINEARISED_POLYNOMIAL_Y))) calldatacopy(add(mPtr, 0x80), add(aproof, PROOF_L_COM_X), 0xc0) - mstore(add(mPtr,0x140), VK_S1_COM_X) - mstore(add(mPtr,0x160), VK_S1_COM_Y) - mstore(add(mPtr,0x180), VK_S2_COM_X) - mstore(add(mPtr,0x1a0), VK_S2_COM_Y) - + mstore(add(mPtr, 0x140), VK_S1_COM_X) + mstore(add(mPtr, 0x160), VK_S1_COM_Y) + mstore(add(mPtr, 0x180), VK_S2_COM_X) + mstore(add(mPtr, 0x1a0), VK_S2_COM_Y) + let offset := 0x1c0 - - mstore(add(mPtr,offset), VK_QCP_0_X) - mstore(add(mPtr,add(offset, 0x20)), VK_QCP_0_Y) + + mstore(add(mPtr, offset), VK_QCP_0_X) + mstore(add(mPtr, add(offset, 0x20)), VK_QCP_0_Y) offset := add(offset, 0x40) mstore(add(mPtr, offset), mload(add(state, STATE_OPENING_LINEARISED_POLYNOMIAL_ZETA))) mstore(add(mPtr, add(offset, 0x20)), calldataload(add(aproof, PROOF_L_AT_ZETA))) @@ -1002,18 +994,23 @@ contract TestPlonkVerifierForDataAggregation { let _mPtr := add(mPtr, add(offset, 0xc0)) - let _poqaz := add(aproof, PROOF_OPENING_QCP_AT_ZETA) calldatacopy(_mPtr, _poqaz, mul(VK_NB_CUSTOM_GATES, 0x20)) _mPtr := add(_mPtr, mul(VK_NB_CUSTOM_GATES, 0x20)) - mstore(_mPtr, calldataload(add(aproof, PROOF_GRAND_PRODUCT_AT_ZETA_OMEGA))) let start_input := 0x1b // 00.."gamma" - let size_input := add(0x14, mul(VK_NB_CUSTOM_GATES,3)) // number of 32bytes elmts = 0x14 (zeta+3*6 for the digests+openings) + 3*VK_NB_CUSTOM_GATES (for the commitments of the selectors) + 1 (opening of Z at ζω) + let size_input := add(0x14, mul(VK_NB_CUSTOM_GATES, 3)) // number of 32bytes elmts = 0x14 (zeta+3*6 for the digests+openings) + 3*VK_NB_CUSTOM_GATES (for the commitments of the selectors) + 1 (opening of Z at ζω) size_input := add(0x5, mul(size_input, 0x20)) // size in bytes: 15*32 bytes + 5 bytes for gamma - let check_staticcall := staticcall(gas(), SHA2, add(mPtr,start_input), size_input, add(state, STATE_GAMMA_KZG), 0x20) + let check_staticcall := staticcall( + gas(), + SHA2, + add(mPtr, start_input), + size_input, + add(state, STATE_GAMMA_KZG), + 0x20 + ) if iszero(check_staticcall) { error_verify() } @@ -1021,7 +1018,6 @@ contract TestPlonkVerifierForDataAggregation { } function compute_commitment_linearised_polynomial_ec(aproof, s1, s2) { - let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) @@ -1066,7 +1062,6 @@ contract TestPlonkVerifierForDataAggregation { add(mPtr, 0x40) ) - let qcp_opening_at_zeta := add(aproof, PROOF_OPENING_QCP_AT_ZETA) let bsb_commitments := add(aproof, PROOF_BSB_COMMITMENTS) for { @@ -1085,7 +1080,6 @@ contract TestPlonkVerifierForDataAggregation { qcp_opening_at_zeta := add(qcp_opening_at_zeta, 0x20) bsb_commitments := add(bsb_commitments, 0x40) } - mstore(mPtr, VK_S3_COM_X) mstore(add(mPtr, 0x20), VK_S3_COM_Y) @@ -1096,10 +1090,11 @@ contract TestPlonkVerifierForDataAggregation { point_acc_mul(add(state, STATE_LINEARISED_POLYNOMIAL_X), mPtr, s2, add(mPtr, 0x40)) point_add( - add(state, STATE_LINEARISED_POLYNOMIAL_X), - add(state, STATE_LINEARISED_POLYNOMIAL_X), - add(state, STATE_FOLDED_H_X), - mPtr) + add(state, STATE_LINEARISED_POLYNOMIAL_X), + add(state, STATE_LINEARISED_POLYNOMIAL_X), + add(state, STATE_FOLDED_H_X), + mPtr + ) } /// @notice Compute the commitment to the linearized polynomial equal to @@ -1166,10 +1161,25 @@ contract TestPlonkVerifierForDataAggregation { let mPtr := add(mload(0x40), STATE_LAST_MEM) let zeta_power_n_plus_two := pow(mload(add(state, STATE_ZETA)), n_plus_two, mPtr) point_mul_calldata(add(state, STATE_FOLDED_H_X), add(aproof, PROOF_H_2_COM_X), zeta_power_n_plus_two, mPtr) - point_add_calldata(add(state, STATE_FOLDED_H_X), add(state, STATE_FOLDED_H_X), add(aproof, PROOF_H_1_COM_X), mPtr) + point_add_calldata( + add(state, STATE_FOLDED_H_X), + add(state, STATE_FOLDED_H_X), + add(aproof, PROOF_H_1_COM_X), + mPtr + ) point_mul(add(state, STATE_FOLDED_H_X), add(state, STATE_FOLDED_H_X), zeta_power_n_plus_two, mPtr) - point_add_calldata(add(state, STATE_FOLDED_H_X), add(state, STATE_FOLDED_H_X), add(aproof, PROOF_H_0_COM_X), mPtr) - point_mul(add(state, STATE_FOLDED_H_X), add(state, STATE_FOLDED_H_X), mload(add(state, STATE_ZETA_POWER_N_MINUS_ONE)), mPtr) + point_add_calldata( + add(state, STATE_FOLDED_H_X), + add(state, STATE_FOLDED_H_X), + add(aproof, PROOF_H_0_COM_X), + mPtr + ) + point_mul( + add(state, STATE_FOLDED_H_X), + add(state, STATE_FOLDED_H_X), + mload(add(state, STATE_ZETA_POWER_N_MINUS_ONE)), + mPtr + ) let folded_h_y := mload(add(state, STATE_FOLDED_H_Y)) folded_h_y := sub(P_MOD, folded_h_y) mstore(add(state, STATE_FOLDED_H_Y), folded_h_y) @@ -1179,7 +1189,6 @@ contract TestPlonkVerifierForDataAggregation { /// - [ PI(ζ) - α²*L₁(ζ) + α(l(ζ)+β*s1(ζ)+γ)(r(ζ)+β*s2(ζ)+γ)(o(ζ)+γ)*z(ωζ) ] /// @param aproof pointer to the proof function compute_opening_linearised_polynomial(aproof) { - let state := mload(0x40) // (l(ζ)+β*s1(ζ)+γ) @@ -1215,7 +1224,7 @@ contract TestPlonkVerifierForDataAggregation { } // BEGINNING utils math functions ------------------------------------------------- - + /// @param dst pointer storing the result /// @param p pointer to the first point /// @param q pointer to the second point @@ -1225,7 +1234,7 @@ contract TestPlonkVerifierForDataAggregation { mstore(add(mPtr, 0x20), mload(add(p, 0x20))) mstore(add(mPtr, 0x40), mload(q)) mstore(add(mPtr, 0x60), mload(add(q, 0x20))) - let l_success := staticcall(gas(),EC_ADD,mPtr,0x80,dst,0x40) + let l_success := staticcall(gas(), EC_ADD, mPtr, 0x80, dst, 0x40) if iszero(l_success) { error_ec_op() } @@ -1250,11 +1259,11 @@ contract TestPlonkVerifierForDataAggregation { /// @param src pointer to a point on Bn254(𝔽_p) /// @param s scalar /// @param mPtr free memory - function point_mul(dst,src,s, mPtr) { - mstore(mPtr,mload(src)) - mstore(add(mPtr,0x20),mload(add(src,0x20))) - mstore(add(mPtr,0x40),s) - let l_success := staticcall(gas(),EC_MUL,mPtr,0x60,dst,0x40) + function point_mul(dst, src, s, mPtr) { + mstore(mPtr, mload(src)) + mstore(add(mPtr, 0x20), mload(add(src, 0x20))) + mstore(add(mPtr, 0x40), s) + let l_success := staticcall(gas(), EC_MUL, mPtr, 0x60, dst, 0x40) if iszero(l_success) { error_ec_op() } @@ -1279,14 +1288,14 @@ contract TestPlonkVerifierForDataAggregation { /// @param src pointer to the point to multiply and add /// @param s scalar /// @param mPtr free memory - function point_acc_mul(dst,src,s, mPtr) { - mstore(mPtr,mload(src)) - mstore(add(mPtr,0x20),mload(add(src,0x20))) - mstore(add(mPtr,0x40),s) - let l_success := staticcall(gas(),7,mPtr,0x60,mPtr,0x40) - mstore(add(mPtr,0x40),mload(dst)) - mstore(add(mPtr,0x60),mload(add(dst,0x20))) - l_success := and(l_success, staticcall(gas(),EC_ADD,mPtr,0x80,dst, 0x40)) + function point_acc_mul(dst, src, s, mPtr) { + mstore(mPtr, mload(src)) + mstore(add(mPtr, 0x20), mload(add(src, 0x20))) + mstore(add(mPtr, 0x40), s) + let l_success := staticcall(gas(), 7, mPtr, 0x60, mPtr, 0x40) + mstore(add(mPtr, 0x40), mload(dst)) + mstore(add(mPtr, 0x60), mload(add(dst, 0x20))) + l_success := and(l_success, staticcall(gas(), EC_ADD, mPtr, 0x80, dst, 0x40)) if iszero(l_success) { error_ec_op() } @@ -1315,7 +1324,7 @@ contract TestPlonkVerifierForDataAggregation { /// @param src pointer to the scalar to multiply and add (on calldata) /// @param s scalar function fr_acc_mul_calldata(dst, src, s) { - let tmp := mulmod(calldataload(src), s, R_MOD) + let tmp := mulmod(calldataload(src), s, R_MOD) mstore(dst, addmod(mload(dst), tmp, R_MOD)) } @@ -1323,16 +1332,16 @@ contract TestPlonkVerifierForDataAggregation { /// @param e exponent /// @param mPtr free memory /// @return res x ** e mod r - function pow(x, e, mPtr)->res { + function pow(x, e, mPtr) -> res { mstore(mPtr, 0x20) mstore(add(mPtr, 0x20), 0x20) mstore(add(mPtr, 0x40), 0x20) mstore(add(mPtr, 0x60), x) mstore(add(mPtr, 0x80), e) mstore(add(mPtr, 0xa0), R_MOD) - let check_staticcall := staticcall(gas(),MOD_EXP,mPtr,0xc0,mPtr,0x20) + let check_staticcall := staticcall(gas(), MOD_EXP, mPtr, 0xc0, mPtr, 0x20) if eq(check_staticcall, 0) { - error_mod_exp() + error_mod_exp() } res := mload(mPtr) } diff --git a/contracts/src/verifiers/PlonkVerifierForDataAggregation.sol b/contracts/src/verifiers/PlonkVerifierForDataAggregation.sol index b7bbee3b..8670ce2a 100644 --- a/contracts/src/verifiers/PlonkVerifierForDataAggregation.sol +++ b/contracts/src/verifiers/PlonkVerifierForDataAggregation.sol @@ -19,28 +19,29 @@ pragma solidity 0.8.26; contract PlonkVerifierForDataAggregation { - uint256 private constant R_MOD = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - uint256 private constant R_MOD_MINUS_ONE = 21888242871839275222246405745257275088548364400416034343698204186575808495616; + uint256 private constant R_MOD_MINUS_ONE = + 21888242871839275222246405745257275088548364400416034343698204186575808495616; uint256 private constant P_MOD = 21888242871839275222246405745257275088696311157297823662689037894645226208583; - + uint256 private constant G2_SRS_0_X_0 = 11559732032986387107991004021392285783925812861821192530917403151452391805634; uint256 private constant G2_SRS_0_X_1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781; uint256 private constant G2_SRS_0_Y_0 = 4082367875863433681332203403145435568316851327593401208105741076214120093531; uint256 private constant G2_SRS_0_Y_1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930; - + uint256 private constant G2_SRS_1_X_0 = 15805639136721018565402881920352193254830339253282065586954346329754995870280; uint256 private constant G2_SRS_1_X_1 = 19089565590083334368588890253123139704298730990782503769911324779715431555531; uint256 private constant G2_SRS_1_Y_0 = 9779648407879205346559610309258181044130619080926897934572699915909528404984; uint256 private constant G2_SRS_1_Y_1 = 6779728121489434657638426458390319301070371227460768374343986326751507916979; - + uint256 private constant G1_SRS_X = 14312776538779914388377568895031746459131577658076416373430523308756343304251; uint256 private constant G1_SRS_Y = 11763105256161367503191792604679297387056316997144156930871823008787082098465; // ----------------------- vk --------------------- uint256 private constant VK_NB_PUBLIC_INPUTS = 1; uint256 private constant VK_DOMAIN_SIZE = 16; - uint256 private constant VK_INV_DOMAIN_SIZE = 20520227692349320520856005386178695395514091625390032197217066424914820464641; + uint256 private constant VK_INV_DOMAIN_SIZE = + 20520227692349320520856005386178695395514091625390032197217066424914820464641; uint256 private constant VK_OMEGA = 14940766826517323942636479241147756311199852622225275649687664389641784935947; uint256 private constant VK_QL_COM_X = 3767637989833674092151354229632559107224950590673664856842061399469467338879; uint256 private constant VK_QL_COM_Y = 18545409996679466114224178746162553880737296402729089689774308937082946761979; @@ -52,23 +53,21 @@ contract PlonkVerifierForDataAggregation { uint256 private constant VK_QO_COM_Y = 10782414695040549646706468913781794882209258381887890407509684555513355143197; uint256 private constant VK_QK_COM_X = 309591480144351325314158474719361148480191595146291661238142838254651436989; uint256 private constant VK_QK_COM_Y = 12063173869829536468830946547606069911666129778788708678515573607390482939756; - + uint256 private constant VK_S1_COM_X = 12287072751694848944507699577006619791724925439540371477056092891137357229312; uint256 private constant VK_S1_COM_Y = 2469356406782415219782253630635766217009619642857495098799013714324696399305; - + uint256 private constant VK_S2_COM_X = 17261757720471042341269061128759148572672168808566386603388432325173708264418; uint256 private constant VK_S2_COM_Y = 20976565876611279190744172824963243461988367679364518747954008723085439460611; - + uint256 private constant VK_S3_COM_X = 18758025488249277181117376239193628449359868741625564388668468130204669284937; uint256 private constant VK_S3_COM_Y = 15566903578741238761792344329051427316196307361197991677131114502821508927172; - + uint256 private constant VK_COSET_SHIFT = 5; - - + uint256 private constant VK_QCP_0_X = 4559262075452024065272338216146989708834054079507534161096300708463935456394; uint256 private constant VK_QCP_0_Y = 1898950104727986554890445533779776634695458253078091580309593009754027486622; - - + uint256 private constant VK_INDEX_COMMIT_API_0 = 5; uint256 private constant VK_NB_CUSTOM_GATES = 1; @@ -78,7 +77,7 @@ contract PlonkVerifierForDataAggregation { uint256 private constant FIXED_PROOF_SIZE = 0x300; // offset proof - + uint256 private constant PROOF_L_COM_X = 0x0; uint256 private constant PROOF_L_COM_Y = 0x20; uint256 private constant PROOF_R_COM_X = 0x40; @@ -122,7 +121,7 @@ contract PlonkVerifierForDataAggregation { // -------- offset state // challenges to check the claimed quotient - + uint256 private constant STATE_ALPHA = 0x0; uint256 private constant STATE_BETA = 0x20; uint256 private constant STATE_GAMMA = 0x40; @@ -153,15 +152,13 @@ contract PlonkVerifierForDataAggregation { // -------- errors uint256 private constant ERROR_STRING_ID = 0x08c379a000000000000000000000000000000000000000000000000000000000; // selector for function Error(string) - // -------- utils (for hash_fr) - uint256 private constant HASH_FR_BB = 340282366920938463463374607431768211456; // 2**128 - uint256 private constant HASH_FR_ZERO_UINT256 = 0; - uint8 private constant HASH_FR_LEN_IN_BYTES = 48; - uint8 private constant HASH_FR_SIZE_DOMAIN = 11; - uint8 private constant HASH_FR_ONE = 1; - uint8 private constant HASH_FR_TWO = 2; - + uint256 private constant HASH_FR_BB = 340282366920938463463374607431768211456; // 2**128 + uint256 private constant HASH_FR_ZERO_UINT256 = 0; + uint8 private constant HASH_FR_LEN_IN_BYTES = 48; + uint8 private constant HASH_FR_SIZE_DOMAIN = 11; + uint8 private constant HASH_FR_ONE = 1; + uint8 private constant HASH_FR_TWO = 2; // -------- precompiles uint8 private constant SHA2 = 0x2; @@ -169,17 +166,14 @@ contract PlonkVerifierForDataAggregation { uint8 private constant EC_ADD = 0x6; uint8 private constant EC_MUL = 0x7; uint8 private constant EC_PAIR = 0x8; - + /// Verify a Plonk proof. /// Reverts if the proof or the public inputs are malformed. /// @param proof serialised plonk proof (using gnark's MarshalSolidity) /// @param public_inputs (must be reduced) /// @return success true if the proof passes false otherwise - function Verify(bytes calldata proof, uint256[] calldata public_inputs) - public view returns(bool success) { - + function Verify(bytes calldata proof, uint256[] calldata public_inputs) public view returns (bool success) { assembly { - let mem := mload(0x40) let freeMem := add(mem, STATE_LAST_MEM) @@ -311,20 +305,23 @@ contract PlonkVerifierForDataAggregation { // end errors ------------------------------------------------- // Beginning checks ------------------------------------------------- - + /// @param s actual number of public inputs function check_number_of_public_inputs(s) { if iszero(eq(s, VK_NB_PUBLIC_INPUTS)) { error_nb_public_inputs() } } - + /// Checks that the public inputs are < R_MOD. /// @param s number of public inputs /// @param p pointer to the public inputs array function check_inputs_size(s, p) { - for {let i} lt(i, s) {i:=add(i,1)} - { + for { + let i + } lt(i, s) { + i := add(i, 1) + } { if gt(calldataload(p), R_MOD_MINUS_ONE) { error_inputs_size() } @@ -335,17 +332,16 @@ contract PlonkVerifierForDataAggregation { /// Checks if the proof is of the correct size /// @param actual_proof_size size of the proof (not the expected size) function check_proof_size(actual_proof_size) { - let expected_proof_size := add(FIXED_PROOF_SIZE, mul(VK_NB_CUSTOM_GATES,0x60)) + let expected_proof_size := add(FIXED_PROOF_SIZE, mul(VK_NB_CUSTOM_GATES, 0x60)) if iszero(eq(actual_proof_size, expected_proof_size)) { - error_proof_size() + error_proof_size() } } - + /// Checks if the multiple openings of the polynomials are < R_MOD. /// @param aproof pointer to the beginning of the proof /// @dev the 'a' prepending proof is to have a local name function check_proof_openings_size(aproof) { - // PROOF_L_AT_ZETA let p := add(aproof, PROOF_L_AT_ZETA) if gt(calldataload(p), R_MOD_MINUS_ONE) { @@ -369,7 +365,7 @@ contract PlonkVerifierForDataAggregation { if gt(calldataload(p), R_MOD_MINUS_ONE) { error_proof_openings_size() } - + // PROOF_S2_AT_ZETA p := add(aproof, PROOF_S2_AT_ZETA) if gt(calldataload(p), R_MOD_MINUS_ONE) { @@ -383,16 +379,18 @@ contract PlonkVerifierForDataAggregation { } // PROOF_OPENING_QCP_AT_ZETA - + p := add(aproof, PROOF_OPENING_QCP_AT_ZETA) - for {let i:=0} lt(i, VK_NB_CUSTOM_GATES) {i:=add(i,1)} - { + for { + let i := 0 + } lt(i, VK_NB_CUSTOM_GATES) { + i := add(i, 1) + } { if gt(calldataload(p), R_MOD_MINUS_ONE) { error_proof_openings_size() } p := add(p, 0x20) } - } // end checks ------------------------------------------------- @@ -414,34 +412,32 @@ contract PlonkVerifierForDataAggregation { /// and is encoded as a uint256 number n. In basis b = 256, the number looks like this /// [0 0 0 .. 0x67 0x61 0x6d, 0x6d, 0x61]. The first non zero entry is at position 27=0x1b /// Gamma reduced (the actual challenge) is stored at add(state, state_gamma) - function derive_gamma(aproof, nb_pi, pi)->gamma_not_reduced { - + function derive_gamma(aproof, nb_pi, pi) -> gamma_not_reduced { let state := mload(0x40) let mPtr := add(state, STATE_LAST_MEM) mstore(mPtr, FS_GAMMA) // "gamma" - - mstore(add(mPtr, 0x20), VK_S1_COM_X) - mstore(add(mPtr, 0x40), VK_S1_COM_Y) - mstore(add(mPtr, 0x60), VK_S2_COM_X) - mstore(add(mPtr, 0x80), VK_S2_COM_Y) - mstore(add(mPtr, 0xa0), VK_S3_COM_X) - mstore(add(mPtr, 0xc0), VK_S3_COM_Y) - mstore(add(mPtr, 0xe0), VK_QL_COM_X) - mstore(add(mPtr, 0x100), VK_QL_COM_Y) - mstore(add(mPtr, 0x120), VK_QR_COM_X) - mstore(add(mPtr, 0x140), VK_QR_COM_Y) - mstore(add(mPtr, 0x160), VK_QM_COM_X) - mstore(add(mPtr, 0x180), VK_QM_COM_Y) - mstore(add(mPtr, 0x1a0), VK_QO_COM_X) - mstore(add(mPtr, 0x1c0), VK_QO_COM_Y) - mstore(add(mPtr, 0x1e0), VK_QK_COM_X) - mstore(add(mPtr, 0x200), VK_QK_COM_Y) - - mstore(add(mPtr, 0x220), VK_QCP_0_X) - mstore(add(mPtr, 0x240), VK_QCP_0_Y) - + mstore(add(mPtr, 0x20), VK_S1_COM_X) + mstore(add(mPtr, 0x40), VK_S1_COM_Y) + mstore(add(mPtr, 0x60), VK_S2_COM_X) + mstore(add(mPtr, 0x80), VK_S2_COM_Y) + mstore(add(mPtr, 0xa0), VK_S3_COM_X) + mstore(add(mPtr, 0xc0), VK_S3_COM_Y) + mstore(add(mPtr, 0xe0), VK_QL_COM_X) + mstore(add(mPtr, 0x100), VK_QL_COM_Y) + mstore(add(mPtr, 0x120), VK_QR_COM_X) + mstore(add(mPtr, 0x140), VK_QR_COM_Y) + mstore(add(mPtr, 0x160), VK_QM_COM_X) + mstore(add(mPtr, 0x180), VK_QM_COM_Y) + mstore(add(mPtr, 0x1a0), VK_QO_COM_X) + mstore(add(mPtr, 0x1c0), VK_QO_COM_Y) + mstore(add(mPtr, 0x1e0), VK_QK_COM_X) + mstore(add(mPtr, 0x200), VK_QK_COM_Y) + + mstore(add(mPtr, 0x220), VK_QCP_0_X) + mstore(add(mPtr, 0x240), VK_QCP_0_Y) + // public inputs let _mPtr := add(mPtr, 0x260) let size_pi_in_bytes := mul(nb_pi, 0x20) @@ -458,7 +454,7 @@ contract PlonkVerifierForDataAggregation { // + nb_public_inputs*0x20 // + nb_custom gates*0x40 let size := add(0x2c5, size_pi_in_bytes) - + size := add(size, mul(VK_NB_CUSTOM_GATES, 0x40)) let l_success := staticcall(gas(), SHA2, add(mPtr, 0x1b), size, mPtr, 0x20) //0x1b -> 000.."gamma" if iszero(l_success) { @@ -473,8 +469,7 @@ contract PlonkVerifierForDataAggregation { /// @return beta_not_reduced the next challenge, beta, not reduced /// @notice the transcript consists of the previous challenge only. /// The reduced version of beta is stored at add(state, state_beta) - function derive_beta(gamma_not_reduced)->beta_not_reduced{ - + function derive_beta(gamma_not_reduced) -> beta_not_reduced { let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) @@ -495,9 +490,8 @@ contract PlonkVerifierForDataAggregation { /// @return alpha_not_reduced the next challenge, alpha, not reduced /// @notice the transcript consists of the previous challenge (beta) /// not reduced, the commitments to the wires associated to the QCP_i, - /// and the commitment to the grand product polynomial - function derive_alpha(aproof, beta_not_reduced)->alpha_not_reduced { - + /// and the commitment to the grand product polynomial + function derive_alpha(aproof, beta_not_reduced) -> alpha_not_reduced { let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) let full_size := 0x65 // size("alpha") + 0x20 (previous challenge) @@ -507,14 +501,14 @@ contract PlonkVerifierForDataAggregation { let _mPtr := add(mPtr, 0x20) mstore(_mPtr, beta_not_reduced) _mPtr := add(_mPtr, 0x20) - + // Bsb22Commitments let proof_bsb_commitments := add(aproof, PROOF_BSB_COMMITMENTS) let size_bsb_commitments := mul(0x40, VK_NB_CUSTOM_GATES) calldatacopy(_mPtr, proof_bsb_commitments, size_bsb_commitments) _mPtr := add(_mPtr, size_bsb_commitments) full_size := add(full_size, size_bsb_commitments) - + // [Z], the commitment to the grand product polynomial calldatacopy(_mPtr, add(aproof, PROOF_GRAND_PRODUCT_COMMITMENT_X), 0x40) let l_success := staticcall(gas(), SHA2, add(mPtr, 0x1b), full_size, mPtr, 0x20) @@ -532,7 +526,6 @@ contract PlonkVerifierForDataAggregation { /// The transcript consists of the previous challenge and the commitment to /// the quotient polynomial h. function derive_zeta(aproof, alpha_not_reduced) { - let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) @@ -557,8 +550,7 @@ contract PlonkVerifierForDataAggregation { /// @param n number of public inputs /// @param mPtr free memory /// @return pi_wo_commit public inputs contribution (except the public inputs coming from the custom gate) - function sum_pi_wo_api_commit(ins, n, mPtr)->pi_wo_commit { - + function sum_pi_wo_api_commit(ins, n, mPtr) -> pi_wo_commit { let state := mload(0x40) let z := mload(add(state, STATE_ZETA)) let zpnmo := mload(add(state, STATE_ZETA_POWER_N_MINUS_ONE)) @@ -567,14 +559,16 @@ contract PlonkVerifierForDataAggregation { batch_compute_lagranges_at_z(z, zpnmo, n, li) let tmp := 0 - for {let i:=0} lt(i,n) {i:=add(i,1)} - { + for { + let i := 0 + } lt(i, n) { + i := add(i, 1) + } { tmp := mulmod(mload(li), calldataload(ins), R_MOD) pi_wo_commit := addmod(pi_wo_commit, tmp, R_MOD) li := add(li, 0x20) ins := add(ins, 0x20) } - } /// batch_compute_lagranges_at_z computes [L_0(z), .., L_{n-1}(z)] @@ -583,27 +577,32 @@ contract PlonkVerifierForDataAggregation { /// @param n_pub number of public inputs (number of Lagranges to compute) /// @param mPtr pointer to which the results are stored function batch_compute_lagranges_at_z(z, zpnmo, n_pub, mPtr) { - let zn := mulmod(zpnmo, VK_INV_DOMAIN_SIZE, R_MOD) // 1/n * (ζⁿ - 1) - + let _w := 1 let _mPtr := mPtr - for {let i:=0} lt(i,n_pub) {i:=add(i,1)} - { - mstore(_mPtr, addmod(z,sub(R_MOD, _w), R_MOD)) + for { + let i := 0 + } lt(i, n_pub) { + i := add(i, 1) + } { + mstore(_mPtr, addmod(z, sub(R_MOD, _w), R_MOD)) _w := mulmod(_w, VK_OMEGA, R_MOD) _mPtr := add(_mPtr, 0x20) } batch_invert(mPtr, n_pub, _mPtr) _mPtr := mPtr _w := 1 - for {let i:=0} lt(i,n_pub) {i:=add(i,1)} - { - mstore(_mPtr, mulmod(mulmod(mload(_mPtr), zn , R_MOD), _w, R_MOD)) + for { + let i := 0 + } lt(i, n_pub) { + i := add(i, 1) + } { + mstore(_mPtr, mulmod(mulmod(mload(_mPtr), zn, R_MOD), _w, R_MOD)) _mPtr := add(_mPtr, 0x20) _w := mulmod(_w, VK_OMEGA, R_MOD) } - } + } /// @notice Montgomery trick for batch inversion mod R_MOD /// @param ins pointer to the data to batch invert @@ -612,8 +611,11 @@ contract PlonkVerifierForDataAggregation { function batch_invert(ins, nb_ins, mPtr) { mstore(mPtr, 1) let offset := 0 - for {let i:=0} lt(i, nb_ins) {i:=add(i,1)} - { + for { + let i := 0 + } lt(i, nb_ins) { + i := add(i, 1) + } { let prev := mload(add(mPtr, offset)) let cur := mload(add(ins, offset)) cur := mulmod(prev, cur, R_MOD) @@ -622,9 +624,12 @@ contract PlonkVerifierForDataAggregation { } ins := add(ins, sub(offset, 0x20)) mPtr := add(mPtr, offset) - let inv := pow(mload(mPtr), sub(R_MOD,2), add(mPtr, 0x20)) - for {let i:=0} lt(i, nb_ins) {i:=add(i,1)} - { + let inv := pow(mload(mPtr), sub(R_MOD, 2), add(mPtr, 0x20)) + for { + let i := 0 + } lt(i, nb_ins) { + i := add(i, 1) + } { mPtr := sub(mPtr, 0x20) let tmp := mload(ins) let cur := mulmod(inv, mload(mPtr), R_MOD) @@ -634,14 +639,12 @@ contract PlonkVerifierForDataAggregation { } } - /// Public inputs (the ones coming from the custom gate) contribution /// @param aproof pointer to the proof /// @param nb_public_inputs number of public inputs /// @param mPtr pointer to free memory /// @return pi_commit custom gate public inputs contribution - function sum_pi_commit(aproof, nb_public_inputs, mPtr)->pi_commit { - + function sum_pi_commit(aproof, nb_public_inputs, mPtr) -> pi_commit { let state := mload(0x40) let z := mload(add(state, STATE_ZETA)) let zpnmo := mload(add(state, STATE_ZETA_POWER_N_MINUS_ONE)) @@ -649,14 +652,10 @@ contract PlonkVerifierForDataAggregation { let p := add(aproof, PROOF_BSB_COMMITMENTS) let h_fr, ith_lagrange - - + h_fr := hash_fr(calldataload(p), calldataload(add(p, 0x20)), mPtr) ith_lagrange := compute_ith_lagrange_at_z(z, zpnmo, add(nb_public_inputs, VK_INDEX_COMMIT_API_0), mPtr) pi_commit := addmod(pi_commit, mulmod(h_fr, ith_lagrange, R_MOD), R_MOD) - - - } /// Computes L_i(zeta) = ωⁱ/n * (ζⁿ-1)/(ζ-ωⁱ) where: @@ -664,16 +663,14 @@ contract PlonkVerifierForDataAggregation { /// @param zpmno ζⁿ-1 /// @param i i-th lagrange /// @param mPtr free memory - /// @return res = ωⁱ/n * (ζⁿ-1)/(ζ-ωⁱ) - function compute_ith_lagrange_at_z(z, zpnmo, i, mPtr)->res { - + /// @return res = ωⁱ/n * (ζⁿ-1)/(ζ-ωⁱ) + function compute_ith_lagrange_at_z(z, zpnmo, i, mPtr) -> res { let w := pow(VK_OMEGA, i, mPtr) // w**i i := addmod(z, sub(R_MOD, w), R_MOD) // z-w**i w := mulmod(w, VK_INV_DOMAIN_SIZE, R_MOD) // w**i/n - i := pow(i, sub(R_MOD,2), mPtr) // (z-w**i)**-1 + i := pow(i, sub(R_MOD, 2), mPtr) // (z-w**i)**-1 w := mulmod(w, i, R_MOD) // w**i/n*(z-w)**-1 res := mulmod(w, zpnmo, R_MOD) - } /// @dev https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2 @@ -681,15 +678,14 @@ contract PlonkVerifierForDataAggregation { /// @param y y coordinate of a point on Bn254(𝔽_p) /// @param mPtr free memory /// @return res an element mod R_MOD - function hash_fr(x, y, mPtr)->res { - + function hash_fr(x, y, mPtr) -> res { // [0x00, .. , 0x00 || x, y, || 0, 48, 0, dst, HASH_FR_SIZE_DOMAIN] // <- 64 bytes -> <-64b -> <- 1 bytes each -> // [0x00, .., 0x00] 64 bytes of zero mstore(mPtr, HASH_FR_ZERO_UINT256) mstore(add(mPtr, 0x20), HASH_FR_ZERO_UINT256) - + // msg = x || y , both on 32 bytes mstore(add(mPtr, 0x40), x) mstore(add(mPtr, 0x60), y) @@ -725,7 +721,7 @@ contract PlonkVerifierForDataAggregation { // [b0 || one || dst || HASH_FR_SIZE_DOMAIN] // <-64bytes -> <- 1 byte each -> mstore8(add(mPtr, 0x20), HASH_FR_ONE) // 1 - + mstore8(add(mPtr, 0x21), 0x42) // dst mstore8(add(mPtr, 0x22), 0x53) mstore8(add(mPtr, 0x23), 0x42) @@ -777,9 +773,8 @@ contract PlonkVerifierForDataAggregation { res := mulmod(mload(mPtr), HASH_FR_BB, R_MOD) // <- res = 2**128 * mPtr[:32] let b1 := shr(128, mload(add(mPtr, 0x20))) // b1 <- [0, 0, .., 0 || b2[:16] ] res := addmod(res, b1, R_MOD) - } - + // END compute_pi ------------------------------------------------- /// @notice compute α² * 1/n * (ζ{n}-1)/(ζ - 1) where @@ -787,7 +782,7 @@ contract PlonkVerifierForDataAggregation { /// * n = vk_domain_size /// * ω = vk_omega (generator of the multiplicative cyclic group of order n in (ℤ/rℤ)*) /// * ζ = zeta (challenge derived with Fiat Shamir) - function compute_alpha_square_lagrange_0() { + function compute_alpha_square_lagrange_0() { let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) @@ -827,7 +822,7 @@ contract PlonkVerifierForDataAggregation { mstore(add(mPtr, 0x100), mload(add(state, STATE_ZETA))) mstore(add(mPtr, 0x120), mload(add(state, STATE_GAMMA_KZG))) let random := staticcall(gas(), SHA2, mPtr, 0x140, mPtr, 0x20) - if iszero(random){ + if iszero(random) { error_random_generation() } random := mod(mload(mPtr), R_MOD) // use the same variable as we are one variable away from getting stack-too-deep error... @@ -876,18 +871,18 @@ contract PlonkVerifierForDataAggregation { mstore(folded_quotients_y, sub(P_MOD, mload(folded_quotients_y))) mstore(mPtr, mload(folded_digests)) - - mstore(add(mPtr, 0x20), mload(add(folded_digests, 0x20))) - mstore(add(mPtr, 0x40), G2_SRS_0_X_0) // the 4 lines are the canonical G2 point on BN254 - mstore(add(mPtr, 0x60), G2_SRS_0_X_1) - mstore(add(mPtr, 0x80), G2_SRS_0_Y_0) - mstore(add(mPtr, 0xa0), G2_SRS_0_Y_1) - mstore(add(mPtr, 0xc0), mload(folded_quotients)) - mstore(add(mPtr, 0xe0), mload(add(folded_quotients, 0x20))) - mstore(add(mPtr, 0x100), G2_SRS_1_X_0) - mstore(add(mPtr, 0x120), G2_SRS_1_X_1) - mstore(add(mPtr, 0x140), G2_SRS_1_Y_0) - mstore(add(mPtr, 0x160), G2_SRS_1_Y_1) + + mstore(add(mPtr, 0x20), mload(add(folded_digests, 0x20))) + mstore(add(mPtr, 0x40), G2_SRS_0_X_0) // the 4 lines are the canonical G2 point on BN254 + mstore(add(mPtr, 0x60), G2_SRS_0_X_1) + mstore(add(mPtr, 0x80), G2_SRS_0_Y_0) + mstore(add(mPtr, 0xa0), G2_SRS_0_Y_1) + mstore(add(mPtr, 0xc0), mload(folded_quotients)) + mstore(add(mPtr, 0xe0), mload(add(folded_quotients, 0x20))) + mstore(add(mPtr, 0x100), G2_SRS_1_X_0) + mstore(add(mPtr, 0x120), G2_SRS_1_X_1) + mstore(add(mPtr, 0x140), G2_SRS_1_Y_0) + mstore(add(mPtr, 0x160), G2_SRS_1_Y_1) check_pairing_kzg(mPtr) } @@ -912,7 +907,6 @@ contract PlonkVerifierForDataAggregation { /// @param aproof pointer to the proof /// acc_gamma stores the γⁱ function fold_state(aproof) { - let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) let mPtr20 := add(mPtr, 0x20) @@ -949,15 +943,14 @@ contract PlonkVerifierForDataAggregation { point_acc_mul(state_folded_digests, mPtr, acc_gamma, mPtr40) fr_acc_mul_calldata(add(state, STATE_FOLDED_CLAIMED_VALUES), add(aproof, PROOF_S2_AT_ZETA), acc_gamma) let poqaz := add(aproof, PROOF_OPENING_QCP_AT_ZETA) - + acc_gamma := mulmod(acc_gamma, l_gamma_kzg, R_MOD) mstore(mPtr, VK_QCP_0_X) mstore(mPtr20, VK_QCP_0_Y) point_acc_mul(state_folded_digests, mPtr, acc_gamma, mPtr40) fr_acc_mul_calldata(add(state, STATE_FOLDED_CLAIMED_VALUES), poqaz, acc_gamma) poqaz := add(poqaz, 0x20) - - } + } /// @notice generate the challenge (using Fiat Shamir) to fold the opening proofs /// at ζ. @@ -975,23 +968,22 @@ contract PlonkVerifierForDataAggregation { /// * Z(ζω) /// @param aproof pointer to the proof function compute_gamma_kzg(aproof) { - let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) mstore(mPtr, FS_GAMMA_KZG) // "gamma" mstore(add(mPtr, 0x20), mload(add(state, STATE_ZETA))) - mstore(add(mPtr,0x40), mload(add(state, STATE_LINEARISED_POLYNOMIAL_X))) - mstore(add(mPtr,0x60), mload(add(state, STATE_LINEARISED_POLYNOMIAL_Y))) + mstore(add(mPtr, 0x40), mload(add(state, STATE_LINEARISED_POLYNOMIAL_X))) + mstore(add(mPtr, 0x60), mload(add(state, STATE_LINEARISED_POLYNOMIAL_Y))) calldatacopy(add(mPtr, 0x80), add(aproof, PROOF_L_COM_X), 0xc0) - mstore(add(mPtr,0x140), VK_S1_COM_X) - mstore(add(mPtr,0x160), VK_S1_COM_Y) - mstore(add(mPtr,0x180), VK_S2_COM_X) - mstore(add(mPtr,0x1a0), VK_S2_COM_Y) - + mstore(add(mPtr, 0x140), VK_S1_COM_X) + mstore(add(mPtr, 0x160), VK_S1_COM_Y) + mstore(add(mPtr, 0x180), VK_S2_COM_X) + mstore(add(mPtr, 0x1a0), VK_S2_COM_Y) + let offset := 0x1c0 - - mstore(add(mPtr,offset), VK_QCP_0_X) - mstore(add(mPtr,add(offset, 0x20)), VK_QCP_0_Y) + + mstore(add(mPtr, offset), VK_QCP_0_X) + mstore(add(mPtr, add(offset, 0x20)), VK_QCP_0_Y) offset := add(offset, 0x40) mstore(add(mPtr, offset), mload(add(state, STATE_OPENING_LINEARISED_POLYNOMIAL_ZETA))) mstore(add(mPtr, add(offset, 0x20)), calldataload(add(aproof, PROOF_L_AT_ZETA))) @@ -1002,18 +994,23 @@ contract PlonkVerifierForDataAggregation { let _mPtr := add(mPtr, add(offset, 0xc0)) - let _poqaz := add(aproof, PROOF_OPENING_QCP_AT_ZETA) calldatacopy(_mPtr, _poqaz, mul(VK_NB_CUSTOM_GATES, 0x20)) _mPtr := add(_mPtr, mul(VK_NB_CUSTOM_GATES, 0x20)) - mstore(_mPtr, calldataload(add(aproof, PROOF_GRAND_PRODUCT_AT_ZETA_OMEGA))) let start_input := 0x1b // 00.."gamma" - let size_input := add(0x14, mul(VK_NB_CUSTOM_GATES,3)) // number of 32bytes elmts = 0x14 (zeta+3*6 for the digests+openings) + 3*VK_NB_CUSTOM_GATES (for the commitments of the selectors) + 1 (opening of Z at ζω) + let size_input := add(0x14, mul(VK_NB_CUSTOM_GATES, 3)) // number of 32bytes elmts = 0x14 (zeta+3*6 for the digests+openings) + 3*VK_NB_CUSTOM_GATES (for the commitments of the selectors) + 1 (opening of Z at ζω) size_input := add(0x5, mul(size_input, 0x20)) // size in bytes: 15*32 bytes + 5 bytes for gamma - let check_staticcall := staticcall(gas(), SHA2, add(mPtr,start_input), size_input, add(state, STATE_GAMMA_KZG), 0x20) + let check_staticcall := staticcall( + gas(), + SHA2, + add(mPtr, start_input), + size_input, + add(state, STATE_GAMMA_KZG), + 0x20 + ) if iszero(check_staticcall) { error_verify() } @@ -1021,7 +1018,6 @@ contract PlonkVerifierForDataAggregation { } function compute_commitment_linearised_polynomial_ec(aproof, s1, s2) { - let state := mload(0x40) let mPtr := add(mload(0x40), STATE_LAST_MEM) @@ -1066,7 +1062,6 @@ contract PlonkVerifierForDataAggregation { add(mPtr, 0x40) ) - let qcp_opening_at_zeta := add(aproof, PROOF_OPENING_QCP_AT_ZETA) let bsb_commitments := add(aproof, PROOF_BSB_COMMITMENTS) for { @@ -1085,7 +1080,6 @@ contract PlonkVerifierForDataAggregation { qcp_opening_at_zeta := add(qcp_opening_at_zeta, 0x20) bsb_commitments := add(bsb_commitments, 0x40) } - mstore(mPtr, VK_S3_COM_X) mstore(add(mPtr, 0x20), VK_S3_COM_Y) @@ -1096,10 +1090,11 @@ contract PlonkVerifierForDataAggregation { point_acc_mul(add(state, STATE_LINEARISED_POLYNOMIAL_X), mPtr, s2, add(mPtr, 0x40)) point_add( - add(state, STATE_LINEARISED_POLYNOMIAL_X), - add(state, STATE_LINEARISED_POLYNOMIAL_X), - add(state, STATE_FOLDED_H_X), - mPtr) + add(state, STATE_LINEARISED_POLYNOMIAL_X), + add(state, STATE_LINEARISED_POLYNOMIAL_X), + add(state, STATE_FOLDED_H_X), + mPtr + ) } /// @notice Compute the commitment to the linearized polynomial equal to @@ -1166,10 +1161,25 @@ contract PlonkVerifierForDataAggregation { let mPtr := add(mload(0x40), STATE_LAST_MEM) let zeta_power_n_plus_two := pow(mload(add(state, STATE_ZETA)), n_plus_two, mPtr) point_mul_calldata(add(state, STATE_FOLDED_H_X), add(aproof, PROOF_H_2_COM_X), zeta_power_n_plus_two, mPtr) - point_add_calldata(add(state, STATE_FOLDED_H_X), add(state, STATE_FOLDED_H_X), add(aproof, PROOF_H_1_COM_X), mPtr) + point_add_calldata( + add(state, STATE_FOLDED_H_X), + add(state, STATE_FOLDED_H_X), + add(aproof, PROOF_H_1_COM_X), + mPtr + ) point_mul(add(state, STATE_FOLDED_H_X), add(state, STATE_FOLDED_H_X), zeta_power_n_plus_two, mPtr) - point_add_calldata(add(state, STATE_FOLDED_H_X), add(state, STATE_FOLDED_H_X), add(aproof, PROOF_H_0_COM_X), mPtr) - point_mul(add(state, STATE_FOLDED_H_X), add(state, STATE_FOLDED_H_X), mload(add(state, STATE_ZETA_POWER_N_MINUS_ONE)), mPtr) + point_add_calldata( + add(state, STATE_FOLDED_H_X), + add(state, STATE_FOLDED_H_X), + add(aproof, PROOF_H_0_COM_X), + mPtr + ) + point_mul( + add(state, STATE_FOLDED_H_X), + add(state, STATE_FOLDED_H_X), + mload(add(state, STATE_ZETA_POWER_N_MINUS_ONE)), + mPtr + ) let folded_h_y := mload(add(state, STATE_FOLDED_H_Y)) folded_h_y := sub(P_MOD, folded_h_y) mstore(add(state, STATE_FOLDED_H_Y), folded_h_y) @@ -1179,7 +1189,6 @@ contract PlonkVerifierForDataAggregation { /// - [ PI(ζ) - α²*L₁(ζ) + α(l(ζ)+β*s1(ζ)+γ)(r(ζ)+β*s2(ζ)+γ)(o(ζ)+γ)*z(ωζ) ] /// @param aproof pointer to the proof function compute_opening_linearised_polynomial(aproof) { - let state := mload(0x40) // (l(ζ)+β*s1(ζ)+γ) @@ -1215,7 +1224,7 @@ contract PlonkVerifierForDataAggregation { } // BEGINNING utils math functions ------------------------------------------------- - + /// @param dst pointer storing the result /// @param p pointer to the first point /// @param q pointer to the second point @@ -1225,7 +1234,7 @@ contract PlonkVerifierForDataAggregation { mstore(add(mPtr, 0x20), mload(add(p, 0x20))) mstore(add(mPtr, 0x40), mload(q)) mstore(add(mPtr, 0x60), mload(add(q, 0x20))) - let l_success := staticcall(gas(),EC_ADD,mPtr,0x80,dst,0x40) + let l_success := staticcall(gas(), EC_ADD, mPtr, 0x80, dst, 0x40) if iszero(l_success) { error_ec_op() } @@ -1250,11 +1259,11 @@ contract PlonkVerifierForDataAggregation { /// @param src pointer to a point on Bn254(𝔽_p) /// @param s scalar /// @param mPtr free memory - function point_mul(dst,src,s, mPtr) { - mstore(mPtr,mload(src)) - mstore(add(mPtr,0x20),mload(add(src,0x20))) - mstore(add(mPtr,0x40),s) - let l_success := staticcall(gas(),EC_MUL,mPtr,0x60,dst,0x40) + function point_mul(dst, src, s, mPtr) { + mstore(mPtr, mload(src)) + mstore(add(mPtr, 0x20), mload(add(src, 0x20))) + mstore(add(mPtr, 0x40), s) + let l_success := staticcall(gas(), EC_MUL, mPtr, 0x60, dst, 0x40) if iszero(l_success) { error_ec_op() } @@ -1279,14 +1288,14 @@ contract PlonkVerifierForDataAggregation { /// @param src pointer to the point to multiply and add /// @param s scalar /// @param mPtr free memory - function point_acc_mul(dst,src,s, mPtr) { - mstore(mPtr,mload(src)) - mstore(add(mPtr,0x20),mload(add(src,0x20))) - mstore(add(mPtr,0x40),s) - let l_success := staticcall(gas(),7,mPtr,0x60,mPtr,0x40) - mstore(add(mPtr,0x40),mload(dst)) - mstore(add(mPtr,0x60),mload(add(dst,0x20))) - l_success := and(l_success, staticcall(gas(),EC_ADD,mPtr,0x80,dst, 0x40)) + function point_acc_mul(dst, src, s, mPtr) { + mstore(mPtr, mload(src)) + mstore(add(mPtr, 0x20), mload(add(src, 0x20))) + mstore(add(mPtr, 0x40), s) + let l_success := staticcall(gas(), 7, mPtr, 0x60, mPtr, 0x40) + mstore(add(mPtr, 0x40), mload(dst)) + mstore(add(mPtr, 0x60), mload(add(dst, 0x20))) + l_success := and(l_success, staticcall(gas(), EC_ADD, mPtr, 0x80, dst, 0x40)) if iszero(l_success) { error_ec_op() } @@ -1315,7 +1324,7 @@ contract PlonkVerifierForDataAggregation { /// @param src pointer to the scalar to multiply and add (on calldata) /// @param s scalar function fr_acc_mul_calldata(dst, src, s) { - let tmp := mulmod(calldataload(src), s, R_MOD) + let tmp := mulmod(calldataload(src), s, R_MOD) mstore(dst, addmod(mload(dst), tmp, R_MOD)) } @@ -1323,16 +1332,16 @@ contract PlonkVerifierForDataAggregation { /// @param e exponent /// @param mPtr free memory /// @return res x ** e mod r - function pow(x, e, mPtr)->res { + function pow(x, e, mPtr) -> res { mstore(mPtr, 0x20) mstore(add(mPtr, 0x20), 0x20) mstore(add(mPtr, 0x40), 0x20) mstore(add(mPtr, 0x60), x) mstore(add(mPtr, 0x80), e) mstore(add(mPtr, 0xa0), R_MOD) - let check_staticcall := staticcall(gas(),MOD_EXP,mPtr,0xc0,mPtr,0x20) + let check_staticcall := staticcall(gas(), MOD_EXP, mPtr, 0xc0, mPtr, 0x20) if eq(check_staticcall, 0) { - error_mod_exp() + error_mod_exp() } res := mload(mPtr) } diff --git a/contracts/test/hardhat/rollup/LineaRollup.ts b/contracts/test/hardhat/rollup/LineaRollup.ts index 936195a3..c092d872 100644 --- a/contracts/test/hardhat/rollup/LineaRollup.ts +++ b/contracts/test/hardhat/rollup/LineaRollup.ts @@ -3,8 +3,8 @@ import { loadFixture, time as networkTime } from "@nomicfoundation/hardhat-netwo import { expect } from "chai"; import { config, ethers, upgrades } from "hardhat"; import { HardhatNetworkHDAccountsConfig } from "hardhat/types"; -import { BaseContract, Contract, HDNodeWallet, Transaction, Wallet, ZeroAddress } from "ethers"; -import { CallForwardingProxy, TestLineaRollup, TestLineaRollupV5 } from "../../../typechain-types"; +import { BaseContract, Contract, HDNodeWallet, Transaction, Wallet } from "ethers"; +import { CallForwardingProxy, TestLineaRollup } from "../../../typechain-types"; import calldataAggregatedProof1To155 from "../_testData/compressedData/aggregatedProof-1-155.json"; import blobAggregatedProof1To155 from "../_testData/compressedDataEip4844/aggregatedProof-1-155.json"; import blobMultipleAggregatedProof1To81 from "../_testData/compressedDataEip4844/multipleProofs/aggregatedProof-1-81.json"; @@ -32,20 +32,9 @@ import { CALLDATA_SUBMISSION_PAUSE_TYPE, BLOB_SUBMISSION_PAUSE_TYPE, FINALIZATION_PAUSE_TYPE, - PAUSE_ALL_ROLE, DEFAULT_ADMIN_ROLE, - UNPAUSE_ALL_ROLE, - PAUSE_BLOB_SUBMISSION_ROLE, - UNPAUSE_BLOB_SUBMISSION_ROLE, - PAUSE_FINALIZATION_ROLE, - UNPAUSE_FINALIZATION_ROLE, DEFAULT_LAST_FINALIZED_TIMESTAMP, SIX_MONTHS_IN_SECONDS, - USED_RATE_LIMIT_RESETTER_ROLE, - PAUSE_L1_L2_ROLE, - PAUSE_L2_L1_ROLE, - UNPAUSE_L1_L2_ROLE, - UNPAUSE_L2_L1_ROLE, LINEA_ROLLUP_INITIALIZE_SIGNATURE, } from "../common/constants"; import { deployUpgradableFromFactory } from "../common/deployment"; @@ -66,9 +55,7 @@ import { generateParentShnarfData, generateBlobDataSubmission, generateBlobParentShnarfData, - convertStringToPaddedHexBytes, calculateLastFinalizedState, - expectEvents, expectEventDirectFromReceiptData, generateBlobDataSubmissionFromFile, } from "../common/helpers"; @@ -88,7 +75,6 @@ kzg.loadTrustedSetup(`${__dirname}/../_testData/trusted_setup.txt`); describe("Linea Rollup contract", () => { let lineaRollup: TestLineaRollup; - let lineaRollupV5: TestLineaRollupV5; let revertingVerifier: string; let sepoliaFullVerifier: string; let callForwardingProxy: CallForwardingProxy; @@ -164,7 +150,7 @@ describe("Linea Rollup contract", () => { before(async () => { [admin, securityCouncil, operator, nonAuthorizedAccount] = await ethers.getSigners(); - const securityCouncilAddress = securityCouncil.address; + const securityCouncilAddress = await securityCouncil.getAddress(); roleAddresses = generateRoleAssignments(LINEA_ROLLUP_ROLES, securityCouncilAddress, [ { @@ -2257,6 +2243,69 @@ describe("Linea Rollup contract", () => { const args = [OPERATOR_ROLE, operator.address, operator.address]; expectEvent(lineaRollup, renounceCall, "RoleRevoked", args); }); + + it("Should fail to accept ETH on the CallForwardingProxy receive function", async () => { + await deployCallForwardingProxy(await lineaRollup.getAddress()); + const forwardingProxyAddress = await callForwardingProxy.getAddress(); + + const tx = { + to: forwardingProxyAddress, + value: ethers.parseEther("0.1"), + }; + + await expectRevertWithReason(admin.sendTransaction(tx), "ETH not accepted"); + }); + + it("Should be able to submit blobs and finalize via callforwarding proxy", async () => { + await deployCallForwardingProxy(await lineaRollup.getAddress()); + const forwardingProxyAddress = await callForwardingProxy.getAddress(); + + expect(await lineaRollup.currentL2BlockNumber()).to.equal(0); + + // Deploy new LineaRollup implementation + const newLineaRollupFactory = await ethers.getContractFactory( + "src/_testing/unit/rollup/TestLineaRollup.sol:TestLineaRollup", + ); + const newLineaRollup = await upgrades.upgradeProxy(lineaRollup, newLineaRollupFactory, { + unsafeAllowRenames: true, + }); + + const upgradedContract = await newLineaRollup.waitForDeployment(); + + await upgradedContract.reinitializeLineaRollupV6( + [], + LINEA_ROLLUP_PAUSE_TYPES_ROLES, + LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, + forwardingProxyAddress, + ); + + // Grants deployed callforwarding proxy as operator + await networkTime.increase(SIX_MONTHS_IN_SECONDS); + await expectEvent( + upgradedContract, + upgradedContract.setFallbackOperator(0n, HASH_ZERO, DEFAULT_LAST_FINALIZED_TIMESTAMP), + "FallbackOperatorRoleGranted", + [admin.address, forwardingProxyAddress], + ); + + // Submit 2 blobs + await sendBlobTransactionViaCallForwarder(upgradedContract, 0, 2, forwardingProxyAddress); + // Submit another 2 blobs + await sendBlobTransactionViaCallForwarder(upgradedContract, 2, 4, forwardingProxyAddress); + + // Finalize 4 blobs + await expectSuccessfulFinalizeViaCallForwarder( + blobAggregatedProof1To155, + 4, + fourthCompressedDataContent.finalStateRootHash, + generateBlobParentShnarfData, + false, + HASH_ZERO, + 0n, + forwardingProxyAddress, + upgradedContract, + ); + }); }); async function sendBlobTransaction(startIndex: number, finalIndex: number, isMultiple: boolean = false) { @@ -2597,322 +2646,4 @@ describe("Linea Rollup contract", () => { ), ); } - - describe("LineaRollup Upgradeable Tests", () => { - let newRoleAddresses: { addressWithRole: string; role: string }[]; - - async function deployLineaRollupFixture() { - const plonkVerifierFactory = await ethers.getContractFactory("TestPlonkVerifierForDataAggregation"); - const plonkVerifier = await plonkVerifierFactory.deploy(); - await plonkVerifier.waitForDeployment(); - - verifier = await plonkVerifier.getAddress(); - - const lineaRollup = (await deployUpgradableFromFactory( - "src/_testing/unit/rollup/TestLineaRollupV5.sol:TestLineaRollupV5", - [ - parentStateRootHash, - 0, - verifier, - securityCouncil.address, - [operator.address], - ONE_DAY_IN_SECONDS, - INITIAL_WITHDRAW_LIMIT, - DEFAULT_LAST_FINALIZED_TIMESTAMP, - ], - { - initializer: "initialize(bytes32,uint256,address,address,address[],uint256,uint256,uint256)", - unsafeAllow: ["constructor"], - }, - )) as unknown as TestLineaRollupV5; - - return lineaRollup; - } - - before(async () => { - const securityCouncilAddress = securityCouncil.address; - - newRoleAddresses = [ - { addressWithRole: securityCouncilAddress, role: USED_RATE_LIMIT_RESETTER_ROLE }, - { addressWithRole: securityCouncilAddress, role: VERIFIER_UNSETTER_ROLE }, - { addressWithRole: securityCouncilAddress, role: PAUSE_ALL_ROLE }, - { addressWithRole: securityCouncilAddress, role: PAUSE_L1_L2_ROLE }, - { addressWithRole: securityCouncilAddress, role: PAUSE_L2_L1_ROLE }, - { addressWithRole: securityCouncilAddress, role: UNPAUSE_ALL_ROLE }, - { addressWithRole: securityCouncilAddress, role: UNPAUSE_L1_L2_ROLE }, - { addressWithRole: securityCouncilAddress, role: UNPAUSE_L2_L1_ROLE }, - { addressWithRole: securityCouncilAddress, role: PAUSE_BLOB_SUBMISSION_ROLE }, - { addressWithRole: securityCouncilAddress, role: UNPAUSE_BLOB_SUBMISSION_ROLE }, - { addressWithRole: securityCouncilAddress, role: PAUSE_FINALIZATION_ROLE }, - { addressWithRole: securityCouncilAddress, role: UNPAUSE_FINALIZATION_ROLE }, - ]; - }); - - beforeEach(async () => { - lineaRollupV5 = await loadFixture(deployLineaRollupFixture); - - // we need to set a non-zero value for the genesis shnarf else it will break on blob submission. - const { parentShnarf, snarkHash, finalStateRootHash, dataEvaluationPoint, dataEvaluationClaim } = - generateParentShnarfData(0); - const genesisShnarf = generateKeccak256( - ["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"], - [parentShnarf, snarkHash, finalStateRootHash, dataEvaluationPoint, dataEvaluationClaim], - ); - - await lineaRollupV5.setDefaultShnarfExistValue(genesisShnarf); - }); - - it("Should revert if fallback operator has address zero", async () => { - expect(await lineaRollupV5.currentL2BlockNumber()).to.equal(0); - - // Deploy new implementation - const newLineaRollupFactory = await ethers.getContractFactory( - "src/_testing/unit/rollup/TestLineaRollup.sol:TestLineaRollup", - ); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollupV5, newLineaRollupFactory, { - unsafeAllowRenames: true, - }); - const upgradedContract = await newLineaRollup.waitForDeployment(); - - expectRevertWithCustomError( - upgradedContract, - upgradedContract.reinitializeLineaRollupV6( - newRoleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - ADDRESS_ZERO, - ), - "ZeroAddressNotAllowed", - ); - }); - - it("Should fail to accept ETH on the CallForwardingProxy receive function", async () => { - await deployCallForwardingProxy(await lineaRollupV5.getAddress()); - const forwardingProxyAddress = await callForwardingProxy.getAddress(); - - const tx = { - to: forwardingProxyAddress, - value: ethers.parseEther("0.1"), - }; - - await expectRevertWithReason(admin.sendTransaction(tx), "ETH not accepted"); - }); - - it("Should be able to submit blobs and finalize via callforwarding proxy", async () => { - // Deploy callforwarding proxy - await deployCallForwardingProxy(await lineaRollupV5.getAddress()); - const forwardingProxyAddress = await callForwardingProxy.getAddress(); - - expect(await lineaRollupV5.currentL2BlockNumber()).to.equal(0); - - // Deploy new LineaRollup implementation - const newLineaRollupFactory = await ethers.getContractFactory( - "src/_testing/unit/rollup/TestLineaRollup.sol:TestLineaRollup", - ); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollupV5, newLineaRollupFactory, { - unsafeAllowRenames: true, - }); - - const upgradedContract = await newLineaRollup.waitForDeployment(); - - await upgradedContract.reinitializeLineaRollupV6( - newRoleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - forwardingProxyAddress, - ); - - // Grants deployed callforwarding proxy as operator - await networkTime.increase(SIX_MONTHS_IN_SECONDS); - await expectEvent( - upgradedContract, - upgradedContract.setFallbackOperator(0n, HASH_ZERO, DEFAULT_LAST_FINALIZED_TIMESTAMP), - "FallbackOperatorRoleGranted", - [admin.address, forwardingProxyAddress], - ); - - // Submit 2 blobs - await sendBlobTransactionViaCallForwarder(upgradedContract, 0, 2, forwardingProxyAddress); - // Submit another 2 blobs - await sendBlobTransactionViaCallForwarder(upgradedContract, 2, 4, forwardingProxyAddress); - - // Finalize 4 blobs - await expectSuccessfulFinalizeViaCallForwarder( - blobAggregatedProof1To155, - 4, - fourthCompressedDataContent.finalStateRootHash, - generateBlobParentShnarfData, - false, - HASH_ZERO, - 0n, - forwardingProxyAddress, - upgradedContract, - ); - }); - - it("Should deploy and upgrade the LineaRollup contract expecting LineaRollupVersionChanged", async () => { - expect(await lineaRollupV5.currentL2BlockNumber()).to.equal(0); - - // Deploy new implementation - const newLineaRollupFactory = await ethers.getContractFactory("src/rollup/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollupV5, newLineaRollupFactory, { - unsafeAllowRenames: true, - }); - const upgradedContract = await newLineaRollup.waitForDeployment(); - - const upgradeCall = upgradedContract.reinitializeLineaRollupV6( - newRoleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - fallbackoperatorAddress, - ); - - const expectedVersion5Bytes8 = convertStringToPaddedHexBytes("5.0", 8); - const expectedVersion6Bytes8 = convertStringToPaddedHexBytes("6.0", 8); - - await expectEvent(upgradedContract, upgradeCall, "LineaRollupVersionChanged", [ - expectedVersion5Bytes8, - expectedVersion6Bytes8, - ]); - }); - - it("Should upgrade the LineaRollup contract expecting FallbackOperatorAddressSet", async () => { - expect(await lineaRollupV5.currentL2BlockNumber()).to.equal(0); - - // Deploy new implementation - const newLineaRollupFactory = await ethers.getContractFactory("src/rollup/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollupV5, newLineaRollupFactory, { - unsafeAllowRenames: true, - }); - const upgradedContract = await newLineaRollup.waitForDeployment(); - const upgradeCall = upgradedContract.reinitializeLineaRollupV6( - newRoleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - fallbackoperatorAddress, - ); - - await expectEvent(upgradedContract, upgradeCall, "FallbackOperatorAddressSet", [ - admin.address, - fallbackoperatorAddress, - ]); - }); - - it("Should not be able to call reinitializeLineaRollupV6 when upgraded.", async () => { - expect(await lineaRollupV5.currentL2BlockNumber()).to.equal(0); - - // Deploy new implementation - const newLineaRollupFactory = await ethers.getContractFactory("src/rollup/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollupV5, newLineaRollupFactory, { - unsafeAllowRenames: true, - }); - const upgradedContract = await newLineaRollup.waitForDeployment(); - await upgradedContract.reinitializeLineaRollupV6( - newRoleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - fallbackoperatorAddress, - ); - - const secondCall = upgradedContract.reinitializeLineaRollupV6( - newRoleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - fallbackoperatorAddress, - ); - - await expectRevertWithReason(secondCall, "Initializable: contract is already initialized"); - }); - - it("Should revert with ZeroAddressNotAllowed when addressWithRole is zero address in reinitializeLineaRollupV6", async () => { - // Deploy new implementation - const newLineaRollupFactory = await ethers.getContractFactory("src/rollup/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollupV5, newLineaRollupFactory, { - unsafeAllowRenames: true, - }); - const upgradedContract = await newLineaRollup.waitForDeployment(); - const roleAddresses = [{ addressWithRole: ZeroAddress, role: DEFAULT_ADMIN_ROLE }, ...newRoleAddresses.slice(1)]; - - await expectRevertWithCustomError( - upgradedContract, - upgradedContract.reinitializeLineaRollupV6( - roleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - fallbackoperatorAddress, - ), - "ZeroAddressNotAllowed", - ); - }); - - it("Should set all permissions", async () => { - // Deploy new implementation - const newLineaRollupFactory = await ethers.getContractFactory("src/rollup/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollupV5, newLineaRollupFactory, { - unsafeAllowRenames: true, - }); - const upgradedContract = await newLineaRollup.waitForDeployment(); - - await upgradedContract.reinitializeLineaRollupV6( - newRoleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - fallbackoperatorAddress, - ); - - for (const { role, addressWithRole } of newRoleAddresses) { - expect(await upgradedContract.hasRole(role, addressWithRole)).to.be.true; - } - }); - - it("Should set all pause types and unpause types in mappings and emit events", async () => { - // Deploy new implementation - const newLineaRollupFactory = await ethers.getContractFactory("src/rollup/LineaRollup.sol:LineaRollup"); - const newLineaRollup = await upgrades.upgradeProxy(lineaRollupV5, newLineaRollupFactory, { - unsafeAllowRenames: true, - }); - const upgradedContract = await newLineaRollup.waitForDeployment(); - - const reinitializePromise = upgradedContract.reinitializeLineaRollupV6( - newRoleAddresses, - LINEA_ROLLUP_PAUSE_TYPES_ROLES, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES, - fallbackoperatorAddress, - ); - - await Promise.all([ - expectEvents( - upgradedContract, - reinitializePromise, - LINEA_ROLLUP_PAUSE_TYPES_ROLES.map(({ pauseType, role }) => ({ - name: "PauseTypeRoleSet", - args: [pauseType, role], - })), - ), - expectEvents( - upgradedContract, - reinitializePromise, - LINEA_ROLLUP_UNPAUSE_TYPES_ROLES.map(({ pauseType, role }) => ({ - name: "UnPauseTypeRoleSet", - args: [pauseType, role], - })), - ), - ]); - - const pauseTypeRolesMappingSlot = 219; - const unpauseTypeRolesMappingSlot = 220; - - for (const { pauseType, role } of LINEA_ROLLUP_PAUSE_TYPES_ROLES) { - const slot = generateKeccak256(["uint8", "uint256"], [pauseType, pauseTypeRolesMappingSlot]); - const roleInMapping = await ethers.provider.getStorage(upgradedContract.getAddress(), slot); - expect(roleInMapping).to.equal(role); - } - - for (const { pauseType, role } of LINEA_ROLLUP_UNPAUSE_TYPES_ROLES) { - const slot = generateKeccak256(["uint8", "uint256"], [pauseType, unpauseTypeRolesMappingSlot]); - const roleInMapping = await ethers.provider.getStorage(upgradedContract.getAddress(), slot); - expect(roleInMapping).to.equal(role); - } - }); - }); }); diff --git a/coordinator/app/src/main/kotlin/net/consensys/zkevm/coordinator/app/L1DependentApp.kt b/coordinator/app/src/main/kotlin/net/consensys/zkevm/coordinator/app/L1DependentApp.kt index 12da7431..65d9f572 100644 --- a/coordinator/app/src/main/kotlin/net/consensys/zkevm/coordinator/app/L1DependentApp.kt +++ b/coordinator/app/src/main/kotlin/net/consensys/zkevm/coordinator/app/L1DependentApp.kt @@ -446,7 +446,7 @@ class L1DependentApp( private val genesisStateProvider = GenesisStateProvider( configs.l1.genesisStateRootHash, - configs.l1.genesisShnarfV5 + configs.l1.genesisShnarfV6 ) private val blobCompressionProofCoordinator = run { diff --git a/coordinator/app/src/main/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfig.kt b/coordinator/app/src/main/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfig.kt index 54c4d1e7..938a8c59 100644 --- a/coordinator/app/src/main/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfig.kt +++ b/coordinator/app/src/main/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfig.kt @@ -278,15 +278,15 @@ data class L1Config( val blockTime: Duration = Duration.parse("PT12S"), @ConfigAlias("eth-fee-history-endpoint") private val _ethFeeHistoryEndpoint: URL?, @ConfigAlias("genesis-state-root-hash") private val _genesisStateRootHash: String, - @ConfigAlias("genesis-shnarf-v5") private val _genesisShnarfV5: String + @ConfigAlias("genesis-shnarf-v6") private val _genesisShnarfV6: String ) { val ethFeeHistoryEndpoint: URL get() = _ethFeeHistoryEndpoint ?: rpcEndpoint val genesisStateRootHash: ByteArray get() = _genesisStateRootHash.decodeHex().assertIs32Bytes("genesisStateRootHash") - val genesisShnarfV5: ByteArray - get() = _genesisShnarfV5.decodeHex().assertIs32Bytes("genesisShnarfV5") + val genesisShnarfV6: ByteArray + get() = _genesisShnarfV6.decodeHex().assertIs32Bytes("genesisShnarfV6") val l1QueryBlockTag: BlockParameter.Tag get() = BlockParameter.Tag.fromString(_l1QueryBlockTag) diff --git a/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfigTest.kt b/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfigTest.kt index 3b62a295..cc690b2f 100644 --- a/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfigTest.kt +++ b/coordinator/app/src/test/kotlin/net/consensys/zkevm/coordinator/app/config/CoordinatorConfigTest.kt @@ -209,7 +209,7 @@ class CoordinatorConfigTest { blockRangeLoopLimit = 500U, _ethFeeHistoryEndpoint = null, _genesisStateRootHash = "0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd", - _genesisShnarfV5 = "0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f" + _genesisShnarfV6 = "0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f" ) private val l2Config = L2Config( diff --git a/coordinator/app/src/test/resources/configs/coordinator.config.toml b/coordinator/app/src/test/resources/configs/coordinator.config.toml index 62ce6851..c62f0fe6 100644 --- a/coordinator/app/src/test/resources/configs/coordinator.config.toml +++ b/coordinator/app/src/test/resources/configs/coordinator.config.toml @@ -110,11 +110,11 @@ finalized-block-tag="latest" # reset this once we know what to do on dev/UAT earliest-block=0 genesis-state-root-hash="0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd" -# shnarf for contract V5 +# shnarf for contract V6 # Keccak256(parentShnarf="0x00...00", snarkHash="0x00...00", # parentStateRootHash="0x072ead6777750dc20232d1cee8dc9a395c2d350df4bbaa5096c6f59b214dcecd", # evaludationClaim="0x00...00", evaludationPoint="0x00...00") -genesis-shnarf-v5="0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f" +genesis-shnarf-v6="0x47452a1b9ebadfe02bdd02f580fa1eba17680d57eec968a591644d05d78ee84f" [l2] rpc-endpoint="http://sequencer:8545" diff --git a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/LineaRollupAsyncFriendly.kt b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/LineaRollupAsyncFriendly.kt index bfdd2d4b..4221324f 100644 --- a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/LineaRollupAsyncFriendly.kt +++ b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/LineaRollupAsyncFriendly.kt @@ -1,6 +1,6 @@ package net.consensys.linea.contract -import build.linea.contract.LineaRollupV5 +import build.linea.contract.LineaRollupV6 import net.consensys.linea.web3j.AtomicContractEIP1559GasProvider import net.consensys.linea.web3j.EIP1559GasFees import net.consensys.linea.web3j.SmartContractErrors @@ -28,7 +28,7 @@ class LineaRollupAsyncFriendly( private val asyncTransactionManager: AsyncFriendlyTransactionManager, contractGasProvider: ContractGasProvider, private val smartContractErrors: SmartContractErrors -) : LineaRollupV5( +) : LineaRollupV6( contractAddress, web3j, asyncTransactionManager, diff --git a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/LineaRollupEnhancedWrapper.kt b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/LineaRollupEnhancedWrapper.kt index 593eafcd..b9b742af 100644 --- a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/LineaRollupEnhancedWrapper.kt +++ b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/LineaRollupEnhancedWrapper.kt @@ -1,6 +1,6 @@ package net.consensys.linea.contract.l1 -import build.linea.contract.LineaRollupV5 +import build.linea.contract.LineaRollupV6 import net.consensys.linea.contract.AsyncFriendlyTransactionManager import net.consensys.linea.contract.Web3JContractAsyncHelper import org.web3j.abi.datatypes.Function @@ -16,7 +16,7 @@ internal class LineaRollupEnhancedWrapper( asyncTransactionManager: AsyncFriendlyTransactionManager, contractGasProvider: ContractGasProvider, val helper: Web3JContractAsyncHelper -) : LineaRollupV5( +) : LineaRollupV6( contractAddress, web3j, asyncTransactionManager, diff --git a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JFunctionBuilders.kt b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JFunctionBuilders.kt deleted file mode 100644 index ad9fbdc9..00000000 --- a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JFunctionBuilders.kt +++ /dev/null @@ -1,104 +0,0 @@ -package net.consensys.linea.contract.l1 - -import build.linea.contract.LineaRollupV5 -import build.linea.contract.LineaRollupV5.BlobSubmissionData -import net.consensys.toBigInteger -import net.consensys.zkevm.domain.BlobRecord -import net.consensys.zkevm.domain.ProofToFinalize -import org.web3j.abi.TypeReference -import org.web3j.abi.datatypes.DynamicArray -import org.web3j.abi.datatypes.DynamicBytes -import org.web3j.abi.datatypes.Function -import org.web3j.abi.datatypes.Type -import org.web3j.abi.datatypes.generated.Bytes32 -import org.web3j.abi.datatypes.generated.Uint256 -import java.math.BigInteger -import java.util.Arrays - -internal fun buildSubmitBlobsFunction( - blobs: List -): Function { - val blobsSubmissionData = blobs.map { blob -> - val blobCompressionProof = blob.blobCompressionProof!! - val supportingSubmissionData = LineaRollupV5.SupportingSubmissionDataV2( - /*finalStateRootHash*/ blobCompressionProof.finalStateRootHash, - /*firstBlockInData*/ blob.startBlockNumber.toBigInteger(), - /*finalBlockInData*/ blob.endBlockNumber.toBigInteger(), - /*snarkHash*/ blobCompressionProof.snarkHash - ) - - BlobSubmissionData( - /*submissionData*/ supportingSubmissionData, - /*dataEvaluationClaim*/ BigInteger(blobCompressionProof.expectedY), - /*kzgCommitment*/ blobCompressionProof.commitment, - /*kzgProof*/ blobCompressionProof.kzgProofContract - ) - } - - /** - * function submitBlobs( - * BlobSubmissionData[] calldata _blobSubmissionData, - * bytes32 _parentShnarf, - * bytes32 _finalBlobShnarf - * ) external; - */ - return Function( - LineaRollupV5.FUNC_SUBMITBLOBS, - Arrays.asList>( - DynamicArray(BlobSubmissionData::class.java, blobsSubmissionData), - Bytes32(blobs.first().blobCompressionProof!!.prevShnarf), - Bytes32(blobs.last().blobCompressionProof!!.expectedShnarf) - ), - emptyList>() - ) -} - -internal fun buildFinalizeBlobsFunction( - aggregationProof: ProofToFinalize, - aggregationLastBlob: BlobRecord, - parentShnarf: ByteArray, - parentL1RollingHash: ByteArray, - parentL1RollingHashMessageNumber: Long -): Function { - val aggregationEndBlobInfo = LineaRollupV5.ShnarfData( - /*parentShnarf*/ aggregationLastBlob.blobCompressionProof!!.prevShnarf, - /*snarkHash*/ aggregationLastBlob.blobCompressionProof!!.snarkHash, - /*finalStateRootHash*/ aggregationLastBlob.blobCompressionProof!!.finalStateRootHash, - /*dataEvaluationPoint*/ aggregationLastBlob.blobCompressionProof!!.expectedX, - /*dataEvaluationClaim*/ aggregationLastBlob.blobCompressionProof!!.expectedY - ) - - val finalizationData = LineaRollupV5.FinalizationDataV2( - /*parentStateRootHash*/ aggregationProof.parentStateRootHash, - /*lastFinalizedShnarf*/ parentShnarf, - /*finalBlockInData*/ aggregationProof.finalBlockNumber.toBigInteger(), - /*shnarfData*/ aggregationEndBlobInfo, - /*lastFinalizedTimestamp*/ aggregationProof.parentAggregationLastBlockTimestamp.epochSeconds.toBigInteger(), - /*finalTimestamp*/ aggregationProof.finalTimestamp.epochSeconds.toBigInteger(), - /*lastFinalizedL1RollingHash*/ parentL1RollingHash, - /*l1RollingHash*/ aggregationProof.l1RollingHash, - /*lastFinalizedL1RollingHashMessageNumber*/ parentL1RollingHashMessageNumber.toBigInteger(), - /*l1RollingHashMessageNumber*/ aggregationProof.l1RollingHashMessageNumber.toBigInteger(), - /*l2MerkleTreesDepth*/ aggregationProof.l2MerkleTreesDepth.toBigInteger(), - /*l2MerkleRoots*/ aggregationProof.l2MerkleRoots, - /*l2MessagingBlocksOffsets*/ aggregationProof.l2MessagingBlocksOffsets - ) - - /** - * function finalizeBlocksWithProof( - * bytes calldata _aggregatedProof, - * uint256 _aggregatedVerifierIndex, - * FinalizationData calldata _finalizationData - * ) external; - */ - val function = Function( - LineaRollupV5.FUNC_FINALIZEBLOCKSWITHPROOF, - Arrays.asList>( - DynamicBytes(aggregationProof.aggregatedProof), - Uint256(aggregationProof.aggregatedVerifierIndex.toLong()), - finalizationData - ), - emptyList>() - ) - return function -} diff --git a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JFunctionBuildersV6.kt b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JFunctionBuildersV6.kt index 23cb67cd..0020b985 100644 --- a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JFunctionBuildersV6.kt +++ b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JFunctionBuildersV6.kt @@ -20,7 +20,6 @@ internal fun buildSubmitBlobsFunction( blobs: List ): Function { return when (version) { - LineaContractVersion.V5 -> buildSubmitBlobsFunction(blobs) LineaContractVersion.V6 -> buildSubmitBlobsFunctionV6(blobs) } } @@ -63,21 +62,10 @@ fun buildFinalizeBlocksFunction( version: LineaContractVersion, aggregationProof: ProofToFinalize, aggregationLastBlob: BlobRecord, - parentShnarf: ByteArray, parentL1RollingHash: ByteArray, parentL1RollingHashMessageNumber: Long ): Function { when (version) { - LineaContractVersion.V5 -> { - return buildFinalizeBlobsFunction( - aggregationProof, - aggregationLastBlob, - parentShnarf, - parentL1RollingHash, - parentL1RollingHashMessageNumber - ) - } - LineaContractVersion.V6 -> { return buildFinalizeBlockFunctionV6( aggregationProof, diff --git a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JLineaRollupSmartContractClient.kt b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JLineaRollupSmartContractClient.kt index aea80c71..76e10102 100644 --- a/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JLineaRollupSmartContractClient.kt +++ b/coordinator/clients/smart-contract-client/src/main/kotlin/net/consensys/linea/contract/l1/Web3JLineaRollupSmartContractClient.kt @@ -1,6 +1,6 @@ package net.consensys.linea.contract.l1 -import build.linea.contract.LineaRollupV5 +import build.linea.contract.LineaRollupV6 import build.linea.contract.l1.Web3JLineaRollupSmartContractClientReadOnly import net.consensys.linea.contract.AsyncFriendlyTransactionManager import net.consensys.linea.contract.Web3JContractAsyncHelper @@ -37,7 +37,7 @@ class Web3JLineaRollupSmartContractClient internal constructor( contractGasProvider, smartContractErrors ), - private val web3jLineaClient: LineaRollupV5 = LineaRollupEnhancedWrapper( + private val web3jLineaClient: LineaRollupV6 = LineaRollupEnhancedWrapper( contractAddress, web3j, asyncTransactionManager, @@ -155,7 +155,6 @@ class Web3JLineaRollupSmartContractClient internal constructor( version, aggregation, aggregationLastBlob, - parentShnarf, parentL1RollingHash, parentL1RollingHashMessageNumber ) @@ -180,7 +179,6 @@ class Web3JLineaRollupSmartContractClient internal constructor( version, aggregation, aggregationLastBlob, - parentShnarf, parentL1RollingHash, parentL1RollingHashMessageNumber ) diff --git a/coordinator/ethereum/blob-submitter/src/integrationTest/kotlin/net/consensys/zkevm/ethereum/finalization/BlobAndAggregationFinalizationIntTest.kt b/coordinator/ethereum/blob-submitter/src/integrationTest/kotlin/net/consensys/zkevm/ethereum/finalization/BlobAndAggregationFinalizationIntTest.kt index 88876b55..abc11db3 100644 --- a/coordinator/ethereum/blob-submitter/src/integrationTest/kotlin/net/consensys/zkevm/ethereum/finalization/BlobAndAggregationFinalizationIntTest.kt +++ b/coordinator/ethereum/blob-submitter/src/integrationTest/kotlin/net/consensys/zkevm/ethereum/finalization/BlobAndAggregationFinalizationIntTest.kt @@ -70,7 +70,7 @@ class BlobAndAggregationFinalizationIntTest : CleanDbTestSuiteParallel() { vertx: Vertx, smartContractVersion: LineaContractVersion ) { - if (listOf(LineaContractVersion.V5, LineaContractVersion.V6).contains(smartContractVersion).not()) { + if (listOf(LineaContractVersion.V6).contains(smartContractVersion).not()) { // V6 with prover V3 is soon comming, so we will need to update/extend this test setup throw IllegalArgumentException("unsupported contract version=$smartContractVersion!") } @@ -99,13 +99,13 @@ class BlobAndAggregationFinalizationIntTest : CleanDbTestSuiteParallel() { ) aggregationsRepository = AggregationsRepositoryImpl(PostgresAggregationsDao(sqlClient, fakeClock)) - val lineaRollupContractForDataSubmissionV5 = rollupDeploymentResult.rollupOperatorClient + val lineaRollupContractForDataSubmissionV6 = rollupDeploymentResult.rollupOperatorClient val acceptedBlobEndBlockNumberConsumer = Consumer { acceptedBlob = it } @Suppress("DEPRECATION") val alreadySubmittedBlobFilter = L1ShnarfBasedAlreadySubmittedBlobsFilter( - lineaRollup = lineaRollupContractForDataSubmissionV5, + lineaRollup = lineaRollupContractForDataSubmissionV6, acceptedBlobEndBlockNumberConsumer = acceptedBlobEndBlockNumberConsumer ) val blobSubmittedEventConsumers = mapOf( @@ -123,7 +123,7 @@ class BlobAndAggregationFinalizationIntTest : CleanDbTestSuiteParallel() { ), blobsRepository = blobsRepository, aggregationsRepository = aggregationsRepository, - lineaSmartContractClient = lineaRollupContractForDataSubmissionV5, + lineaSmartContractClient = lineaRollupContractForDataSubmissionV6, alreadySubmittedBlobsFilter = alreadySubmittedBlobFilter, gasPriceCapProvider = FakeGasPriceCapProvider(), blobSubmittedEventDispatcher = EventDispatcher(blobSubmittedEventConsumers), @@ -208,15 +208,6 @@ class BlobAndAggregationFinalizationIntTest : CleanDbTestSuiteParallel() { }.whenException(testContext::failNow) } - @Test - @Timeout(3, timeUnit = TimeUnit.MINUTES) - fun `submission works with contract V5`( - vertx: Vertx, - testContext: VertxTestContext - ) { - testSubmission(vertx, testContext, LineaContractVersion.V5) - } - @Test @Timeout(3, timeUnit = TimeUnit.MINUTES) fun `submission works with contract V6`( diff --git a/coordinator/ethereum/message-anchoring/src/integrationTest/kotlin/net.consensys.zkevm.ethereum.coordination.messageanchoring/L1EventQuerierIntegrationTest.kt b/coordinator/ethereum/message-anchoring/src/integrationTest/kotlin/net.consensys.zkevm.ethereum.coordination.messageanchoring/L1EventQuerierIntegrationTest.kt index c4347a2e..37e17a16 100644 --- a/coordinator/ethereum/message-anchoring/src/integrationTest/kotlin/net.consensys.zkevm.ethereum.coordination.messageanchoring/L1EventQuerierIntegrationTest.kt +++ b/coordinator/ethereum/message-anchoring/src/integrationTest/kotlin/net.consensys.zkevm.ethereum.coordination.messageanchoring/L1EventQuerierIntegrationTest.kt @@ -1,6 +1,6 @@ package net.consensys.zkevm.ethereum.coordination.messageanchoring -import build.linea.contract.LineaRollupV5 +import build.linea.contract.LineaRollupV6 import build.linea.contract.l1.LineaContractVersion import io.vertx.core.Vertx import io.vertx.junit5.Timeout @@ -37,7 +37,7 @@ class L1EventQuerierIntegrationTest { @BeforeEach fun beforeEach() { val deploymentResult = ContractsManager.get() - .deployLineaRollup(contractVersion = LineaContractVersion.V5) + .deployLineaRollup(contractVersion = LineaContractVersion.V6) .get() testLineaRollupContractAddress = deploymentResult.contractAddress web3Client = Web3jClientManager.l1Client @@ -82,9 +82,9 @@ class L1EventQuerierIntegrationTest { contract.sendMessage(it.recipient, it.fee, it.calldata, it.value).sendAsync() .thenApply { receipt -> Pair( - LineaRollupV5.getMessageSentEventFromLog( + LineaRollupV6.getMessageSentEventFromLog( receipt.logs.first { log -> - log.topics.contains(EventEncoder.encode(LineaRollupV5.MESSAGESENT_EVENT)) + log.topics.contains(EventEncoder.encode(LineaRollupV6.MESSAGESENT_EVENT)) } ), receipt @@ -103,9 +103,9 @@ class L1EventQuerierIntegrationTest { contract.sendMessage(it.recipient, it.fee, it.calldata, it.value).sendAsync() .thenApply { receipt -> Pair( - LineaRollupV5.getMessageSentEventFromLog( + LineaRollupV6.getMessageSentEventFromLog( receipt.logs.first { log -> - log.topics.contains(EventEncoder.encode(LineaRollupV5.MESSAGESENT_EVENT)) + log.topics.contains(EventEncoder.encode(LineaRollupV6.MESSAGESENT_EVENT)) } ), receipt @@ -159,10 +159,10 @@ class L1EventQuerierIntegrationTest { contract.sendMessage(it.recipient, it.fee, it.calldata, it.value).sendAsync() .thenApply { receipt -> Pair( - LineaRollupV5.staticExtractEventParameters( - LineaRollupV5.MESSAGESENT_EVENT, + LineaRollupV6.staticExtractEventParameters( + LineaRollupV6.MESSAGESENT_EVENT, receipt.logs.first { log -> - log.topics.contains(EventEncoder.encode(LineaRollupV5.MESSAGESENT_EVENT)) + log.topics.contains(EventEncoder.encode(LineaRollupV6.MESSAGESENT_EVENT)) } ), receipt diff --git a/coordinator/ethereum/message-anchoring/src/integrationTest/kotlin/net.consensys.zkevm.ethereum.coordination.messageanchoring/MessageServiceIntegrationTest.kt b/coordinator/ethereum/message-anchoring/src/integrationTest/kotlin/net.consensys.zkevm.ethereum.coordination.messageanchoring/MessageServiceIntegrationTest.kt index 13493133..78b3edd6 100644 --- a/coordinator/ethereum/message-anchoring/src/integrationTest/kotlin/net.consensys.zkevm.ethereum.coordination.messageanchoring/MessageServiceIntegrationTest.kt +++ b/coordinator/ethereum/message-anchoring/src/integrationTest/kotlin/net.consensys.zkevm.ethereum.coordination.messageanchoring/MessageServiceIntegrationTest.kt @@ -1,6 +1,6 @@ package net.consensys.zkevm.ethereum.coordination.messageanchoring -import build.linea.contract.LineaRollupV5 +import build.linea.contract.LineaRollupV6 import build.linea.contract.l1.LineaContractVersion import io.vertx.core.Vertx import io.vertx.junit5.Timeout @@ -49,7 +49,7 @@ class MessageServiceIntegrationTest { private fun deployContracts() { val l1RollupDeploymentResult = ContractsManager.get() - .deployLineaRollup(contractVersion = LineaContractVersion.V5) + .deployLineaRollup(contractVersion = LineaContractVersion.V6) .get() @Suppress("DEPRECATION") l1ContractLegacyClient = l1RollupDeploymentResult.rollupOperatorClientLegacy @@ -202,10 +202,10 @@ class MessageServiceIntegrationTest { .toSafeFuture() .thenApply { transactionReceipt -> log.debug("Message has been sent in block {}", transactionReceipt.blockNumber) - val eventValues = LineaRollupV5.staticExtractEventParameters( - LineaRollupV5.MESSAGESENT_EVENT, + val eventValues = LineaRollupV6.staticExtractEventParameters( + LineaRollupV6.MESSAGESENT_EVENT, transactionReceipt.logs.first { log -> - log.topics.contains(EventEncoder.encode(LineaRollupV5.MESSAGESENT_EVENT)) + log.topics.contains(EventEncoder.encode(LineaRollupV6.MESSAGESENT_EVENT)) } ) MessageSentResult( diff --git a/coordinator/ethereum/message-anchoring/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/messageanchoring/L1EventQuerierImpl.kt b/coordinator/ethereum/message-anchoring/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/messageanchoring/L1EventQuerierImpl.kt index da8b339b..28d831eb 100644 --- a/coordinator/ethereum/message-anchoring/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/messageanchoring/L1EventQuerierImpl.kt +++ b/coordinator/ethereum/message-anchoring/src/main/kotlin/net/consensys/zkevm/ethereum/coordination/messageanchoring/L1EventQuerierImpl.kt @@ -1,6 +1,6 @@ package net.consensys.zkevm.ethereum.coordination.messageanchoring -import build.linea.contract.LineaRollupV5 +import build.linea.contract.LineaRollupV6 import io.vertx.core.Vertx import net.consensys.linea.async.toSafeFuture import net.consensys.toULong @@ -24,10 +24,10 @@ class L1EventQuerierImpl( private val l1Web3jClient: Web3j ) : L1EventQuerier { companion object { - val encodedMessageSentEvent: String = EventEncoder.encode(LineaRollupV5.MESSAGESENT_EVENT) + val encodedMessageSentEvent: String = EventEncoder.encode(LineaRollupV6.MESSAGESENT_EVENT) fun parseMessageSentEventLogs(log: Log): SendMessageEvent { - val messageSentEvent = LineaRollupV5.getMessageSentEventFromLog(log) + val messageSentEvent = LineaRollupV6.getMessageSentEventFromLog(log) return SendMessageEvent( Bytes32.wrap(messageSentEvent._messageHash), messageSentEvent._nonce.toULong(), diff --git a/coordinator/ethereum/message-anchoring/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/messageanchoring/L1EventQuerierImplTest.kt b/coordinator/ethereum/message-anchoring/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/messageanchoring/L1EventQuerierImplTest.kt index 140d5c8a..e2e9cd62 100644 --- a/coordinator/ethereum/message-anchoring/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/messageanchoring/L1EventQuerierImplTest.kt +++ b/coordinator/ethereum/message-anchoring/src/test/kotlin/net/consensys/zkevm/ethereum/coordination/messageanchoring/L1EventQuerierImplTest.kt @@ -1,6 +1,6 @@ package net.consensys.zkevm.ethereum.coordination.messageanchoring -import build.linea.contract.LineaRollupV5 +import build.linea.contract.LineaRollupV6 import io.vertx.core.Vertx import io.vertx.junit5.Timeout import io.vertx.junit5.VertxExtension @@ -603,7 +603,7 @@ class L1EventQuerierImplTest { private fun createRandomSendEvent(blockNumber: String, logIndex: String): LogResult { val log = Log() - val eventSignature: String = EventEncoder.encode(LineaRollupV5.MESSAGESENT_EVENT) + val eventSignature: String = EventEncoder.encode(LineaRollupV6.MESSAGESENT_EVENT) val messageHashValue = Bytes32.random() val messageHash = org.web3j.abi.datatypes.generated.Bytes32(messageHashValue.toArray()) diff --git a/coordinator/ethereum/test-utils/src/main/kotlin/net/consensys/zkevm/ethereum/ContractsManager.kt b/coordinator/ethereum/test-utils/src/main/kotlin/net/consensys/zkevm/ethereum/ContractsManager.kt index f83c8a74..ab51cc60 100644 --- a/coordinator/ethereum/test-utils/src/main/kotlin/net/consensys/zkevm/ethereum/ContractsManager.kt +++ b/coordinator/ethereum/test-utils/src/main/kotlin/net/consensys/zkevm/ethereum/ContractsManager.kt @@ -57,7 +57,7 @@ interface ContractsManager { fun deployRollupAndL2MessageService( dataCompressionAndProofAggregationMigrationBlock: ULong = 1000UL, numberOfOperators: Int = 1, - l1ContractVersion: LineaContractVersion = LineaContractVersion.V5 + l1ContractVersion: LineaContractVersion = LineaContractVersion.V6 ): SafeFuture fun connectToLineaRollupContract( diff --git a/coordinator/ethereum/test-utils/src/main/kotlin/net/consensys/zkevm/ethereum/MakefileContractDeploymentHelper.kt b/coordinator/ethereum/test-utils/src/main/kotlin/net/consensys/zkevm/ethereum/MakefileContractDeploymentHelper.kt index 5f0c5507..428d9a0d 100644 --- a/coordinator/ethereum/test-utils/src/main/kotlin/net/consensys/zkevm/ethereum/MakefileContractDeploymentHelper.kt +++ b/coordinator/ethereum/test-utils/src/main/kotlin/net/consensys/zkevm/ethereum/MakefileContractDeploymentHelper.kt @@ -77,7 +77,6 @@ fun makeDeployLineaRollup( ) deploymentPrivateKey?.let { env["DEPLOYMENT_PRIVATE_KEY"] = it } val command = when (contractVersion) { - LineaContractVersion.V5 -> "make deploy-linea-rollup-v5" LineaContractVersion.V6 -> "make deploy-linea-rollup-v6" else -> throw IllegalArgumentException("Unsupported contract version: $contractVersion") } @@ -118,7 +117,7 @@ fun main() { makeDeployLineaRollup( L1AccountManager.generateAccount().privateKey, listOf("03dfa322A95039BB679771346Ee2dBfEa0e2B773"), - LineaContractVersion.V5 + LineaContractVersion.V6 ), makeDeployL2MessageService( L2AccountManager.generateAccount().privateKey, diff --git a/coordinator/ethereum/test-utils/src/test/kotlin/net/consensys/zkevm/ethereum/MakefileContractDeploymentHelperKtTest.kt b/coordinator/ethereum/test-utils/src/test/kotlin/net/consensys/zkevm/ethereum/MakefileContractDeploymentHelperKtTest.kt index 270b1a61..aa3b1b15 100644 --- a/coordinator/ethereum/test-utils/src/test/kotlin/net/consensys/zkevm/ethereum/MakefileContractDeploymentHelperKtTest.kt +++ b/coordinator/ethereum/test-utils/src/test/kotlin/net/consensys/zkevm/ethereum/MakefileContractDeploymentHelperKtTest.kt @@ -52,8 +52,8 @@ class MakefileContractDeploymentHelperKtTest { assertThat( getDeployedAddress( listOf( - "LineaRollupV5.2.1 artifact has been deployed in 1.855172125s ", - "contract=LineaRollupV5.2.1 deployed: address=0x8613180dF1485B8b87DEE3BCf31896659eb1a092 blockNumber=1414", + "LineaRollup6.2.1 artifact has been deployed in 1.855172125s ", + "contract=LineaRollupV6.2.1 deployed: address=0x8613180dF1485B8b87DEE3BCf31896659eb1a092 blockNumber=1414", "" ), lineaRollupAddressPattern diff --git a/jvm-libs/linea/clients/interfaces/src/main/kotlin/build/linea/contract/l1/LineaRollupSmartContractClient.kt b/jvm-libs/linea/clients/interfaces/src/main/kotlin/build/linea/contract/l1/LineaRollupSmartContractClient.kt index a7934683..0544afd9 100644 --- a/jvm-libs/linea/clients/interfaces/src/main/kotlin/build/linea/contract/l1/LineaRollupSmartContractClient.kt +++ b/jvm-libs/linea/clients/interfaces/src/main/kotlin/build/linea/contract/l1/LineaRollupSmartContractClient.kt @@ -4,7 +4,6 @@ import net.consensys.linea.BlockParameter import tech.pegasys.teku.infrastructure.async.SafeFuture enum class LineaContractVersion : Comparable { - V5, // "EIP4844 multiple blobs per tx support - version in all networks" V6 // more efficient data submission and new events for state recovery } diff --git a/jvm-libs/linea/clients/linea-l1-contract-client/src/main/kotlin/build/linea/contract/l1/Web3JLineaRollupSmartContractClientReadOnly.kt b/jvm-libs/linea/clients/linea-l1-contract-client/src/main/kotlin/build/linea/contract/l1/Web3JLineaRollupSmartContractClientReadOnly.kt index 34c05fae..b3df1dcf 100644 --- a/jvm-libs/linea/clients/linea-l1-contract-client/src/main/kotlin/build/linea/contract/l1/Web3JLineaRollupSmartContractClientReadOnly.kt +++ b/jvm-libs/linea/clients/linea-l1-contract-client/src/main/kotlin/build/linea/contract/l1/Web3JLineaRollupSmartContractClientReadOnly.kt @@ -1,6 +1,5 @@ package build.linea.contract.l1 -import build.linea.contract.LineaRollupV5 import build.linea.contract.LineaRollupV6 import net.consensys.encodeHex import net.consensys.linea.BlockParameter @@ -34,8 +33,8 @@ open class Web3JLineaRollupSmartContractClientReadOnly( private val log: Logger = LogManager.getLogger(Web3JLineaRollupSmartContractClientReadOnly::class.java) ) : LineaRollupSmartContractClientReadOnly { - protected fun contractClientAtBlock(blockParameter: BlockParameter): LineaRollupV5 { - return contractClientAtBlock(blockParameter, LineaRollupV5::class.java) + protected fun contractClientAtBlock(blockParameter: BlockParameter): LineaRollupV6 { + return contractClientAtBlock(blockParameter, LineaRollupV6::class.java) } protected fun contractClientAtBlock(blockParameter: BlockParameter, contract: Class): T { @@ -49,16 +48,6 @@ open class Web3JLineaRollupSmartContractClientReadOnly( ).apply { this.setDefaultBlockParameter(blockParameter.toWeb3j()) } - - LineaRollupV5::class.java.isAssignableFrom(contract) -> LineaRollupV5.load( - contractAddress, - web3j, - fakeCredentials, - StaticGasProvider(BigInteger.ZERO, BigInteger.ZERO) - ).apply { - this.setDefaultBlockParameter(blockParameter.toWeb3j()) - } - else -> throw IllegalArgumentException("Unsupported contract type: ${contract::class.java}") } as T } @@ -101,7 +90,7 @@ open class Web3JLineaRollupSmartContractClientReadOnly( if (error.cause is ContractCallException) { // means that contract does not have CONTRACT_VERSION method available yet // so it is still V5, so defaulting to V5 - SafeFuture.completedFuture(LineaContractVersion.V5) + SafeFuture.completedFuture(LineaContractVersion.V6) } else { SafeFuture.failedFuture(error) } @@ -134,10 +123,10 @@ open class Web3JLineaRollupSmartContractClientReadOnly( override fun isBlobShnarfPresent(blockParameter: BlockParameter, shnarf: ByteArray): SafeFuture { return getVersion() .thenCompose { version -> - if (version == LineaContractVersion.V5) { - contractClientAtBlock(blockParameter, LineaRollupV5::class.java).shnarfFinalBlockNumbers(shnarf) - } else { - contractClientAtBlock(blockParameter, LineaRollupV6::class.java).blobShnarfExists(shnarf) + when (version!!) { + LineaContractVersion.V6 -> contractClientAtBlock(blockParameter, LineaRollupV6::class.java).blobShnarfExists( + shnarf + ) } .sendAsync() .thenApply { it != BigInteger.ZERO } diff --git a/jvm-libs/linea/linea-contracts/l1-rollup/build.gradle b/jvm-libs/linea/linea-contracts/l1-rollup/build.gradle index 257d66ec..c813e7c4 100644 --- a/jvm-libs/linea/linea-contracts/l1-rollup/build.gradle +++ b/jvm-libs/linea/linea-contracts/l1-rollup/build.gradle @@ -20,11 +20,9 @@ dependencies { web3jContractWrappers { def contractsDir = layout.buildDirectory.dir("${rootProject.projectDir}/contracts/abi").get() def contractV6Abi = contractsDir.file("LineaRollupV6.0.abi").asFile.absolutePath - def contractV5Abi = contractsDir.file("LineaRollupV5.0.abi").asFile.absolutePath contractsPackage = "build.linea.contract" contracts = [ - "$contractV5Abi": "LineaRollupV5", "$contractV6Abi": "LineaRollupV6" ] }