{
"missing": {
"nextStage": "Stage 1",
"requirements": [
"Users' withdrawals can be censored by the permissioned operators.",
"Upgrades executed by actors with more centralized control than a Security Council provide less than 7d for users to exit if the permissioned operator is down or censoring.",
"The Security Council is not properly set up."
],
"principle": "Compromising ≥75% of the Security Council should be the only way (other than bugs) for a rollup to indefinitely block an L2→L1 message (e.g. a withdrawal) or push an invalid L2→L1 message (e.g. an invalid withdrawal) with a <7d exit window."
},
"stage": "Stage 0",
"summary": [
{
"stage": "Stage 0",
"requirements": [
{
"satisfied": true,
"description": "A complete and functional proof system is deployed."
},
{
"satisfied": true,
"description": "There are at least 5 external actors who can submit fraud proofs."
},
{
"satisfied": true,
"description": "The project calls itself a rollup."
},
{
"satisfied": true,
"description": "State roots are posted to Ethereum L1."
},
{
"satisfied": true,
"description": "Inputs for the state transition function are posted to Ethereum L1."
},
{
"satisfied": true,
"description": "A source-available node exists that can recreate the state from Ethereum L1 data. Please note that the L2BEAT team has not verified the validity of the node source code. [View code](https://github.com/morph-l2/run-morph-node)"
}
]
},
{
"stage": "Stage 1",
"requirements": [
{
"satisfied": false,
"description": "Users' withdrawals can be censored by the permissioned operators."
},
{
"satisfied": false,
"description": "Upgrades executed by actors with more centralized control than a Security Council provide less than 7d for users to exit if the permissioned operator is down or censoring."
},
{
"satisfied": false,
"description": "The Security Council is not properly set up."
},
{
"satisfied": true,
"description": "The proof system meets the minimum trusted setup requirements defined in the L2BEAT [trusted setup assessment framework](https://forum.l2beat.com/t/the-trusted-setups-framework-for-zk-catalog/381).",
"upcoming": true
},
{
"satisfied": true,
"description": "Prover source code is published.",
"upcoming": true
},
{
"satisfied": false,
"description": "Not all onchain verifiers' smart contracts can be independently regenerated from the verifier source code.",
"upcoming": true
},
{
"satisfied": true,
"description": "The sources of all programs used are public and program hashes can be independently regenerated.",
"upcoming": true
}
],
"principle": {
"satisfied": false,
"description": "Compromising ≥75% of the Security Council should be the only way (other than bugs) for a rollup to indefinitely block an L2→L1 message (e.g. a withdrawal) or push an invalid L2→L1 message (e.g. an invalid withdrawal) with a <7d exit window."
}
},
{
"stage": "Stage 2",
"requirements": [
{
"satisfied": false,
"description": "Fraud proof submission is open only to whitelisted actors."
},
{
"satisfied": false,
"description": "Upgrades unrelated to onchain provable bugs provide less than 30d to exit."
},
{
"satisfied": false,
"description": "The Security Council's actions are not confined to onchain provable bugs."
}
]
}
]
}
scalingRisks+7-7
{
"self": {
"stateValidation": {
"value": "Fraud proofs (1R, ZK)",
"description": "Fraud proofs allow actors watching the chain to prove that the state is incorrect. Single round proofs (1R) only require a single transaction to resolve. ZK proofs are used to prove the correctness of the state transition. The system currently operates with at least 5 whitelisted challengers external to the team.",
"sentiment": "warning",
"orderHint": null,
"challengeDelay": 172800,
"initialBond": "1.0",
"secondLine": "2d challenge period"
},
"dataAvailability": {
"value": "Onchain",
"description": "All of the data needed for proof construction is published on Ethereum L1.",
"sentiment": "good",
"orderHint": null
},
"exitWindow": {
"value": "None",
"description": "There is no window for users to exit in case of an unwanted regular upgrade since contracts are instantly upgradable.",
"sentiment": "bad",
"orderHint": 0
},
"sequencerFailure": {
"value": "Enqueue via L1",
"description": "Users can force the sequencer to include a transaction by submitting a request through L1. If the sequencer censors for 7d, any new proposal must include at least 1 transaction from the queue. Self-proposing is not possible if the sequencer is down.",
"sentiment": "warning",
"value": "Force via L1",
"description": "Users can force the sequencer to include a transaction by submitting a request through L1. If the sequencer censors or is down for 7d, new L1 batches must include at least 1 transaction from the queue.",
"sentiment": "good",
"orderHint": 604800
},
"proposerFailure": {
"value": "Cannot withdraw",
"description": "Only the whitelisted proposers can publish state roots on L1, so in the event of failure the withdrawals are frozen.",
"sentiment": "bad",
"orderHint": null
"value": "Self propose",
"description": "Anyone can become a Proposer after 7d of inactivity from the currently whitelisted Proposers. This requires using the source-available prover to submit a zk proof of validity for the proposal.",
"sentiment": "good",
"orderHint": 604800
}
}
}
scalingTechnology+10-24
{
"dataAvailability": [
{
"name": "All data required for proofs is published on chain",
"description": "All the data that is used to construct the system state is published on chain in the form of cheap blobs or calldata. This ensures that it will be available for enough time.",
"risks": [],
"references": [
{
"title": "Rollup.sol - Etherscan source code commitBatch() and commitBatchWithBlobProof() functions",
"url": "https://etherscan.io/address/0x759894Ced0e6af42c26668076Ffa84d02E3CeF60#code"
}
]
}
],
"exitMechanisms": [
{
"name": "Regular messaging",
"description": "The user initiates L2->L1 messages by submitting a regular transaction on this chain. When the block containing that transaction is settled, the message becomes available for processing on L1. The process of block finalization takes a challenge period of 2d to complete.",
"risks": [
{
"category": "Funds can be frozen if",
"text": "the operator censors withdrawal transaction."
}
],
"risks": [],
"references": [
{
"title": "L1ETHGateway.sol - Etherscan source code, finalizeWithdrawETH function",
"url": "https://etherscan.io/address/0x63eeCb6bE6087B094c2CBAA34f2902593eAE979c#code"
}
]
}
],
"forceTransactions": {
"name": "Users can enqueue transactions",
"description": "Users can force the sequencer to include a transaction by submitting a request through L1. If the sequencer censors for 7d, any new proposal must include at least 1 transaction from the queue. Self-proposing is not possible if the sequencer is down.",
"risks": [
{
"category": "Users can be censored if",
"text": "the operator is offline."
}
],
"name": "Users can force transactions",
"description": "Users can force the sequencer to include a transaction by submitting a request through L1. If the sequencer censors such a request or is down for 7d, any new proposal must include at least 1 transaction from the queue. Proposing is permissionless under these conditions if proven immediately.",
"risks": [],
"references": [
{
"title": "EnforcedTxGateway proxy - PAUSED - Etherscan source code",
"url": "https://etherscan.io/address//0xc5Fa3b8968c7FAbEeA2B530a20b88d0C2eD8abb7#readProxyContract#F7"
},
{
"title": "EnforcedTxGateway.sol implementation - Etherscan source code",
"url": "https://etherscan.io/address/0xCb13746Fc891fC2e7D824870D00a26F43fE6123e#code"
},
{
"title": "Rollup.sol - Sequencer decides if / how many transactions to dequeue",
"url": "https://etherscan.io/address/0x1320d6A438d268044c8EEff0eE6B24E5EC9584e3#code#F1#L678"
}
]
},
"operator": {
"name": "Morph uses a decentralised sequencer network",
"description": "The system uses a decentralised sequencer/proposer network. At the moment all sequencers are run by Morph and - from the point of Ethereum - they don't need to reach consensus on a block as any one of them can propose a block with an L2 state root on Ethereum. There is a plan to use tendermint with BLS signatures to verify consensus after Petra upgrade.",
"name": "Decentralised sequencer network",
"description": "BLS signatures of the Sequencers are not verified onchain. Sequencing is centralized an permissioned to the listed sequencers in practice.",
"references": [
{
"title": "L1Staking.sol - Etherscan source code, verifySignature() function",
"url": "https://etherscan.io/address/0xDb0734109051DaAB5c32E45e9a5ad0548B2df714#code"
"title": "L1Staking.sol - Etherscan source code, verifySignature() stub",
"url": "https://etherscan.io/address/0xDb0734109051DaAB5c32E45e9a5ad0548B2df714#code#F1#L340"
}
],
"risks": [
{
"category": "MEV can be extracted if",
"text": "the operator exploits their centralized position and frontruns user transactions."
}
]
},
"stateValidation": {
"categories": [
{
"title": "Fraud proofs",
"description": "Morph uses a one round fault proof system where whitelisted Challengers, if they find a faulty state root within the 2d challenge window, can post a 1 WEI bond and request a ZK proof of the state transition. At least 5 Challengers are operated by entities external to the team. After the challenge, during a 3d proving window, a ZK proof must be delivered, otherwise the state root is considered invalid and the root proposer bond, which is currently set to 1 ETH, is slashed. The zkVM used is SP1 from Succinct. If the valid proof is delivered, the Challenger loses the challenge bond. The Morph Multisig can revert unfinalized batches.",
"description": "Morph uses a one round fault proof system where whitelisted Challengers, if they find a faulty state root within the 2d challenge window, can post a 1 WEI bond and request a ZK proof of the state transition. At least 5 Challengers are operated by entities external to the team. After the challenge, during a 3d proving window, a ZK proof must be delivered, otherwise the state root is considered invalid and the root proposer bond, which is currently set to 1 ETH, is slashed. The zkVM used is SP1 by Succinct. If a valid proof is delivered, the Challenger loses the challenge bond. The Morph Multisig can revert unfinalized batches.",
"references": [
{
"title": "Whitelisted Challengers - Morph Docs",
"url": "https://docs.morphl2.io/docs/how-morph-works/optimistic-zkevm/#challenger-address-list"
},
{
"title": "Rollup.sol - Etherscan source code, commitBatch(), challengeState(), proveState() functions",
"url": "https://etherscan.io/address/0x1320d6A438d268044c8EEff0eE6B24E5EC9584e3"
"url": "https://etherscan.io/address/0xB2F539aede77DF4cD1d427d046bBbBd8dB4cBAAF"
}
],
"risks": [
{
"category": "Funds can be stolen if",
"text": "no whitelisted challenger posts a challenge for an incorrect state root."
}
]
}
]
}
}
contracts+9-2
{
"addresses": {
"ethereum": [
{
"name": "ZkEvmVerifierV1",
"isVerified": true,
"address": "eth:0x045d4BC73Bd1918192f34e98532A5272Ef620423",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "A snark verifier based on SP1 by Succinct. It verifies RISC-V execution in a PLONK proof. Used to verify the validity of L2 state transitions for single round fraud proofs.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x045d4BC73Bd1918192f34e98532A5272Ef620423#code"
},
{
"name": "L1ETHGateway",
"isVerified": true,
"address": "eth:0x1C1Ffb5828c3A48B54E8910F1c75256a498aDE68",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x31110622D6CA24c9FF307d6ae1715F16E47F16A0"
],
"implementations": [
"eth:0x63eeCb6bE6087B094c2CBAA34f2902593eAE979c"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1729307603,
"transactionHash": "0x2054355788d3d4ae212cb29348eee2664d126305b4ace5fe2269871cd9165713",
"implementations": [
"eth:0x98dF320641C2E65ab4BbeF1e6f6C66D9B50EdE5F"
]
},
{
"timestamp": 1729341335,
"transactionHash": "0x0bff29c5d35495d0e9c22547b91c8e9e468edbfa2e8ccf1872de99a9f06e63ef",
"implementations": [
"eth:0x63eeCb6bE6087B094c2CBAA34f2902593eAE979c"
]
}
],
"description": "Contract used to bridge ETH from L1 to L2.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1",
"upgradableBy": [
{
"name": "Morph Multisig 1",
"delay": "no"
}
],
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x1C1Ffb5828c3A48B54E8910F1c75256a498aDE68#code"
},
{
"name": "ProxyAdmin",
"isVerified": true,
"address": "eth:0x31110622D6CA24c9FF307d6ae1715F16E47F16A0",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "* Roles:\n * **owner**: TimelockController",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x31110622D6CA24c9FF307d6ae1715F16E47F16A0#code"
},
{
"name": "L1MessageQueueWithGasPriceOracle",
"isVerified": true,
"address": "eth:0x3931Ade842F5BB8763164bDd81E5361DcE6cC1EF",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x31110622D6CA24c9FF307d6ae1715F16E47F16A0"
],
"implementations": [
"eth:0xf3b7724334cb0aDBC49CAC90e166Af99C07Be6aa"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1729307207,
"transactionHash": "0xed442ee7f96c1151761ddca9e4b923adff4e0703bc9ae42ca30bf4356f195f5d",
"implementations": [
"eth:0x98dF320641C2E65ab4BbeF1e6f6C66D9B50EdE5F"
]
},
{
"timestamp": 1729330799,
"transactionHash": "0xae27c6c83cea4ce8b8a923fddfb122f66e63139e514ba0624a5373b1a1f2829c",
"implementations": [
"eth:0x828F68e2E05a34fA836416F124350E25021876ac"
]
},
{
"timestamp": 1736755919,
"transactionHash": "0x60cc38cb058516da361ecd5f548fc9216fbcda9eb08255b529ebbf78dac44f7b",
"implementations": [
"eth:0xa3b5bFB885FF92EB8445f262c289548e77c3c0aA"
]
},
{
"timestamp": 1772517791,
"transactionHash": "0x29632a0458dbc5cbad5e831228a54c118e8e0746bff06fcf151cad568079a318",
"implementations": [
"eth:0xf3b7724334cb0aDBC49CAC90e166Af99C07Be6aa"
]
}
],
"description": "Contains the array of queued L1 -> L2 messages, either appended using the L1Messenger or the EnforcedTxGateway.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1",
"upgradableBy": [
{
"name": "Morph Multisig 1",
"delay": "no"
}
],
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x3931Ade842F5BB8763164bDd81E5361DcE6cC1EF#code"
},
{
"name": "L1StandardERC20Gateway",
"isVerified": true,
"address": "eth:0x44c28f61A5C2Dd24Fc71D7Df8E85e18af4ab2Bd8",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x31110622D6CA24c9FF307d6ae1715F16E47F16A0"
],
"implementations": [
"eth:0x75BC012fA81DF052baFc4EF9255Af29B6C4e5301"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1729307651,
"transactionHash": "0x588ba3041901915cf5dda72776946664559ea839ead325836697c3d6764608b4",
"implementations": [
"eth:0x98dF320641C2E65ab4BbeF1e6f6C66D9B50EdE5F"
]
},
{
"timestamp": 1729341383,
"transactionHash": "0xecc550f05d2956f7b7782408e784270c2dd858fd1add437f7292309f9be0795e",
"implementations": [
"eth:0x75BC012fA81DF052baFc4EF9255Af29B6C4e5301"
]
}
],
"description": "Contract used to bridge ERC20 tokens from L1 to L2. It uses a fixed token list.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1",
"upgradableBy": [
{
"name": "Morph Multisig 1",
"delay": "no"
}
],
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x44c28f61A5C2Dd24Fc71D7Df8E85e18af4ab2Bd8#code"
},
{
"name": "TimelockController",
"isVerified": true,
"address": "eth:0x542675E90E269F20ecbb9e0095d4751ac155B530",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x8654061457582c867B77A3a9f4ca714dFc84Ec17"
],
"implementations": [
"eth:0x5F0CAaf0d3b8dd8eA9f80CDbb0021930d3c17353"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1770779267,
"transactionHash": "0x8758e296217ea0a7f75403d57eb75eaa7067a45dd1b9cfc070e7fb1c1d9f6554",
"implementations": [
"eth:0x5F0CAaf0d3b8dd8eA9f80CDbb0021930d3c17353"
]
}
],
"description": "A timelock with access control. The current minimum delay is 0s.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1\n * **canceller**: Morph Multisig 2\n * **defaultAdmin**: Morph Multisig 1, TimelockController; ultimately Morph Multisig 1\n * **executor**: Morph Multisig 1\n * **proposer**: Morph Multisig 2",
"upgradableBy": [
{
"name": "Morph Multisig 1",
"delay": "no"
}
],
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x542675E90E269F20ecbb9e0095d4751ac155B530#code"
},
{
"name": "MultipleVersionRollupVerifier",
"isVerified": true,
"address": "eth:0x5d1584c27b4aD233283c6da1ca1B825d6f220EC1",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Used to update the verifier and keep track of current and old versions. Routes to a registered verifier by batch index, so that every batch is verified by the latest verifier that is enabled for this batch.\n* Roles:\n * **owner**: Morph Multisig 2",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x5d1584c27b4aD233283c6da1ca1B825d6f220EC1#code"
},
{
"name": "ZkEvmVerifierV1",
"isVerified": true,
"address": "eth:0x5ff102a4A4Ce2040288a797CE4CCCa85eE1E2d70",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "A snark verifier based on SP1 by Succinct. It verifies RISC-V execution in a PLONK proof. Used to verify the validity of L2 state transitions for single round fraud proofs.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x5ff102a4A4Ce2040288a797CE4CCCa85eE1E2d70#code"
},
{
"name": "L1GatewayRouter",
"isVerified": true,
"address": "eth:0x7497756ADA7e656aE9f00781aF49Fc0fD08f8A8a",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x31110622D6CA24c9FF307d6ae1715F16E47F16A0"
],
"implementations": [
"eth:0x6D9623d44C4A1629815D9d6236FF25C4f82Cc819"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1729307555,
"transactionHash": "0x47781299a90c1fdd6771fbf104e0433f05cc7b610d63ce9368349a41f563b3c8",
"implementations": [
"eth:0x98dF320641C2E65ab4BbeF1e6f6C66D9B50EdE5F"
]
},
{
"timestamp": 1729331927,
"transactionHash": "0xeda36c4631ff08b30a6812f16d35626894001ea8259fe51f1e38fa8ea78d3d37",
"implementations": [
"eth:0x6D9623d44C4A1629815D9d6236FF25C4f82Cc819"
]
}
],
"description": "Main entrypoint for depositing ETH and ERC20 tokens, which are then forwarded to the correct escrow.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1\n * **owner**: Morph Multisig 2",
"upgradableBy": [
{
"name": "Morph Multisig 1",
"delay": "no"
}
],
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x7497756ADA7e656aE9f00781aF49Fc0fD08f8A8a#code"
},
{
"name": "Rollup",
"isVerified": true,
"address": "eth:0x759894Ced0e6af42c26668076Ffa84d02E3CeF60",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x31110622D6CA24c9FF307d6ae1715F16E47F16A0"
],
"implementations": [
"eth:0x1320d6A438d268044c8EEff0eE6B24E5EC9584e3"
"eth:0xB2F539aede77DF4cD1d427d046bBbBd8dB4cBAAF"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1729307507,
"transactionHash": "0xfb3bc602abb088d5d94e6869d56417de3c16a3966e5c6abfa4d157dfbcc36cba",
"implementations": [
"eth:0x98dF320641C2E65ab4BbeF1e6f6C66D9B50EdE5F"
]
},
{
"timestamp": 1729331495,
"transactionHash": "0xeb4cc4248a0b3f459f4d7ab5877114fd4f55fd073c78347df548a9f03013068e",
"implementations": [
"eth:0xcffdDbcb5B9EA2ee45ABA121e0849ADc87c38326"
]
},
{
"timestamp": 1729432115,
"transactionHash": "0xd60de4a76f275ec7931bc430b7440f07c15f30028195405f855bd98c33ad72d6",
"implementations": [
"eth:0x073403E147a8e607b80985fe458c0B527287278F"
]
},
{
"timestamp": 1732765919,
"transactionHash": "0xa452e20183f6860f105cb398bccc9d75dd3758444b956061b3031d1f0a33c424",
"implementations": [
"eth:0xaD900dB30Bcdf84c38Df0067eA327bbEccCF071A"
]
},
{
"timestamp": 1736753519,
"transactionHash": "0x809b1d9bba9fd8f61c038603ddf7a6f0a079db83a4a6d341cf23d2af5764a9be",
"implementations": [
"eth:0x43190DfD1F572Cb56B1942B44482d1774151D77A"
]
},
{
"timestamp": 1747033883,
"transactionHash": "0x1cd98e49b0d0c30a39c97683c374f5d3541d1ed02b14272a7113709fe01700d7",
"implementations": [
"eth:0x9C79e8F5d0fE910d84a6a0d4A03E8136d036eBec"
]
},
{
"timestamp": 1764060695,
"transactionHash": "0x27b0e1b46f9878a502c68e414bc6fea028c3a551760e5687c56bdd4eda4f31c9",
"implementations": [
"eth:0xDF0749e688AE74508D84699Ba2405ED610Aaf8c5"
]
},
{
"timestamp": 1772517971,
"transactionHash": "0xc86bc6dc60ad304afbc7f423668a272434c17dbf4a0bb27906d74f0940a6eab1",
"implementations": [
"eth:0x1320d6A438d268044c8EEff0eE6B24E5EC9584e3"
]
},
{
"timestamp": 1774575251,
"transactionHash": "0x8eec835066ebedafa6430fc7b0cd1de2b7a46eb09e56519868ca9dbb938f4c8f",
"implementations": [
"eth:0xB2F539aede77DF4cD1d427d046bBbBd8dB4cBAAF"
]
}
],
"description": "The main contract of the Morph rollup. Allows to post transaction data and state roots and implements the challenge mechanism along with the proof system. Sequencing and proposing are behind a whitelist. If the EnforcedTxGateway is not paused, any sequencer must include at least one L1 -> L2 message in their proposal if the oldest message is > 7d old. Although the contract exposes the external function commitBatchWithProof(), it currently reverts for non-whitelisted actors.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1\n * **challengers**: EOA 1, EOA 10, EOA 11, EOA 13, EOA 14, EOA 15, EOA 16, EOA 18, EOA 19, EOA 2, EOA 20, EOA 21, EOA 22, EOA 23, EOA 24, EOA 25, EOA 26, EOA 27, EOA 28, EOA 3, EOA 30, EOA 31, EOA 32, EOA 33, EOA 34, EOA 35, EOA 36, EOA 37, EOA 38, EOA 4, EOA 40, EOA 41, EOA 42, EOA 5, EOA 6, EOA 8, EOA 9, Morph Multisig 2\n * **owner**: Morph Multisig 2",
"description": "The main contract of the Morph rollup. Allows to post transaction data and state roots and implements the the proof system. Sequencing and proposing are behind a whitelist. If the EnforcedTxGateway is not paused, any sequencer must include at least one L1 -> L2 message in their proposal if the oldest message is > 7d old. If the Sequencers are censoring or down for more than 7d, users can permissionlessly propose and prove via `commitBatchWithProof()`.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1\n * **challengers**: EOA 1, EOA 10, EOA 11, EOA 13, EOA 14, EOA 15, EOA 16, EOA 18, EOA 19, EOA 2, EOA 20, EOA 21, EOA 22, EOA 23, EOA 24, EOA 25, EOA 26, EOA 27, EOA 28, EOA 3, EOA 30, EOA 31, EOA 32, EOA 33, EOA 34, EOA 35, EOA 36, EOA 37, EOA 38, EOA 4, EOA 40, EOA 41, EOA 42, EOA 5, EOA 6, EOA 8, EOA 9, Morph Multisig 2\n * **owner**: Morph Multisig 2",
"upgradableBy": [
{
"name": "Morph Multisig 1",
"delay": "no"
}
],
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x759894Ced0e6af42c26668076Ffa84d02E3CeF60#code"
},
{
"name": "ProxyAdmin",
"isVerified": true,
"address": "eth:0x8654061457582c867B77A3a9f4ca714dFc84Ec17",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "* Roles:\n * **owner**: Morph Multisig 1",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x8654061457582c867B77A3a9f4ca714dFc84Ec17#code"
},
{
"name": "EnforcedTxGateway",
"isVerified": true,
"address": "eth:0xc5Fa3b8968c7FAbEeA2B530a20b88d0C2eD8abb7",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x31110622D6CA24c9FF307d6ae1715F16E47F16A0"
],
"implementations": [
"eth:0xCb13746Fc891fC2e7D824870D00a26F43fE6123e"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1729308143,
"transactionHash": "0x42f9fb783f90953e26e04d4f27a703daa2992362fe44c5e11d646dae054e1e6b",
"implementations": [
"eth:0x98dF320641C2E65ab4BbeF1e6f6C66D9B50EdE5F"
]
},
{
"timestamp": 1729341695,
"transactionHash": "0x52cd27aa90911acebc0bec090cf04928fd3663207dc55381d57c4a47e1dda26a",
"implementations": [
"eth:0xCb13746Fc891fC2e7D824870D00a26F43fE6123e"
]
}
],
"description": "Contracts to force L1 -> L2 messages with the L1 sender. Currently paused: false.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1\n * **owner**: Morph Multisig 2",
"upgradableBy": [
{
"name": "Morph Multisig 1",
"delay": "no"
}
],
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xc5Fa3b8968c7FAbEeA2B530a20b88d0C2eD8abb7#code"
},
{
"name": "L1CrossDomainMessenger",
"isVerified": true,
"address": "eth:0xDc71366EFFA760804DCFC3EDF87fa2A6f1623304",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x31110622D6CA24c9FF307d6ae1715F16E47F16A0"
],
"implementations": [
"eth:0x0cC37d5239F9027A1269f53D83c73084D538f3a9"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1729307111,
"transactionHash": "0xf29bb9908992a7c79573ffb28d3783584653f43095b1b2278fc8951f567bebe7",
"implementations": [
"eth:0x98dF320641C2E65ab4BbeF1e6f6C66D9B50EdE5F"
]
},
{
"timestamp": 1729330715,
"transactionHash": "0x63ce107f943635805762c4ccd98b13cf1977f8ed1e13bd98821ebb545b9ed38e",
"implementations": [
"eth:0xB8F0871bc0832cb756f07fFC4bDdC8b6bf8577b5"
]
},
{
"timestamp": 1736755823,
"transactionHash": "0x908d9fce8cd9a787900543daabf45936a8873b543f593030f3edceeca35543f8",
"implementations": [
"eth:0x0cC37d5239F9027A1269f53D83c73084D538f3a9"
]
}
],
"description": "Contract used to send L1 -> L2 and relay messages from L2. It allows to replay failed messages and to drop skipped messages. L1 -> L2 messages sent using this contract pay for L2 gas on L1 and will have the aliased address of this contract as the sender.\n* Roles:\n * **admin**: ProxyAdmin; ultimately Morph Multisig 1",
"upgradableBy": [
{
"name": "Morph Multisig 1",
"delay": "no"
}
],
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xDc71366EFFA760804DCFC3EDF87fa2A6f1623304#code"
},
{
"name": "Whitelist",
"isVerified": true,
"address": "eth:0xFFafDd9167777C0e5421e0B6789D6d7A5E386984",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Generic whitelist. Currently used to whitelist addresses that can send or relay messages to/from L2 without paying for L2 gas.\n* Roles:\n * **owner**: Morph Multisig 2\n * **whitelisted**: L1Staking",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xFFafDd9167777C0e5421e0B6789D6d7A5E386984#code"
}
]
},
"escrows": [
{
"address": "0xDc71366EFFA760804DCFC3EDF87fa2A6f1623304",
"sinceTimestamp": 1729307111,
"tokens": [
"ETH"
],
"chain": "ethereum",
"chainId": 1
},
{
"address": "0x44c28f61A5C2Dd24Fc71D7Df8E85e18af4ab2Bd8",
"sinceTimestamp": 1729307651,
"tokens": "*",
"chain": "ethereum",
"chainId": 1
},
{
"address": "0xA534BAdd09b4C62B7B1C32C41dF310AA17b52ef1",
"sinceTimestamp": 1729307783,
"tokens": "*",
"chain": "ethereum",
"chainId": 1
},
{
"address": "0xc9045350712A1DCC3A74Eca18Bc985424Bbe7535",
"sinceTimestamp": 1729308239,
"tokens": [
"USDC"
],
"chain": "ethereum",
"chainId": 1
},
{
"address": "0x2C8314f5AADa5D7a9D32eeFebFc43aCCAbe1b289",
"sinceTimestamp": 1729308239,
"tokens": [
"USDC"
],
"chain": "ethereum",
"chainId": 1
}
],
"programHashes": [
{
"title": "Morph Guest program (v0.4.9 release)",
"description": "Proves the correct execution of the Morph L2 state transition function (based on the Geth EVM) for a batch of blocks using the SP1 zkVM.",
"programUrl": "https://github.com/morph-l2/morph/tree/v0.4.9/prover/bin/client",
"proverSystemProject": "sp1turbo",
"verificationStatus": "successful",
"verificationSteps": "\nRebuilding this program vkey requires specific docker image and sp1 version. The docker image requires a linux platform or some emulation workarounds. To prepare:\n\n1. Install cargo make: `cargo install --debug --locked cargo-make`\n2. Install sp1 toolchain v3.4.0: `curl -L https://sp1up.succinct.xyz/ | bash`, then `sp1up -v 3.4.0`\n3. Install docker [https://docs.docker.com/get-started/get-docker/](https://docs.docker.com/get-started/get-docker/)\n\nVerify:\n\n1. Checkout the correct branch in [morph repo](https://github.com/morph-l2/morph): `git checkout v0.4.9`. Commit hash should be `1f4e42cf4c0e6680285770885477bc7450e5e900`\n2. Make sure docker is running by running `docker ps`\n3. Pull the specific SP1 docker image: `docker pull ghcr.io/succinctlabs/sp1@sha256:`\n`aa6c43a119183f8e4af65405e692760310562b0bae580be164bf4ce0f1f9b3cd`\n4. Create a local Docker tag for the pulled image: `docker tag ghcr.io/succinctlabs/sp1@sha256:`\n`aa6c43a119183f8e4af65405e692760310562b0bae580be164bf4ce0f1f9b3cd ghcr.io/succinctlabs/sp1:v3.4.0-local.1`\n5. Build the program binary from `prover/bin/client` dir: `cargo prove build --docker --tag v3.4.0-local.1`\n6. The generated elf binary `verifier-client` will be placed in `prover/target/elf-compilation/docker/riscv32im-succinct-zkvm-elf/release`. Move it to `prover/bin/client/elf` and rename to `riscv32im-succinct-zkvm-elf`.\n7. Regenerate and print the vkey from the elf binary by calling `cargo run --release --bin vkey` from `prover` dir.\n ",
"hash": "0x00ad538a51c761c06f5075d11f3ee64d5d00c272a741ccf098e1d9f062fee13d"
},
{
"title": "Morph Guest program (v0.4.5 release)",
"description": "Proves the correct execution of the Morph L2 state transition function (based on the Geth EVM) for a batch of blocks using the SP1 zkVM.",
"programUrl": "https://github.com/morph-l2/morph/tree/v0.4.5/prover/bin/client",
"proverSystemProject": "sp1turbo",
"verificationStatus": "successful",
"verificationSteps": "\nRebuilding this program vkey requires specific docker image and sp1 version. The docker image requires a linux platform or some emulation workarounds. To prepare:\n\n1. Install cargo make: `cargo install --debug --locked cargo-make`\n2. Install sp1 toolchain v3.4.0: `curl -L https://sp1up.succinct.xyz/ | bash`, then `sp1up -v 3.4.0`\n3. Install docker [https://docs.docker.com/get-started/get-docker/](https://docs.docker.com/get-started/get-docker/)\n\nVerify:\n\n1. Checkout the correct branch in [morph repo](https://github.com/morph-l2/morph): `git checkout v0.4.5`. Commit hash should be `2223d9836827b3c13ec0fbd7f769fed4b5235a9a`\n2. Make sure docker is running by running `docker ps`\n3. Pull the specific SP1 docker image: `docker pull ghcr.io/succinctlabs/sp1@sha256:`\n`aa6c43a119183f8e4af65405e692760310562b0bae580be164bf4ce0f1f9b3cd`\n4. Create a local Docker tag for the pulled image: `docker tag ghcr.io/succinctlabs/sp1@sha256:`\n`aa6c43a119183f8e4af65405e692760310562b0bae580be164bf4ce0f1f9b3cd ghcr.io/succinctlabs/sp1:v3.4.0-local.1`\n5. Build the program binary from `prover/bin/client` dir: `cargo prove build --docker --tag v3.4.0-local.1`\n6. The generated elf binary `verifier-client` will be placed in `prover/target/elf-compilation/docker/riscv32im-succinct-zkvm-elf/release`. Move it to `prover/bin/client/elf` and rename to `riscv32im-succinct-zkvm-elf`.\n7. Regenerate and print the vkey from the elf binary by calling `cargo run --release --bin vkey` from `prover` dir.\n ",
"hash": "0x0059b74a8fd03c44462de3916b45ebeedb9f1158e3037e8c40b8941cbe438d7e"
}
],
"risks": [
{
"category": "Funds can be stolen if",
"text": "a contract receives a malicious code upgrade. There is no delay on code upgrades.",
"isCritical": true
}
]
}