diff --git a/public/images/infrastructure-logos/layerzero.png b/public/images/infrastructure-logos/layerzero.png new file mode 100644 index 000000000..642061cf3 Binary files /dev/null and b/public/images/infrastructure-logos/layerzero.png differ diff --git a/src/content/blog/layerzero-centralization-poc.md b/src/content/blog/layerzero-centralization-poc.md new file mode 100644 index 000000000..10146cfbf --- /dev/null +++ b/src/content/blog/layerzero-centralization-poc.md @@ -0,0 +1,194 @@ +--- +title: "LayerZero Centralization Risk" +description: "We discuss the centralization risk of Protocols integrating LayerZero." +date: 2025-09-26T13:00:00Z +published: true +categories: ["Research"] +authors: ["yvesboutellier"] +tags: ["Research", "Decentralization", "Infrastructure"] +--- + +Few months ago we started releasing reports on the decentralization of infrastructure protocols which DeFi protocols rely upon as dependencies. Today we are releasing a report on the centralization risk of protocols integrating LayerZero. In this blog article we demonstrate a proof of concept with a link to a repository on how a project that is built on top of LayerZero can be compromised by centralizing the verifier set within LayerZero configurations of a protocol. This impacts a single protocol as LayerZero popularized the isolated security compared to the shared security of canonical bridges. We also referenced LayerZero in one of our existing reports and assess [Maverick V2](/protocols/maverick-v2/ethereum) with our analysis derived from the PoC and the [infrastructure risk report](/protocols/layerzero/ethereum). + +At DeFiScan we push for transparency and inform the ecosystem on centralization risks of DeFi projects by exposing upgradeability and dependencies in the smart contract architecture of DeFi protocols. + +## LayerZero + +LayerZero is a cross-chain messaging protocol that enables the transfer of value and data between different blockchains. It is composed of a few building blocks. To be specific, let's say we have Ethereum Mainnet and Arbitrum as our two chains. On each chain, we have an endpoint contract that acts as entry gate for cross-chain communication. + +As an example, we analyse a protocol that is built on top of LayerZero and our protocol has a contract on each chain, connected to the chain's endpoint contract. If users want to transfer value from Ethereum Mainnet to Arbitrum, our smart contract on Ethereum Mainnet will call the endpoint contract on Ethereum Mainnet and if our contract is a token for example it either burns the tokens or locks it on Ethereum Mainnet. + +The call from our token contract to the endpoint contract will emit an event that is picked up by our verifier network or the default verifier network configured by LayerZero if none has been specified by the protocol. These configured verifier networks run offchain algorithms that listen to these blockchain emitted events and verify the events. Each verifier network, if they deem the transaction as valid, will call on the destination network (here Arbitrum) the receiver library and send a transaction to mark the message as valid (for reference, we use this in step 3 maliciousily). This verification includes the details of the source and destination of the message, and the payload that has to be executed on the destination network. **Crucially**, the validator network is trusted to report the information accurately, there is no cryptographic primitives that bind the transaction on the source chain to the message sent by the validator network on the destination chain. In a next step, if all required verifiers have verified the message, the verification can be committed. Once comitted, the message is executable on the destination network. Any actor can call the endpoint contract on Arbitrum to execute the message, which calls our token contract with the verified payload, and, for example, mints an equivalent amount of tokens that were locked on Ethereum Mainnet. + +### Example Transcaction bridging from Ethereum Sepolia to Arbitrum Sepolia + +Send call on OFT (Mainnet Sepolia Tx): + +https://sepolia.etherscan.io/tx/0xc4fc209f2c778c9609f4ecd85131f778b11e03e6866696cc259e6f3275b1fd26 + +execute302 call (Arbitrum Sepolia Tx): + +https://sepolia.arbiscan.io/tx/0x9a3c2b7dc6212ca62acbe44d33e958ffc82e67955770c0a5acab9d65b3fd1fab + +![Normal bridging](../protocols/diagrams/LayerZero-normal-bridging.png) + +## Upgradeability within LayerZero + +The configuration of the verifier set within LayerZero is upgradeable. This means that the verifier set can be changed by the protocol that uses and is built on top of LayerZero. + +Important to note is that, even though LayerZero is a dependency for a project, the permission to update the verifier set lies within the protocol's permission owners, not in the dependency (LayerZero's multisig) - unless the protocol uses the default settings. + +## Proof of Concept + +In the upcoming sections we will show a proof of concept on how a project that is built on top of LayerZero can be compromised by centralizing the verifier set within LayerZero configurations of a protocol. + +In LayerZero each project either relies on the default configuration or can configure their own verifier set. + +The default configuration is a set of verifiers that are configured by the [multisig](/protocol/layerzero/ethereum#security-council) with the following address [0xBe010A7e3686FdF65E93344ab664D065A0B02478](https://etherscan.io/address/0xBe010A7e3686FdF65E93344ab664D065A0B02478), which is controlled by LayerZero. + +## Step 1 + +The ability to update the verifier set is owned by the protocol. If the owner account (whether a single EOA or a multisig) is compromised, an attacker could exploit that power. + +In our model the attacker first takes control of the owner account and, to make the PoC easier to follow, transfers contract ownership to an attacker-created EOA. + +Reference transactions: + +transfer ownership: [0x4194774aef7111988eeb6c1ca062097ff553669302f5c825f527232aa8721989](https://sepolia.etherscan.io/tx/0x4194774aef7111988eeb6c1ca062097ff553669302f5c825f527232aa8721989) +set delegate: [0x43b66ae30b6b366be3d0048bd2777938cba5eecc73f4e357fd3a7869fedbdb3f](https://sepolia.etherscan.io/tx/0x43b66ae30b6b366be3d0048bd2777938cba5eecc73f4e357fd3a7869fedbdb3f) + +## Step 2 + +Next, the attacker sets the configuration within an endpoint on a chain he or she wants to exploit. For example this could be Ethereum Mainnet. + +The verifier set can be changed to a set of verifiers that are controlled by the attacker (the array `requiredDVNs` just holds one address, requiredDVNCount is one). This could be simply an EOA which crafts a payload that the attacker wants to be executed, verifies this message and commits it to the destination chain. With a single required verifier and minimal confirmations required the attack can happen almost instantly. If the integrating contract is a token for example, the attacker could simply mint or unlock tokens on any of the configured blockchains. + +```solidity + UlnConfig memory uln = UlnConfig({ + confirmations: 1, // minimum block confirmations required on A before sending to B + requiredDVNCount: 1, // number of DVNs required + optionalDVNCount: type(uint8).max, // optional DVNs count, uint8 + optionalDVNThreshold: 0, // optional DVN threshold + requiredDVNs: requiredDVNs, // sorted list of required DVN addresses + optionalDVNs: optionalDVN // sorted list of optional DVNs + }); +``` + +Reference transaction: + +[0xf3db5c1921a9fe7f52235cbafd2649a5167489b6db86baa5c00e405de7ee09f1](https://sepolia.etherscan.io/tx/0xf3db5c1921a9fe7f52235cbafd2649a5167489b6db86baa5c00e405de7ee09f1) + +## Step 3 + +The attacker calls `verify()` on the receiving library with the payload they want to execute. This will verify the payload. If the integrating contract is an OFT (a wrapper contract around ERC20 that integrates LayerZero crosschain flow), the payload is just the receiving address and the amount scaled by the shared decimals. To complete the payload, a global unique identifier (guid) is added at the beginning, this number can be random. The payload is hashed and submitted. + +Additionally, a `_packetHeader` is supplied which specifies the source and destination contract and chain id of the message path, the nonce of the message, and the packet version. + +```solidity +// payload hash +bytes memory _message = abi.encodePacked( + bytes32(uint256(uint160(attacker))), // address padded to 32 bytes + uint64(AMOUNT_TO_STEAL) // amount in shared decimals +); + +bytes32 _guid = bytes32(uint256(69)); // guid is a global unique identifier +bytes memory payload = abi.encodePacked(_guid, _message); +bytes32 _payloadHash = keccak256(payload); +uint64 nonce = 3; // we did one incoming tx on mainnet from arbitrum until now, (0 if not initialized, 1 one tx) + +IReceiveUln302 uln = IReceiveUln302(ulnAddress); + +// packetversion: 1 byte +// nonce: 8 bytes +// srcEid: 4 bytes +// sender: 32 bytes +// dstEid: 4 bytes +// receiver: 32 bytes +// total: 81 bytes +bytes memory _packetHeader = abi.encodePacked(packetVersion, nonce, srcEid, sender, dstEid, receiver); +``` + +The `EndpointV2` contract will later check if this payload has been _verified_ by the required verifiers (what we just did). + +Reference transaction: + +[0x537f887bf58eaa4975f42cb96de5825c4af0898cea0e29ac723133328f3cb2a3](https://sepolia.etherscan.io/tx/0x537f887bf58eaa4975f42cb96de5825c4af0898cea0e29ac723133328f3cb2a3) + +## Step 4 + +The attacker calls `commitVerification` on the receiving library with the same payload hash and packet header as with the verify call. This will commit the verification to the destination chain. That means the payload hash is stored inside the `EndpointV2` contract. + +This call will revert if the payload hash or packet header do not match the verify call and if the required verifiers have not verified the payload, as we just in Step 3. + +Reference transaction: + +[0xc2bae285c1232ec8329343379857c191c8c701c95278942652680e500db067b9](https://sepolia.etherscan.io/tx/0xc2bae285c1232ec8329343379857c191c8c701c95278942652680e500db067b9) + +## Step 5 + +We can call `lzReceive` on the `EndpointV2` contract with a message whose hash is equal to the payload hash we submitted in Step 3 and 4. This will execute the payload on the destination chain. + +```solidity +bytes memory _message = abi.encodePacked( + bytes32(uint256(uint160(attacker))), // address padded to 32 bytes + uint64(AMOUNT_TO_STEAL) // amount in shared decimals +); + +// MALICIOUS: We dont use packet's data from event but our attack params that we have verified and comitted +ILayerZeroEndpointV2(endpoint).lzReceive(_origin, OFT_ADDRESS_MAINNET, _guid, _message, _extraData); +``` + +[0x44196a9b06dcb79a41f943cd9a4f4c2358739400b57e1de2c49145b3d9c873e2](https://sepolia.etherscan.io/tx/0x44196a9b06dcb79a41f943cd9a4f4c2358739400b57e1de2c49145b3d9c873e2) + +![Malicious Flow inside architecture](../protocols/diagrams/LayerZero-Centralization.png) + +## Severity + +Ultimately, the severity of the attack vector depends on the contract and the protocol that is built on top of LayerZero. We created a flowchart to interpret the impact on DeFiScan rated DeFi protocols. + +The following flowchart demonstrates that LayerZero integration introduces different risk profiles - either in the _Dependency_ dimension or as additional _Upgradeability_ risks. + +![Assessment](../protocols/diagrams/LayerZero-assessment.png) + +For example if the contract is an OFT, the potential severity is high, as the attacker can mint any amount of tokens. This severity is comparable to an upgradeable token contract, as the upgrade can include stealing funds and minting unbacked tokens. However, compared to a non-upgradeable token with fixed supply, introducing LayerZero integration (an cross-chain transfer) increases the risk of exploitation through centralization. + +## Mitigation + +### Upgradeability + +Only a designated delegate of an OApp/OFT or the OApp/OFT contract itself can configure the verifier set as in Step 2. In order to prevent this attack vector or its likelihood, the following options exist + +1. the verifier set is immutable, no delegate is configured for the OApp/OFT and no delegate can be configured, this is achieved by overriding `setDelegate` function inside the integrating contract and disable the function. Additionally, the OApp/OFT must not implement a function that calls the `setConfig` function on the Endpoint. This comes with the trade-off that the verifier set cannot be changed in the future and if the verifier stops working or is discontinued, new contracts need to be deployed. +2. the verifier set is mutable, but the ownership and the registered delegate of the OApp/OFT belongs to a multisig account that satisfies the security council requirements or an onchain governance process that has distributed voting power. This makes exploit attempts more difficult. + +### Autonomy + +The protocol (OApp/OFT) ultimately depends on the DVNs that are configured, whether this is the default DVN settings or a custom setup. + +We analysed the DVN settings of OApps/OFTs built on Ethereum Mainnet that where set in past 6 months. + +What we found is that 43% of the contracts using LayerZero have setup only one DVN (Fig 1.), this marks ultimate dependency to just one DVN. In most cases this is the LayerZero Labs DVN (Fig 2). In contrast 57% have chosen to reduce dependency to single DVNs by configure two different DVNs (48%) or some have three DVNs configured (9%). + +We did not found much diversity in the configurations, most OApp/OFTs in our analysis had the same DVNs configured for all incoming connections on Ethereum Mainnet. + +Fig 1. +![DVN Count Distribution](../protocols/diagrams/ethereum_dvn_count_dist.png) + +Fig 2. +![DVNs as configured as sole DVN](../protocols/diagrams/ethereum_single_dvn.png) + +## Shared vs isolated security + +LayerZero brought the concept of isolated security to crosschain communication, where each DApp can configure their own verifier set and their requirements. This allows for dynamic changes in accepted verifiers and the security budget when the App grows and change partners who are trusted in a modular way. However it also introduces a new risk of centralization and requires a lot more effort in monitoring the configured DVNs from the side of the DeFi community as in contrast with bridges that are shared between many DApps. + +## Risk through LayerZero Labs + +LayerZero Labs manages the default verifier set, which is used by default when an app has no verifier configured. If LayerZero Labs were to be compromised, the default verifier set could be compromised as well, leading to attacks on all DApps that use the default verifier set. + +## Closing remarks + +LayerZero is a powerful tool for crosschain communication by allowing modular configuration of verifiers and security settings. However centralization risk evaluation needs to be assessed for each app. It is important to be aware of these risks and to take appropriate measures to mitigate them. We hope this article contributed to assess the centralization risks in DeFi projects that use Layer Zero. + +## Disclaimer + +This article is for educational purposes only. The authors are not liable for any loss or damage arising from the use of this article. diff --git a/src/content/protocols/diagrams/LayerZero-Centralization.png b/src/content/protocols/diagrams/LayerZero-Centralization.png new file mode 100644 index 000000000..d4a490663 Binary files /dev/null and b/src/content/protocols/diagrams/LayerZero-Centralization.png differ diff --git a/src/content/protocols/diagrams/LayerZero-assessment.png b/src/content/protocols/diagrams/LayerZero-assessment.png new file mode 100644 index 000000000..3b28faa83 Binary files /dev/null and b/src/content/protocols/diagrams/LayerZero-assessment.png differ diff --git a/src/content/protocols/diagrams/LayerZero-normal-bridging.png b/src/content/protocols/diagrams/LayerZero-normal-bridging.png new file mode 100644 index 000000000..cc065771a Binary files /dev/null and b/src/content/protocols/diagrams/LayerZero-normal-bridging.png differ diff --git a/src/content/protocols/diagrams/ethereum_dvn_count_dist.png b/src/content/protocols/diagrams/ethereum_dvn_count_dist.png new file mode 100644 index 000000000..49821d6d4 Binary files /dev/null and b/src/content/protocols/diagrams/ethereum_dvn_count_dist.png differ diff --git a/src/content/protocols/diagrams/ethereum_single_dvn.png b/src/content/protocols/diagrams/ethereum_single_dvn.png new file mode 100644 index 000000000..98bbc25c0 Binary files /dev/null and b/src/content/protocols/diagrams/ethereum_single_dvn.png differ diff --git a/src/content/protocols/diagrams/layerZero-architecture.png b/src/content/protocols/diagrams/layerZero-architecture.png new file mode 100644 index 000000000..f4831680d Binary files /dev/null and b/src/content/protocols/diagrams/layerZero-architecture.png differ diff --git a/src/content/protocols/layerzero/data.json b/src/content/protocols/layerzero/data.json new file mode 100644 index 000000000..511cd0e2d --- /dev/null +++ b/src/content/protocols/layerzero/data.json @@ -0,0 +1,10 @@ +{ + "id": "layerzero", + "protocol": "Layer Zero", + "website": "https://layerzero.network/", + "defillama_slug": [""], + "socials": { + "x": "https://x.com/LayerZero_Core" + }, + "github": ["https://github.com/LayerZero-Labs"] +} diff --git a/src/content/protocols/layerzero/ethereum.md b/src/content/protocols/layerzero/ethereum.md new file mode 100644 index 000000000..e30076ba9 --- /dev/null +++ b/src/content/protocols/layerzero/ethereum.md @@ -0,0 +1,169 @@ +--- +chain: "Ethereum" +type: "Bridges" +logo: "/images/infrastructure-logos/layerzero.png" +stage: "I0" +protocols: ["maverick-v2"] +reasons: [] +risks: ["L", "H", "L", "M", "L"] +author: ["sagaciousyves"] +submission_date: "2025-05-07" +publish_date: "2025-05-15" +update_date: "2025-06-18" +--- + +# Summary + +LayerZero is a crosschain protocol that allows for the transfer of data and assets between chains. It is a permissionless protocol, meaning that any app can use the protocol for moving messages and tokens between chains. LayerZero relies on a Decentralized Validator Network (DVN) which validate transaction data that needs to move crosschain. LayerZero allows each protocol that integrates the crosschain protocol to configure their own security stack (DVNs) and executors. + +# Protocol Analysis + +![Architecture](../diagrams/layerZero-architecture.png) + +For moving messages and tokens across chains, protocol contracts post the message that has to be moved crosschain to the `EndpointV2` contract on the source chain alongside metadata which specifies the source and destination contract as well as endpoints. This `EndpointV2` contract on the source chain subsequently sends the data to a configured sending library that encodes the data and takes care of paying the verifiers (DVNs) and the Executor for verifying and executing the crosschain messages. After that, the `EndpointV2` contract emits an event (`PacketSent`) that has to be picked up by the configured and responsible DVNs. + +Once picked up and verified, the DVNs attest the verification of the crosschain messages to the configured Receive Library contract (`ReceiveUln302.verify(...)`) on the destination chain. When the threshold is met, any account can call `commitVerification` on the destination chain to stage the message for execution. + +In an additional step the executor executes the targeted message on the destination chain by calling `lzReceive`. If the designated executor does not execute the transaction on the destination chain, any user can step in and execute the transaction. Executing validated messages is permissionless. Users' transactions can thus not be censored once verified by the DVNs on the destination chain. `lzReceive` calls the target contract which is the OApp, OFT or custom contract. + +# Rating + +The risk of crosschain messaging lies in the execution of fraudulent messages on the destination chain and in censoring the transaction from moving crosschain. For example, if the bridged message is permissioned to mint tokens, a malicious DVN could mint tokens for themselves. In LayerZero, registering as a DVN is permissionless, thus also malicious DVNs can be registered to the LayerZero protocol. + +The following sections examine the roles of LayerZero Labs, DVNs and integrating protocols and risks associated with each role. + +## LayerZero Labs + +LayerZero endpoints are not upgradeable. LayerZero Labs' role in the LayerZero protocol is to; 1) deploy Endpoints on new chains, 2) register new libraries to endpoints, 3) set default libraries and 4) change default DVNs. The existing endpoints and default configurations are not affected if LayerZero Labs ceases to exist. + +The [OneSig](#security-council) multisig can change the default DVNs that verify crosschain messages with the function `setDefaultUlnConfigs`. If integrating protocols have no security stack / DVNs configured, their OApps/OFTs will fallback to the default DVN setup. In case LayerZero would setup a malicious DVN, this could lead to _loss of funds_. + +Furthermore, the [OneSig](#security-council) multisig can change default libraries and the ownership over the `EndpointV2` contract. The send library (latest version is `SendUln302`) is used to encode the data that is sent to the destination chain. Additionally, the send library handles the payment of the verifiers (DVNs) and the executor for verifying and executing the crosschain messages. If integrating protocols have no libraries configured, they will use the default libraries. If the default send library is updated, integrating protocols that have not configured a library will be forced to use the new default library. If the default library is updated to a library that does not handle the payment of verifiers (DVNs) and the executor, it could lead to blocked crosschain transactions as DVNs are not incentivized to validate crosschain transactions. + +Currently, the default DVNs for each path can be looked up at this page: https://layerzeroscan.com/tools/defaults + +## DVNs + +DVNs are trusted to verify the crosschain transaction data, if they choose to not verify, it would block and censor crosschain transactions. + +Moreover, if the required DVNs collude (or if just a single DVN is configured) they could collectively verify a fraudulent transaction on the target chain. If a smart contract and protocol integrates LayerZero, it gives LayerZero's endpoint permission to execute designated function like `lzReceice` upon verified and committed crosschain messages. The colluding DVNs can call this function with any viable parameters, mimicking a valid crosschain transaction for malicious purposes. If the integrating contract is an OFT, it would lead to unbacked minting of the token, as it is shown in our [blog article](/blog/layerzero-centralization-poc). + +Risks from specific DVNs are not included into the score of this infrastructure, but are reviewed on a case-by-case basis for integrating protocols. + +## Integrating Protocols (OApps, OFTs and custom integrations) + +Protocols that integrate LayerZero for crosschain bridging are responsible to configure DVNs and Executors. The protocol specific configuration remains mutable at all times. If protocols choose not to configure the DVNs or libraries, the LayerZero protocol falls back to defaults that were set by the [OneSig](#security-council) multisig. If protocols rely on a limited and narrow DVN set and permissioned Executor set, it could result in censorship for users of the protocol. To be censorship resistant it is thus important to rely on a diverse set of DVNs. In case of censorship the protocol needs to update configuration and require new DVNs to relay the messages and token transfers or reimburse its users if tokens have been burnt/locked. + +Moreover, if the protocol owner (DAO, multisig, EOA) is compromised and the attacker configures a malicious security stack (DVN), it could result in _loss of funds_ if the malicious DVN(s) approves and relays a fraudulent minting on the destination chain (see our [blog article](/blog/layerzero-centralization-poc)). + +Lastly, the protocol owner can change the peer contract on the destination chain (`setPeer`) to a malicious contract if the contract is not upgradeable, or upgrade the peer contract if it is upgradeable. This could result in _loss of funds_ for users of the protocol. + +It is essential that the integrating protocol guards permission over DVN configuration as malicious configuration can result in _loss of funds_ for users of the protocol at any time + +Risks from integrating protocols are not included into the score of this infrastructure, but are reviewed on a case-by-case basis. + +## Conclusion + +LayerZero protocol exposes centralized permissions on the default validator set that is used if the protocol owner does not configure a security stack. This results in a _High_ Centralization score. + +Furthermore, integrating protocols need to be evaluated individually on their current configured security stack, the perissioned control on configuring the security stack and upgradeability of _OApps_ and _OFTs_ contracts. + +> Overall score: High + +# Reviewer Notes + +- This review was limited to Endpoints and associated libraries deployed on Ethereum mainnet. We note that the findings should generalize to all chains according to LayerZero's documentation. +- LayerZero simplifies integration for protocols with the OApp and OFT contracts +- Each integrating protocol (OApp, OFT, or custom integration) sets up configuration for a specific path from chain A to chain B. The configuration from chain B to chain A is an separate configuration and as a consequence can deviate. +- Security stack, verifiers and DVNs are all synonymous. +- 0xfe9ab78ed4f9f3dbb168d9f5e5213d78605c9805 is unverified. It's the executor's implementation contract. The executor does not control or manage any user funds. + +# Appendix + +## Security Council + +| Multisig / Role | Address | Type | At least 7 signers | At least 51% threshold | ≥50% non-insider signers | Signers publicly announced | +| --------------- | --------------------------------------------------------------------------------------------------------------------- | ------------ | ------------------ | ---------------------- | ------------------------ | -------------------------- | +| OneSig | [0xBe010A7e3686FdF65E93344ab664D065A0B02478](https://etherscan.io/address/0xBe010A7e3686FdF65E93344ab664D065A0B02478) | Multisig 3/5 | ❌ | ✅ | ❌ | ❌ | + +## Contracts + +| Contract Name | Address | +| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| EndpointV2 | [0x1a44076050125825900e736c501f859c50fE728c](https://etherscan.io/address/0x1a44076050125825900e736c501f859c50fE728c) | +| ReceiveUln302 | [0xc02Ab410f0734EFa3F14628780e6e695156024C2](https://etherscan.io/address/0xc02Ab410f0734EFa3F14628780e6e695156024C2) | +| SendUln302 | [0xbB2Ea70C9E858123480642Cf96acbcCE1372dCe1](https://etherscan.io/address/0xbB2Ea70C9E858123480642Cf96acbcCE1372dCe1) | +| ReadLib1002 | [0x74F55Bc2a79A27A0bF1D1A35dB5d0Fc36b9FDB9D](https://etherscan.io/address/0x74F55Bc2a79A27A0bF1D1A35dB5d0Fc36b9FDB9D) | +| OptimizedTransparentUpgradeableProxy (Executor Proxy) | [0x173272739Bd7Aa6e4e214714048a9fE699453059](https://etherscan.io/address/0x173272739Bd7Aa6e4e214714048a9fE699453059) | +| Unverified Executor (Implementation) | [0xfe9ab78ed4f9f3dbb168d9f5e5213d78605c9805](https://etherscan.io/address/0xfe9ab78ed4f9f3dbb168d9f5e5213d78605c9805) | +| ProxyAdmin | [0xa36797bA947b378AefE5f726Cd87766CD3c25Ee3](https://etherscan.io/address/0xa36797bA947b378AefE5f726Cd87766CD3c25Ee3) | +| BlockedMessageLib | [0x1ccbf0db9c192d969de57e25b3ff09a25bb1d862](https://etherscan.io/address/0x1ccbf0db9c192d969de57e25b3ff09a25bb1d862) | +| DeadDVN | [0x747C741496a507E4B404b50463e691A8d692f6Ac](https://etherscan.io/address/0x747C741496a507E4B404b50463e691A8d692f6Ac) | +| OneSig | [0xBe010A7e3686FdF65E93344ab664D065A0B02478](https://etherscan.io/address/0xBe010A7e3686FdF65E93344ab664D065A0B02478) | +| Treasury | [0x5ebB3f2feaA15271101a927869B3A56837e73056](https://etherscan.io/address/0x5ebB3f2feaA15271101a927869B3A56837e73056) | + +## All Permission Owners + +| Name | Account | Type | +| -------- | --------------------------------------------------------------------------------------------------------------------- | ------------ | +| OneSig | [0xBe010A7e3686FdF65E93344ab664D065A0B02478](https://etherscan.io/address/0xBe010A7e3686FdF65E93344ab664D065A0B02478) | Multisig 3/5 | +| Treasury | [0x5ebB3f2feaA15271101a927869B3A56837e73056](https://etherscan.io/address/0x5ebB3f2feaA15271101a927869B3A56837e73056) | Contract | + +## Permissions + +| Contract | Function | Impact | Owner | +| ------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | +| EndpointV2 | registerLibrary | This function allows new libraries to be used. New libraries are not automatically active for existing apps, apps need to actively add new libraries to their configurations. Unless the app does not have any library configured, and the default is newly set with `setDefaultSendLibrary` or `setDefaultReceiveLibrary`. | OneSig | +| EndpointV2 | setDefaultSendLibrary | This function allows to set the default send library. Send libraries currently handle the payment of verifiers (DVNs) and of the executor and encoding of the message. Setting a new library that does not handle the payment could lead to currently disabling the payment of verifiers (DVNs) and of the executor. | OneSig | +| EndpointV2 | setDefaultReceiveLibrary | This function allows to set the default receive library. Setting a new library that does not handle the payment could lead to currently disabling the payment of verifiers (DVNs) and of the executor. | OneSig | +| EndpointV2 | setDefaultReceiveLibraryTimeout | This function allows to set the default library that is used when there is a timeout on the receiving destination. The confirmation of the message would go through the defaultReceiveLibraryTimeout instead of the defaultReceiveLibrary. | OneSig | +| EndpointV2 | setSendLibrary | Allows the OApp or OFT owner to configure an already registered library for sending messages. | OApp or delegates of OApp | +| EndpointV2 | setReceiveLibrary | Allows the OApp or OFT owner to configure an already registered library for receiving messages. | OApp or delegates of OApp | +| EndpointV2 | setReceiveLibraryTimeout | Allows the OApp or OFT owner to configure an already registered library as fallback, if the there is a timeout. | OApp or delegates of OApp | +| EndpointV2 | setConfig | The permission owner can configure DVNs and verification thresholds. IF a malicious DVN is configured, it can lead to loss of funds for users. | OApp or delegates of OApp | +| EndpointV2 | renounceOwnership | If ownership over this contract is renounced, the owner will no longer be able to register libraries and set default libraries. | OneSig | +| EndpointV2 | transferOwnership | Transfers ownership of the contract to a new account. | OneSig | +| EndpointV2 | skip | Skipping the next nonce to prevent message verification | OApp or delegates of OApp | +| EndpointV2 | nilify | Marks a packet as verified, but disallows execution until it is re-verified. | OApp or delegates of OApp | +| EndpointV2 | burn | Marks a nonce as unexecutable and un-verifiable. The nonce can never be re-verified or executed. | OApp or delegates of OApp | +| EndpointV2 | send | This function is called by the OApp to initiate a crosschain message which emits the event `MessageSent` that has to be picked up by configured DVNs. | OApp | +| EndpointV2 | clear | This function allows to clear a message, which means the cleared message can be ignored by the app and can never be executed. | OApp or delegates of OApp | +| EndpointV2 | setLzToken | Allows the owner of the contract to set the LayerZero token which can be used for payment. | OneSig | +| EndpointV2 | recoverToken | Allows the owner of the contract to recover ERC20 tokens that were sent to the address by mistake. | OneSig | +| ReceiveUln302 | setDefaultUlnConfigs | This function allows the permission owner to set the default DVNs. If protocols have no security stack / DVNs configured, they will fallback to the default configs setup. In case LayerZero would setup a malicious security stack, this could lead to loss of funds upon crosschain transactions. | OneSig | +| ReceiveUln302 | renounceOwnership | If the owner calls this function the default configuration, ie. default DVN and thresholds will become immutable for this library. The owner of the EndpointV2 contract still can register a new library and specify a different default configuration. | OneSig | +| ReceiveUln302 | transferOwnership | This function allows the owner to transfer ownership to a new account. This account can set the default DVN and thresholds. | OneSig | +| ReceiveUln302 | setConfig | This function is called by the EndpointV2 contract and stores the new configuration for the OApp that called the EndpointV2 contract. Settings for the DVNs on the destination chain are set to specify which DVNs are required to verify the crosschain message. | EndpointV2 | +| SendUln302 | send | This function is called by the EndpointV2 contract to create the encoded data packet that will be picked up by DVNs. With this function DVNs and executors are paid. | EndpointV2 | +| SendUln302 | setTreasury | Fees paid to LayerZero protocol are send to the address that is labelled as treasury. This function updates the address that is labelled as treasury. | OneSig | +| SendUln302 | withdrawLzTokenFee | This allows the address labelled as treasury to withdraw the fees that were accumulated. | Treasury | +| SendUln302 | setDefaultExecutorConfigs | This function sets the default executor that triggers lzReceive when a message is verified. | OneSig | +| SendUln302 | setTreasuryNativeFeeCap | The fee by the treasury can be set dynamically, as it's dynamically requested during the quote() call with \_quoteTreasury(). However, the fee can never be higher than the native fee cap. The native fee cap can after deployment never be increased, only decreased. | OneSig | +| SendUln302 | renounceOwnership | If the owner calls this function the default configuration, ie. default DVN and thresholds will become immutable for this library. The owner of the EndpointV2 contract still can register a new library and specify a different default configuration. | OneSig | +| SendUln302 | transferOwnership | This function allows the owner to transfer ownership to a new account. This account can set the default DVN and thresholds. | OneSig | +| SendUln302 | setDefaultUlnConfigs | This function allows the permission owner to set the default DVNs that are paid for delivering crosschain message. If protocols have no security stack / DVNs configured, they will fallback to the default configs setup. In case LayerZero would setup a malicious security stack, this could lead to loss of funds upon crosschain transactions. Where the settings on the source chain are not critical, as payment of Verifiers to execute the transaction on the destination chain is not an obstacle. | OneSig | +| SendUln302 | setConfig | This function is called by the EndpointV2 contract and stores the new configuration for the OApp that called the EndpointV2 contract. Settings for the DVNs on the source chain are set to specify which DVNs are paid. | EndpointV2 | +| ReadLib1002 | setDefaultReadLibConfigs | This function allows the permission owner to set the default DVNs that are paid for delivering crosschain message. If protocols have no security stack / DVNs configured, they will fallback to the default configs setup. In case LayerZero would setup a malicious security stack, this could lead to loss of funds upon crosschain transactions. Where the settings on the source chain are not critical, as payment of Verifiers to execute the transaction on the destination chain is not an obstacle. | OneSig | +| ReadLib1002 | renounceOwnership | If renounced, the default settings render immutable. This affects protocols that specified the ReadLib1002 for send and receive library. However, this protocols can specify new libraries. | OneSig | +| ReadLib1002 | transferOwnership | The ReadLib1002 combines both send and receive capabilities of SendUln302 and ReceiveUln302 libraries to process read requests and deliver verified responses across chains. So it allows also to set default configurations. If protocols have no security stack / DVNs configured, they will fallback to the default configs setup. In case LayerZero would setup a malicious security stack, this could lead to loss of funds upon crosschain transactions | OneSig | +| ReadLib1002 | setTreasury | Fees paid to LayerZero protocol are send to the address that is labelled as treasury. This function updates the address that is labelled as treasury. | OneSig | +| ReadLib1002 | setTreasuryNativeFeeCap | The fee by the treasury can be set dynamically, as it's dynamically requested during the quote() call with \_quoteTreasury(). However, the fee can never be higher than the native fee cap. The native fee cap can after deployment never be increased, only decreased. | OneSig | +| ReadLib1002 | send | This function is called by the EndpointV2 contract to create the encoded data packet that will be picked up by DVNs. With this function DVNs and executors are paid. | EndpointV2 | +| ReadLib1002 | setConfig | This function is called by the EndpointV2 contract and stores the new configuration for the OApp that called the EndpointV2 contract. Settings for the DVNs on the destination chain are set to specify which DVNs are required to verify the crosschain message. | EndpointV2 | +| ReadLib1002 | withdrawLzTokenFee | This allows the address labelled as treasury to withdraw the fees that were accumulated. | Treasury | +| OneSig | setExecutorRequired | This function allows to set the boolean flag, whether an executor is required. If no executor is required, as soon as enough signatures are given, the execution is permissionless. Otherwise only listed executors and signers are allowed to execute. | OneSig | +| OneSig | setExecutor | This function allows to set executors. Executors are allowed to execute signed transactions next to signers. | OneSig | +| OneSig | setThreshold | This allows to set the number of signatures that are required in order to approve the transaction. | OneSig | +| OneSig | setSigner | This function allows to add signers to the multisig. | OneSig | +| OneSig | setSeed | This allows to set the seed to prevent replay attacks. | OneSig | +| OneSig | executeTransaction | This function allows arbitrary calls to arbitrary destinations (batch). Currenlty, the function requires that 3 out of 5 signers sign the transactions. The execution can also be done by the Executor of the OneSig contract. | any Signer or Executor of the OneSig, need to supply signatures with 3/5 votes | + +## Signers of OneSig + +| Name | Account | Type | +| --------------- | --------------------------------------------------------------------------------------------------------------------- | ---- | +| OneSig Signer 1 | [0x0cb72C1F6a36c225A7E2B21712E8853A4A1acc47](https://etherscan.io/address/0x0cb72C1F6a36c225A7E2B21712E8853A4A1acc47) | EOA | +| OneSig Signer 2 | [0x5bC6AA6ad117A8B50ABf9E1658971f5DA1968c5c](https://etherscan.io/address/0x5bC6AA6ad117A8B50ABf9E1658971f5DA1968c5c) | EOA | +| OneSig Signer 3 | [0x73E9c017Ad37e2113e709D8070Cc9E1b28180e1e](https://etherscan.io/address/0x73E9c017Ad37e2113e709D8070Cc9E1b28180e1e) | EOA | +| OneSig Signer 4 | [0x771dcAcB96024d1e55Fd21Fe8a8187AA7EC9e77e](https://etherscan.io/address/0x771dcAcB96024d1e55Fd21Fe8a8187AA7EC9e77e) | EOA | +| OneSig Signer 5 | [0xe67DB04d7eFF4e9ec282eD929632D4FF058112d7](https://etherscan.io/address/0xe67DB04d7eFF4e9ec282eD929632D4FF058112d7) | EOA |