From 6b0320c3fd4c833f2b2f4537e728d298b714d97a Mon Sep 17 00:00:00 2001 From: "lz.angg" <162380499+angg-lz@users.noreply.github.com> Date: Fri, 26 Apr 2024 00:30:57 +0000 Subject: [PATCH 1/9] Add documentation --- README.md | 80 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 013f86c..df658ac 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,73 @@ -## L2SyncMint +# SyncPools -The `L2SyncMint` framework allows for easily adding native minting on L2 chains. +A `Sync Pool` is an OApp that allows users to deposit tokens on multiple Layer 2s, and then sync them all to Layer 1 - all using the LayerZero messaging protocol. -It's particularly useful because: +- [SyncPools](#syncpools) +- [Usage](#usage) + - [Build \& Test](#build--test) +- [Terminology](#terminology) + - [Anticipated deposits](#anticipated-deposits) + - [Actual deposits](#actual-deposits) + - [Batched syncs](#batched-syncs) + - [Lock box](#lock-box) + - [Fast Messages](#fast-messages) + - [Fast L1 Updating / Syncing](#fast-l1-updating--syncing) +- [Contracts Structure](#contracts-structure) + - [`L2SyncPool`](#l2syncpool) + - [`L1SyncPool`](#l1syncpool) + - [`L1Receiver`](#l1receiver) + - [`L2ExchangeRateProvider`](#l2exchangerateprovider) +- [Example User Flow](#example-user-flow) -- Batched syncs: Any interactions with mainnet occur in batches, this is a core feature as it allows for _low-cost_ L2 minting where no high L1 gas fee needs to be incurred on every mint. Both the fast sync and the actual ETH bridged are batched to save gas. -- Fast L1 updating: The L1 update occurs through the LayerZero bridge allowing for the L1 deposit pool to quickly realize that there is more outstanding supply. Typically this would be on eg. a daily sync schedule. -- Cost-efficient native ETH bridging: The actual ETH is however transferred over the native L2 bridge, significantly reducing cost (only gas cost) and of course increasing security compared to third party asset bridge solutions. -### Structure - -`L2SyncPool`: Extended with the specific L2 bridge details for every L2 type. The entrypoint for the user: Users can deposit ETH into this contract for it to mint the LST on the L2 (using `mint` on the actual LST token). It will periodically forward all ETH over the native bridge, alongside with sending a message to the `L1SyncPool` using LayerZero, notifying it of the supply adjustment in a much more rapid manner. - -`L1SyncPool`: The system is divided in an `L1SyncPool` which primary responsibility is first notifying the LST deposit pool of incoming mints and subsequently (normally 7 days later), exchanging the dummy deposit in the deposit pool with the actual ETH received. - -`L1Receiver`: Developed and deployed for every native bridge type (Arbitrum, Optimism...). Its only responsibility is receiving ETH from the L2 bridge and forwarding it to the SyncPool, alongside with the sync metadata. - -`L2ExchangeRateProvider`: The `L2SyncPool` needs to know the current exchange rate between ETH and the LST to operate. It configures an external oracle contract (the `L2ExchangeRateProvider`) to provide this data. Typically this would be or call a simple LayerZero OAPP that periodically receives the exchange rate from L1. - -### Build +# Usage +Clone the repository and run the following to get the contracts compiled and running in your machine +## Build & Test ```shell $ yarn build ``` -### Test - ```shell $ yarn test ``` + +# Terminology +## Anticipated deposits +A user can deposit _`N`_ ETH on L2, the L2 sync pool will send a fast message to the L1 sync pool anticipating the actual _`N`_ ETH deposit (as it takes ~7 days to finalize the deposit), and finalize the deposit when the _`N`_ ETH is actually received from the L2. The internal function `_anticipatedDeposit` mints the dummy tokens and deposits them to the L1 deposit pool. + +## Actual deposits +Deposits are finalized after the challenge period (usually ~7 days) has ended. The internal function `_finalizeDeposit` swaps the dummy token for the actual ETH. + +## Batched syncs +Any interactions with mainnet occur in batches, this is a core feature as it allows for _low-cost_ L2 minting where no high L1 gas fee needs to be incurred on every mint. Both the fast sync and the actual ETH bridged are batched to save gas. + +## Lock box +A Lockbox is a mechanism used to manage and secure the ETH deposited by the users for staking. The L1 sync pool is responsible for managing the lock box making sure it is backed by the correct amount of tokens. + +## Fast Messages +Fast messages are used to anticipate the deposit, and slow messages are used to finalize the deposit. A user can deposit _`N`_ ETH on L2, the L2 sync pool will send a fast message to the L1 sync pool anticipating the actual _`N`_ ETH deposit (as it takes ~7 days to finalize the deposit), and finalize the deposit when the _`N`_ ETH is actually received from the L2. + +## Fast L1 Updating / Syncing +The L1 update occurs through the LayerZero bridge allowing for the L1 deposit pool to quickly realize that there is more outstanding supply. Typically this would be on a (say) daily sync schedule. + +# Contracts Structure + +## `L2SyncPool` +This contract is deployed on each supported L2 for each token type. This contract acts as the entrypoint for the user. Users deposit ETH into this contract for it to mint the LST on the L2 (using `mint` on the actual LST token). It will periodically forward all ETH over the native bridge, alongside with sending a message to the `L1SyncPool` using LayerZero, notifying it of the supply adjustment in a much more rapid manner. + +## `L1SyncPool` +This contract takes care of the actual syncing process, it receives different messages from L2s and handles the **anticipated** and the **actual** deposits. + +The `L2SyncPool` periodically calls `L1SyncPool` to forward all ETH over the native bridge along with a message notifying adjustment of supply in a rapid manner. The supply is instantly adjusted and approximately 7 days later the dummy deposit in the deposit pool is replaced with the actual ETH received. + +## `L1Receiver` +Developed and deployed for every native bridge type (Arbitrum, Optimism...). Its only responsibility is to receive messages from the native L2 bridge, decode it and forward it to the `L1SyncPool`, along with the sync metadata. + +## `L2ExchangeRateProvider` +The `L2SyncPool` needs to know the current exchange rate between ETH and the LST to operate. It configures an external oracle contract (the `L2ExchangeRateProvider`) to provide this data. Typically this would be a call a simple LayerZero OApp that periodically receives the exchange rate from this contract. + + +# Example User Flow + +// todo: add steps and contract interactions a user would go thru + functions snippets From b5e6eb1b7197711c73eb2f76c767f984ba9354ac Mon Sep 17 00:00:00 2001 From: "lz.angg" <162380499+angg-lz@users.noreply.github.com> Date: Fri, 26 Apr 2024 19:23:34 +0000 Subject: [PATCH 2/9] add setup --- README.md | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index df658ac..5c5220a 100644 --- a/README.md +++ b/README.md @@ -17,57 +17,82 @@ A `Sync Pool` is an OApp that allows users to deposit tokens on multiple Layer 2 - [`L1SyncPool`](#l1syncpool) - [`L1Receiver`](#l1receiver) - [`L2ExchangeRateProvider`](#l2exchangerateprovider) +- [Setup](#setup) + - [Deployments on L1 chain](#deployments-on-l1-chain) + - [Deployments on L2 chains](#deployments-on-l2-chains) - [Example User Flow](#example-user-flow) # Usage + Clone the repository and run the following to get the contracts compiled and running in your machine ## Build & Test -```shell -$ yarn build -``` - -```shell -$ yarn test +Requires [foundry](https://book.getfoundry.sh/getting-started/installation) +```bash +yarn; yarn build; yarn test ``` # Terminology + ## Anticipated deposits + A user can deposit _`N`_ ETH on L2, the L2 sync pool will send a fast message to the L1 sync pool anticipating the actual _`N`_ ETH deposit (as it takes ~7 days to finalize the deposit), and finalize the deposit when the _`N`_ ETH is actually received from the L2. The internal function `_anticipatedDeposit` mints the dummy tokens and deposits them to the L1 deposit pool. ## Actual deposits + Deposits are finalized after the challenge period (usually ~7 days) has ended. The internal function `_finalizeDeposit` swaps the dummy token for the actual ETH. ## Batched syncs + Any interactions with mainnet occur in batches, this is a core feature as it allows for _low-cost_ L2 minting where no high L1 gas fee needs to be incurred on every mint. Both the fast sync and the actual ETH bridged are batched to save gas. ## Lock box + A Lockbox is a mechanism used to manage and secure the ETH deposited by the users for staking. The L1 sync pool is responsible for managing the lock box making sure it is backed by the correct amount of tokens. ## Fast Messages + Fast messages are used to anticipate the deposit, and slow messages are used to finalize the deposit. A user can deposit _`N`_ ETH on L2, the L2 sync pool will send a fast message to the L1 sync pool anticipating the actual _`N`_ ETH deposit (as it takes ~7 days to finalize the deposit), and finalize the deposit when the _`N`_ ETH is actually received from the L2. ## Fast L1 Updating / Syncing + The L1 update occurs through the LayerZero bridge allowing for the L1 deposit pool to quickly realize that there is more outstanding supply. Typically this would be on a (say) daily sync schedule. # Contracts Structure ## `L2SyncPool` + This contract is deployed on each supported L2 for each token type. This contract acts as the entrypoint for the user. Users deposit ETH into this contract for it to mint the LST on the L2 (using `mint` on the actual LST token). It will periodically forward all ETH over the native bridge, alongside with sending a message to the `L1SyncPool` using LayerZero, notifying it of the supply adjustment in a much more rapid manner. ## `L1SyncPool` + This contract takes care of the actual syncing process, it receives different messages from L2s and handles the **anticipated** and the **actual** deposits. The `L2SyncPool` periodically calls `L1SyncPool` to forward all ETH over the native bridge along with a message notifying adjustment of supply in a rapid manner. The supply is instantly adjusted and approximately 7 days later the dummy deposit in the deposit pool is replaced with the actual ETH received. ## `L1Receiver` + Developed and deployed for every native bridge type (Arbitrum, Optimism...). Its only responsibility is to receive messages from the native L2 bridge, decode it and forward it to the `L1SyncPool`, along with the sync metadata. ## `L2ExchangeRateProvider` + The `L2SyncPool` needs to know the current exchange rate between ETH and the LST to operate. It configures an external oracle contract (the `L2ExchangeRateProvider`) to provide this data. Typically this would be a call a simple LayerZero OApp that periodically receives the exchange rate from this contract. +# Setup + +Say the setup of chains is such that we have 1 L1 chain (*`A`*) and 2 L2 chains (*``* and *``*) + +### Deployments on L1 chain +- `L1BaseSyncPool` +- Receiver contracts for both X and Y - `L1ReceiverETH` & `L1ReceiverETH` +- Dummy token contracts for both X and Y - `DummyToken` (is a dependency for the Receiver contracts) + +### Deployments on L2 chains +- `L2ExchangeRateProvider` (requires admin) +- `L2SyncPool` (requires admin) + # Example User Flow -// todo: add steps and contract interactions a user would go thru + functions snippets +Eg., say user _**`A`**_ is interacting with L2 chain _**`C`**_. The first entrypoint of _**`A`**_ is the `L2SyncPool` contract on _**`C`**_ ([`examples/L2/syncpools/L2ModeSyncPoolETH.sol`](/contracts//examples/L2/syncpools/L2ModeSyncPoolETH.sol)) \ No newline at end of file From 69ea4310b0ce12899036d4531b53f63026a2700e Mon Sep 17 00:00:00 2001 From: "lz.angg" <162380499+angg-lz@users.noreply.github.com> Date: Fri, 26 Apr 2024 22:29:49 +0000 Subject: [PATCH 3/9] add initialization and user flow --- README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5c5220a..6834bdb 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,10 @@ A `Sync Pool` is an OApp that allows users to deposit tokens on multiple Layer 2 - [Setup](#setup) - [Deployments on L1 chain](#deployments-on-l1-chain) - [Deployments on L2 chains](#deployments-on-l2-chains) + - [Initialization](#initialization) - [Example User Flow](#example-user-flow) + - [Deposit](#deposit) + - [Sync](#sync) # Usage @@ -61,6 +64,9 @@ The L1 update occurs through the LayerZero bridge allowing for the L1 deposit po # Contracts Structure +> [!TIP] +> The [`examples/`](/contracts/examples/) directory has an example implementation of all of the contracts for Ethereum L1 and Linea and Mode L2. + ## `L2SyncPool` This contract is deployed on each supported L2 for each token type. This contract acts as the entrypoint for the user. Users deposit ETH into this contract for it to mint the LST on the L2 (using `mint` on the actual LST token). It will periodically forward all ETH over the native bridge, alongside with sending a message to the `L1SyncPool` using LayerZero, notifying it of the supply adjustment in a much more rapid manner. @@ -81,18 +87,74 @@ The `L2SyncPool` needs to know the current exchange rate between ETH and the LST # Setup -Say the setup of chains is such that we have 1 L1 chain (*`A`*) and 2 L2 chains (*``* and *``*) +Say the setup of chains is such that we have 1 L1 chain (*`A`*) and 2 L2 chains (*``* and *``*). +> [!TIP] +> The [`examples/`](/contracts/examples/) directory has an example implementation of all of the contracts for Ethereum L1 and **Linea** and **Mode** L2. The [L1Deploy.sol](/script/L1/L1Deploy.sol) and [LineaDeploy.sol](/script/L2/LineaDeploy.sol) and [ModeDeploy.sol](/script/L2/ModeDeploy.sol) script goes through the entire deployment flow for L1 and L2. + ### Deployments on L1 chain -- `L1BaseSyncPool` +- `L1SyncPool` - Receiver contracts for both X and Y - `L1ReceiverETH` & `L1ReceiverETH` - Dummy token contracts for both X and Y - `DummyToken` (is a dependency for the Receiver contracts) ### Deployments on L2 chains - `L2ExchangeRateProvider` (requires admin) -- `L2SyncPool` (requires admin) +- `L2SyncPool` (requires admin, see example initialization parameters [here](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/test/Playground.t.sol#L183-L191)) + +### Initialization +> [!NOTE] +> Code snippets in the following pointers are from [`Playground.t.sol`](/test/Playground.t.sol) test file +- `L1SyncPool` must have minter role for DummyToken +- Setup the Vault (or Lockbox) - example implementation for a Vault can be found in [`examples/mock/L1VaultEth.sol`](/contracts/examples/mock/L1VaultETH.sol) +- Set dummy token in `L1SyncPool` contract as the address of the deployed DummyToken - has to be set for each `EID` (EID is the [EndpointId](https://docs.layerzero.network/v2/developers/evm/technical-reference/endpoints)) + ```solidity + L1SyncPoolETH(ethereum.syncPool).setDummyToken(MODE.originEid, ethereum.dummyETHs[CHAINS.MODE]); + + L1SyncPoolETH(ethereum.syncPool).setDummyToken(LINEA.originEid, ethereum.dummyETHs[CHAINS.LINEA]); + ``` +- Set receiver for both `X` and `Y` L2s + ```solidity + L1SyncPoolETH(ethereum.syncPool).setReceiver(MODE.originEid, ethereum.receivers[CHAINS.MODE]); + + L1SyncPoolETH(ethereum.syncPool).setReceiver(LINEA.originEid, ethereum.receivers[CHAINS.LINEA]); + ``` +- Set `L2SyncPool` on both L2s as `peers` on `L1SyncPool` + ```solidity + L1SyncPoolETH(ethereum.syncPool).setPeer(MODE.originEid, bytes32(uint256(uint160(mode.syncPool)))); + + L1SyncPoolETH(ethereum.syncPool).setPeer(LINEA.originEid, bytes32(uint256(uint160(linea.syncPool)))); + ``` + Read more about setting peers [here](https://docs.layerzero.network/v2/developers/evm/oft/quickstart#setting-trusted-peers) +- Configure OApp parameters to complete OApp setup of L2SyncPool + - call `setEnforcedOptions` on `L2SyncPool`. Read more about setting enforced options [here](https://docs.layerzero.network/v2/developers/evm/oapp/overview#optional-enforced-options) + - call `setConfig` on L2's LayerZero Endpoint. Read more about setting config [here](https://docs.layerzero.network/v2/developers/evm/configuration/configure-dvns#call-setconfig-on-the-send-and-receive-lib) + - Example setup can be found [here](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/test/Playground.t.sol#L651-L683) # Example User Flow -Eg., say user _**`A`**_ is interacting with L2 chain _**`C`**_. The first entrypoint of _**`A`**_ is the `L2SyncPool` contract on _**`C`**_ ([`examples/L2/syncpools/L2ModeSyncPoolETH.sol`](/contracts//examples/L2/syncpools/L2ModeSyncPoolETH.sol)) \ No newline at end of file +### Deposit + +- Say user _**`A`**_ is interacting with L2 chain _**`X`**_ and holds the native ETH for _**`X`**_ +- The expected amount is queried from `L2ExchangeRateProvider` for some specific amount of ETH +- The [`.deposit()`](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/contracts/L2/L2BaseSyncPoolUpgradeable.sol#L194-L238) function is called on `L2SyncPoolETH.sol` + - The `.deposit()` function mints the `tokenOut` to _**`A`**_ (LST) + +### Sync +- `.sync()` - a public payable function called to sync tokens to Layer 1. Sends a LayerZero Message to L1SyncPool contract. + >[!IMPORTANT] + > It is very important to listen for the `Sync` event to know when and how much tokens were synced especially if an action is required on another chain (for example, executing the message). If an action was required but was not executed, the tokens won't be sent to the L1. + > ```solidity + > emit Sync(dstEid, tokenIn, unsyncedAmountIn, unsyncedAmountOut); + > ``` +- `.lzReceive` on L1SyncPool is called + - increments the vault's (or lockbox) assets by the deposited amount + - **Anticipates a deposit**: executes [`_anticipatedDeposit`](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/contracts/examples/L1/L1SyncPoolETH.sol#L108) - Will mint the dummy tokens and deposit them to the L1 deposit pool + - calls [`_handleAnticipatedDeposit`](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/contracts/L1/L1BaseSyncPoolUpgradeable.sol#L266) - Internal function to handle an anticipated deposit. + - Will emit an InsufficientDeposit event if the actual amount out is less than the expected amount out. + - Will emit a Fee event if the actual amount out is equal or greater than the expected amount out. + - The fee kept in this contract will be used to back any future insufficient deposits. + - When the fee is used, the total unbacked tokens will be lower than the actual missing amount + >[!IMPORTANT] + > Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) + From fea7abcc6748eb5c5526c16f63e1764bfe1ce976 Mon Sep 17 00:00:00 2001 From: "lz.angg" <162380499+angg-lz@users.noreply.github.com> Date: Fri, 26 Apr 2024 22:38:08 +0000 Subject: [PATCH 4/9] fix --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6834bdb..2ebff8b 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ The `L2SyncPool` needs to know the current exchange rate between ETH and the LST # Setup -Say the setup of chains is such that we have 1 L1 chain (*`A`*) and 2 L2 chains (*``* and *``*). +Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chains (*``* and *``*). > [!TIP] > The [`examples/`](/contracts/examples/) directory has an example implementation of all of the contracts for Ethereum L1 and **Linea** and **Mode** L2. The [L1Deploy.sol](/script/L1/L1Deploy.sol) and [LineaDeploy.sol](/script/L2/LineaDeploy.sol) and [ModeDeploy.sol](/script/L2/ModeDeploy.sol) script goes through the entire deployment flow for L1 and L2. @@ -142,7 +142,7 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and 2 L2 chains ### Sync - `.sync()` - a public payable function called to sync tokens to Layer 1. Sends a LayerZero Message to L1SyncPool contract. - >[!IMPORTANT] + >[!NOTE] > It is very important to listen for the `Sync` event to know when and how much tokens were synced especially if an action is required on another chain (for example, executing the message). If an action was required but was not executed, the tokens won't be sent to the L1. > ```solidity > emit Sync(dstEid, tokenIn, unsyncedAmountIn, unsyncedAmountOut); @@ -155,6 +155,6 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and 2 L2 chains - Will emit a Fee event if the actual amount out is equal or greater than the expected amount out. - The fee kept in this contract will be used to back any future insufficient deposits. - When the fee is used, the total unbacked tokens will be lower than the actual missing amount - >[!IMPORTANT] + >[!NOTE] > Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) From 61c0ca64ebde86d7e7bdfc74201b0d828bcee841 Mon Sep 17 00:00:00 2001 From: "lz.angg" <162380499+angg-lz@users.noreply.github.com> Date: Fri, 26 Apr 2024 22:39:01 +0000 Subject: [PATCH 5/9] fix indentation --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2ebff8b..6007026 100644 --- a/README.md +++ b/README.md @@ -142,11 +142,11 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chain ### Sync - `.sync()` - a public payable function called to sync tokens to Layer 1. Sends a LayerZero Message to L1SyncPool contract. - >[!NOTE] - > It is very important to listen for the `Sync` event to know when and how much tokens were synced especially if an action is required on another chain (for example, executing the message). If an action was required but was not executed, the tokens won't be sent to the L1. - > ```solidity - > emit Sync(dstEid, tokenIn, unsyncedAmountIn, unsyncedAmountOut); - > ``` +>[!NOTE] +> It is very important to listen for the `Sync` event to know when and how much tokens were synced especially if an action is required on another chain (for example, executing the message). If an action was required but was not executed, the tokens won't be sent to the L1. +> ```solidity +> emit Sync(dstEid, tokenIn, unsyncedAmountIn, unsyncedAmountOut); +> ``` - `.lzReceive` on L1SyncPool is called - increments the vault's (or lockbox) assets by the deposited amount - **Anticipates a deposit**: executes [`_anticipatedDeposit`](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/contracts/examples/L1/L1SyncPoolETH.sol#L108) - Will mint the dummy tokens and deposit them to the L1 deposit pool @@ -155,6 +155,6 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chain - Will emit a Fee event if the actual amount out is equal or greater than the expected amount out. - The fee kept in this contract will be used to back any future insufficient deposits. - When the fee is used, the total unbacked tokens will be lower than the actual missing amount - >[!NOTE] - > Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) + >[!NOTE] + > Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) From b2e5832da3cee6e64074c776fc2a033007c17b49 Mon Sep 17 00:00:00 2001 From: "lz.angg" <162380499+angg-lz@users.noreply.github.com> Date: Fri, 26 Apr 2024 22:39:36 +0000 Subject: [PATCH 6/9] fix indentation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6007026..8f424ec 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,6 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chain - Will emit a Fee event if the actual amount out is equal or greater than the expected amount out. - The fee kept in this contract will be used to back any future insufficient deposits. - When the fee is used, the total unbacked tokens will be lower than the actual missing amount - >[!NOTE] - > Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) +>[!NOTE] +> Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) From c784a8e865361b31841734ea6c2af872ae3fce8f Mon Sep 17 00:00:00 2001 From: "lz.angg" <162380499+angg-lz@users.noreply.github.com> Date: Fri, 26 Apr 2024 22:39:43 +0000 Subject: [PATCH 7/9] fix indentation --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8f424ec..b0499c5 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,6 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chain - Will emit a Fee event if the actual amount out is equal or greater than the expected amount out. - The fee kept in this contract will be used to back any future insufficient deposits. - When the fee is used, the total unbacked tokens will be lower than the actual missing amount ->[!NOTE] -> Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) - + >[!NOTE] + > Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) + From f6d72b83e7c131665cf1425f55a67160c04f37db Mon Sep 17 00:00:00 2001 From: "lz.angg" <162380499+angg-lz@users.noreply.github.com> Date: Fri, 26 Apr 2024 22:40:11 +0000 Subject: [PATCH 8/9] make important --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b0499c5..2ffd421 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chain ### Sync - `.sync()` - a public payable function called to sync tokens to Layer 1. Sends a LayerZero Message to L1SyncPool contract. ->[!NOTE] +>[!IMPORTANT] > It is very important to listen for the `Sync` event to know when and how much tokens were synced especially if an action is required on another chain (for example, executing the message). If an action was required but was not executed, the tokens won't be sent to the L1. > ```solidity > emit Sync(dstEid, tokenIn, unsyncedAmountIn, unsyncedAmountOut); @@ -155,6 +155,6 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chain - Will emit a Fee event if the actual amount out is equal or greater than the expected amount out. - The fee kept in this contract will be used to back any future insufficient deposits. - When the fee is used, the total unbacked tokens will be lower than the actual missing amount - >[!NOTE] - > Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) +>[!IMPORTANT] +> Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) From 909db72227bb2b8431d30c53d1647acb0c8a3930 Mon Sep 17 00:00:00 2001 From: Angela Gilhotra Date: Mon, 8 Jul 2024 23:15:20 -0700 Subject: [PATCH 9/9] from what i could recall --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 2ffd421..624b203 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Any interactions with mainnet occur in batches, this is a core feature as it all ## Lock box -A Lockbox is a mechanism used to manage and secure the ETH deposited by the users for staking. The L1 sync pool is responsible for managing the lock box making sure it is backed by the correct amount of tokens. +Lockbox is basically just the [OFTAdapter](https://github.com/LayerZero-Labs/LayerZero-v2/blob/main/oapp/contracts/oft/OFTAdapter.sol), the contract that will contain the outstanding OFT supply on the source (or main) chain. ## Fast Messages @@ -64,7 +64,7 @@ The L1 update occurs through the LayerZero bridge allowing for the L1 deposit po # Contracts Structure -> [!TIP] +> [!TIP] > The [`examples/`](/contracts/examples/) directory has an example implementation of all of the contracts for Ethereum L1 and Linea and Mode L2. ## `L2SyncPool` @@ -87,13 +87,13 @@ The `L2SyncPool` needs to know the current exchange rate between ETH and the LST # Setup -Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chains (*``* and *``*). -> [!TIP] +Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chains (*``* and *``*). +> [!TIP] > The [`examples/`](/contracts/examples/) directory has an example implementation of all of the contracts for Ethereum L1 and **Linea** and **Mode** L2. The [L1Deploy.sol](/script/L1/L1Deploy.sol) and [LineaDeploy.sol](/script/L2/LineaDeploy.sol) and [ModeDeploy.sol](/script/L2/ModeDeploy.sol) script goes through the entire deployment flow for L1 and L2. ### Deployments on L1 chain -- `L1SyncPool` +- `L1SyncPool` - Receiver contracts for both X and Y - `L1ReceiverETH` & `L1ReceiverETH` - Dummy token contracts for both X and Y - `DummyToken` (is a dependency for the Receiver contracts) @@ -109,13 +109,13 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chain - Set dummy token in `L1SyncPool` contract as the address of the deployed DummyToken - has to be set for each `EID` (EID is the [EndpointId](https://docs.layerzero.network/v2/developers/evm/technical-reference/endpoints)) ```solidity L1SyncPoolETH(ethereum.syncPool).setDummyToken(MODE.originEid, ethereum.dummyETHs[CHAINS.MODE]); - + L1SyncPoolETH(ethereum.syncPool).setDummyToken(LINEA.originEid, ethereum.dummyETHs[CHAINS.LINEA]); ``` - Set receiver for both `X` and `Y` L2s ```solidity L1SyncPoolETH(ethereum.syncPool).setReceiver(MODE.originEid, ethereum.receivers[CHAINS.MODE]); - + L1SyncPoolETH(ethereum.syncPool).setReceiver(LINEA.originEid, ethereum.receivers[CHAINS.LINEA]); ``` - Set `L2SyncPool` on both L2s as `peers` on `L1SyncPool` @@ -147,14 +147,14 @@ Say the setup of chains is such that we have 1 L1 chain (*`A`*) and two L2 chain > ```solidity > emit Sync(dstEid, tokenIn, unsyncedAmountIn, unsyncedAmountOut); > ``` -- `.lzReceive` on L1SyncPool is called +- `.lzReceive` on L1SyncPool is called - increments the vault's (or lockbox) assets by the deposited amount - **Anticipates a deposit**: executes [`_anticipatedDeposit`](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/contracts/examples/L1/L1SyncPoolETH.sol#L108) - Will mint the dummy tokens and deposit them to the L1 deposit pool - - calls [`_handleAnticipatedDeposit`](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/contracts/L1/L1BaseSyncPoolUpgradeable.sol#L266) - Internal function to handle an anticipated deposit. - - Will emit an InsufficientDeposit event if the actual amount out is less than the expected amount out. - - Will emit a Fee event if the actual amount out is equal or greater than the expected amount out. - - The fee kept in this contract will be used to back any future insufficient deposits. + - calls [`_handleAnticipatedDeposit`](https://github.com/LayerZero-Labs/SyncPools/blob/5ef225b435f3df56f2255b034fe251c27e765d7f/contracts/L1/L1BaseSyncPoolUpgradeable.sol#L266) - Internal function to handle an anticipated deposit. + - Will emit an InsufficientDeposit event if the actual amount out is less than the expected amount out. + - Will emit a Fee event if the actual amount out is equal or greater than the expected amount out. + - The fee kept in this contract will be used to back any future insufficient deposits. - When the fee is used, the total unbacked tokens will be lower than the actual missing amount >[!IMPORTANT] > Any time the `InsufficientDeposit` event is emitted, necessary actions should be taken to back the lock box (such as using POL, increasing the deposit fee on the faulty L2, etc.) - +