# Take-Home System-Design Assignment In this exercise you will design **the cross-layer settlement system** that lets an existing L2 order-book perps engine interoperate **synchronously** with Ethereum L1. We give you the tech primitives you design the components and message flows that satisfy the product stories below and explain the trade-offs. --- ## 0 · Background & Assumptions | Topic | Fact you can rely on | |-------|----------------------| | **L2 exchange** | Already live on a high throughput L2 where its orderbook is completely on-chain, exactly like Hyperliquid, but an L2. Matching engine, margin & liquidation logic run in L2 blocks. | | **Fast proof gadget** | We will use Automata’s [**TEE multi-prover**](https://docs.ata.network/tee-overview/tee-prover) (SGX / TDX) to prove each L2 block. A prover produces `(postStateRoot, DCAP quote)`; an L1 contract (`DCAPVerifier + OnChainPCCS`) verifies this inside the *same* Ethereum slot. | | **Same-slot messaging** | For L1→L2 direction we adopt the pattern in *[Same-slot L1–L2 message passing](https://ethresear.ch/t/same-slot-l1-l2-message-passing/21186)*: an L2 batch can “consume” an L1 log in the very block it is published. | | **Oracle** | A Chainlink-style price feed exists on L1. | | **Lending protocol** | There is a lending protocol on L1 (like AAVE) that lets users use their L2 perp positions as collateral. It uses clear risk rules to keep the protocol safe. | | **Liquidation boundaries** | Perp position liquidations always occur on the L2 orderbook, while lending protocol liquidations always occur on L1. Each system is responsible for its own liquidation logic, ensuring both are self-contained. | --- ## 1 · Product Requirements | ID | User story | |----|------------| | **R-1** | *As a **trader** I want to withdraw my collateral from L2 to L1 **at any time**, so that my funds arrive in the **very next Ethereum block** and the UI can show me an immediate soft confirmation.* | | **R-2** | *As a **trader** I want to **use my open perp position on L2 as collateral** to borrow assets on an L1 lending protocol, so that I can access liquidity without closing my trade.* | | **R-3** | *As the **system**, when a perp position is liquidated on L2 I must send a proof to L1 **in the same block** so that the related L1 loan can be closed safely.* | | **R-4** | *As the **lending protocol**, if the mark-to-market value of a trader’s L2 position falls below maintenance margin (using an L1 price oracle) the L2 engine must liquidate the position and repay the loan, all in one atomic cross-layer flow.* | --- ## 2 · Your Tasks ### 2.1 Identify and list **all major components** *Use your judgement to decide which components are necessary for your design.* Generally speaking, there are three kinds of components will be needed in the current system - **L1 contracts:** All on-chain logic and state on Ethereum mainnet. - **L2 components:** The core exchange and messaging infrastructure on the L2. - **Off-chain actors:** Any external services or bots. --- ### 2.2 For **each requirement (R-1 … R-4)** You should be prepared to **draw a sequencer diagram** for each requirement(R-1 to R-4) that shows the exact call flow across components. --- ### 2.3 For each diagram, **explain the purpose of every step** For each step in your sequence diagrams, you should be able to explain **what happens** exactly and why it is needed. #### Answer-format example (for inspiration) > **Requirement X – *simple deposit* (illustrative only)** ```mermaid sequenceDiagram participant T as Trader participant L2 as Sequencer participant P as TEE Prover participant B as Bridge(L1) participant V as Vault(L1) T->>L2: 1. deposit(1 ETH) L2-->>P: 2. include in block N P->>B: 3. postStateRoot + quote B->>V: 4. verify DCAP & credit V-->>T: 5. L1 balance updated L2-->>T: 6. UI soft-ack ``` | Step | What happens | Purpose / checks | |------|------------------------------------------------------------------------------|-----------------------------------------------| | 1 | Trader signs `deposit()` tx on L2. | Locks funds in L2 vault. | | 2 | Sequencer includes tx in block N. | … | | 3 | TEE prover replays block N, produces quote, submits `updateState()`. | DCAP quote embedded with `keccak256(root)`. | | … | … | … | ### 2.4 Open-ended Design Questions *Prepare to answer the following open-ended questions. --- **1. Latency Mismatch** *Ethereum block time is ~12 seconds, while L2 blocks are sub-second. Because certain actions—like liquidations or withdrawals—can only be finalized or processed after they are included in the next L1 (Ethereum) block, there is a delay or "gating" effect: users must wait for the next L1 block before their withdrawal or liquidation is actually completed on-chain. How does your design prevent users from exploiting this latency gap to trigger a “bank-run” (i.e., mass withdrawals or liquidations) before L1 can react?* *For example, consider a scenario where a user uses a perp position as collateral for a loan on L1. If the user's L2 perp position is liquidated due to adverse price movement, the L1 lending protocol must also close or liquidate the user's loan to avoid bad debt. However, because L2 liquidations are only finalized after the next L1 block, there is a window where the L1 protocol is unaware of the liquidation event on L2.* - **Explanation:** - What are the implications of this latency mismatch for cross-layer collateral management? - How does your design ensure that L1 lending protocols remain solvent and synchronized with L2 risk events? - Describe mechanisms to prevent users from exploiting the latency gap between L1 and L2 (e.g., withdrawal queues, withdrawal limits, or time-based restrictions). - Discuss how you ensure solvency and prevent mass withdrawals or liquidations before L1 can react. --- **2. Alternative Proof Systems** *Currently, the system design assumes the use of a TEE-based multiprover for state proofs. However, we anticipate the need to be forward compatible with a ZK-based proof stack (e.g., SP1 without TEE) in the future, especially as real-time ZK proving becomes practical.* - What changes would be required in your design to support switching from a TEE-based to a ZK-based prover? - What necessary abstractions or interfaces should be introduced to support both proof systems? ---