Luke Tchang
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # FLAX Privacy Layer - Updated ## Introduction FLAX is a drop-in-place privacy layer for EVM chains that is compatible with existing protocols and tokens. FLAX enables: - Anonymous interaction with any on-chain application using ERC20/721/1155 assets - Confidential payments (hidden sender, recipient, and amount) FLAX enables easy and usable privacy, focusing on three core properties---flexibility, composability, and cost. #### Flexibility FLAX is a dapp that can be deployed to any EVM chain. There is no need to bridge to a separate L1 or L2 for privacy. FLAX serves as a drop-in-place privacy layer for existing ecosystems. #### Composability FLAX is backwards-compatible with all existing assets and on-chain applications. No wrapped assets and no smart contract modifications---the original token contracts remain untouched. The accounting is simply moved up one layer to the FLAX protocol. #### Cost Through transaction batching and zk proof aggregation, we will eventually be able to achieve private usage of funds at an overhead cost of roughly ~150-200k gas per operation. ## High Level Architecture FLAX uses one large multi-asset pool, known as the Vault, to store every user's funds. All user interactions with dapps are initiated from the FLAX Wallet contract without revealing the identity of the user. * Vault.sol - Responsible for holding all of the funds and is only callable by the Wallet * Wallet.sol * Manages all of the note commitments and therefore keeps track (cryptographically) of which users own which notes * Makes the external contract calls for the user * The entry point for users when they want to perform a DeFi transaction or a smart contract call The Wallet will request the funds needed from the Vault, and then perform the contract call. Once the contract call is made, the Wallet will send back any remaining or new funds back to the Vault. The Wallet will then create new note commitments for these values for the user. The following diagram illustrates a high level view of the workflow: ![](https://i.imgur.com/Rq7h5S0.png) ### FLAX API #### Wallet.sol **[1]** `DepositFunds(Deposit deposit)` * Creates new note commitments for the deposited amount for the user calling this function. * Caller must be the owner of the deposit tokens. * This is to prevent any user from making your deposits for you if you have approved the vault to spend the tokens * User must first approve the **Vault** to spend the deposited amount. * The Vault is the one making the transfer to prevent users from using processBundle with a malicious action to transfer the funds how they like * Calls the Vault.makeDeposit(deposit), and the Vault will call (assetType).transfer(deposit.spender, address(this), deposit.value). **[2]** `ProcessBundle(Bundle bundle) returns (bool[] successes, bytes[][] results)` * Performs every Operation inside the bundle * For each Operation, handles: * Spend Txs - Verifies user owns the notes listed in the spend tx. Gathers specified funds from the Vault for each valid spend tx. * Actions - Makes an external call to the user-defined smart contract with the user-defined data for each Action. Note: An action can not call the Vault. * Refund Txs - Creates new note commitments for the user for each asset type with positive balance. Sends the funds to the Vault. Asset types must be known in advance. * The Wallet will contain 0 funds before this call, and 0 funds after. **[3]** `ConfidentialTransfer(...) returns (bool success)` - Takes list of spend proofs, an asset address, an amount, and a recipient address - Nullifies the spent note commitments - Enqueues new note commitments for the spent assets that now belonging to the new recipient **[4]** `Commit8FromQueue()` * Commits 8 leaves in the leafQueue to the noteCommitmentTree. The sequencer is responsible for calling this function periodically. Note: User's cannot spend note commitments in the queue. They must be commited to the tree via this function in order to be spent. #### Vault.sol These are the exposed functions that only the Wallet can call. **[1]** `RequestFunds(uint256[] values, address[] assetTypes) onlyWallet` * Transfers the given value for each asset type to the Wallet. * Called by the Wallet after the Wallet verified valid SpendTxs corresponding to the given values and asset types. * Not callable by processBundles since actions cannot call the Vault. **[2]** `makeDeposit(IFLAXTeller.Deposit calldata deposit) onlyWallet returns (bool)` * Calls assetType.transfer(deposit.spender, address(this), deposit.value) - essentially transfering approved funds to this contract. * Returns the success status of the transfer call. ### Batching In order to get the lowest gas cost per user interaction, FLAX will batch multiple transactions into one and submit them on-chain via a sequencer. This may initially add a mild latency to user transactions (parametrizable based on user preferences). Under early low volume, FLAX will likely subsidize costs to ensure low latency. In the future, higher volume will make batching more time and cost effective. ### Proof Aggregation In order to further reduce gas costs, we will aggregate multiple users' spend proofs into single aggregate proofs. This is possible through recursive composition or [other aggregation schemes](https://eprint.iacr.org/2021/529.pdf). ## FLAX Usage Using FLAX privacy is extremely simple. Once you deposit assets into the pool, you are free to make private transfers or contract calls as usual. The underlying ERC20/721/1155 assets remain unchanged (no wrapped assets). All that changes is that the accounting of said assets is moved to our protocol layer. Note: Both confidential payments and anonymous contract calls will be usable manually through our browser extension (likely a MetaMask snap) or programatically through our SDK. The SDK contains all logic for tracking and spending private balances. The browser extension wraps the SDK functionality in a simple UI. ### Confidential Payments 1. Deposit funds to the shielded pool via the wallet's deposit methods. 2. Attain a shielded address for your recipient. Given knowledge of your counterparty's address base (an identifier privately shared with you by the recipient), our SDK will automatically handle generating the shielded address. 3. Call an exposed `confidentialTransfer` method on the wallet, entering an asset type, amount, and shielded recipient address. ### Anonymous Contract Calls 1. Deposit funds to the shielded pool via the wallet's deposit methods. 2. Specify your desired assets, contract calldata, and contract address. 3. Format the contract call into a FLAX operation and call `performOperation`(handled by SDK or browser extension). ## Compliance While we seek to empower users with on-chain privacy, we will also take measures to be regulatorily compliant where needed. ### Per-User Viewing Keys Each user has their own viewing key. Knowledge of a user’s viewing key allows one to link together the user’s private transactions. Usage of specific assets within FLAX can be made contingent on sharing one’s viewing key with a privileged party (e.g. an asset issuer). ### Travel Rule (and other custom logic) As an extension of per-user viewing keys, we can encode custom conditions for requiring sharing of viewing keys. For example, we could require users to share viewing keys only for transactions that use more than 1,000,000 USDC. ### Privacy-Preserving Blacklists Services such as Circle or Chainalysis provide blacklists of illicit addresses. In order to draw on such blacklists while still preserving privacy, we can deploy a custom zk blacklist. For each FLAX call, we could enables users to provide a zk proof that their shielded address is not included in the blacklist without revealing their address. ## Appendix ### Other Future Features * **Note joining** - We can currently only spend one note at a time. We want to enable joining notes together via a single spend proof. This will reduce spend costs and enable easier confidential payments. * **Easier confidential payments** - Given UX benefits provided by note joining (above), we will likely build out a whole set of tooling specifically around confidential payments. ### Gas Estimates Note: Got these from Wei Jie's [slides](https://docs.google.com/presentation/d/1G1zQjTKPKclUtwaYidek07eceL7BB1rZ0nMH39dU3yw/edit#slide=id.p) and [research post](https://ethresear.ch/t/gas-and-circuit-constraint-benchmarks-of-binary-and-quinary-incremental-merkle-trees-using-the-poseidon-hash-function/7446) from 0xPARC group. #### Cost By On-Chain Op * Groth16 proof verification: ~200k gas + ~21k gas per public input * Aggregate proof (8 aggregated spend proofs) verification: ~350-400k gas * Poseidon (2 inputs): 53189 gas, 240 constraints * Poseidon (5 inputs): 121984 gas, ??? constraints * SHA256 (2 inputs): 2179 gas, 409926 constraints #### Prover Costs * Proof generation (1.1M constraints): * ~ 7 seconds on an Intel i7 1.80GHz laptop with rapidsnark (optimised for Intel x86) * ~ 17 seconds with zkutil (Rust/bellman) * Minutes with snarkjs (Nodejs) * Binary Merkle Tree (Poseidon Hash) * Depth = 32, Gas Cost = 1.32 million (for entire transaction) * Quinary Merkle Tree (Poseidon Hash) * Depth = 15, Gas Cost = 1.78 million (for entire transaction) #### `Operation` On-Chain Op Costs * 1 merkle tree insert per spend ~1.3 million gas * 1 batch merkle tree insertion for 8 note commitments ~1.4 mil * 1 batch merkle tree insertion for 16 note commitments is ~1.6mil * 1 proof verification per spend ~200k gas + 21k per pub input * 1 Poseidon hash per refund tx ~50k gas * 1 merkle tree insert per refund tx ~1.3 million gas * 2 contract.balanceOf calls per ERC20 interacted with #### Costs for *n* `Operation`, *m* spends, and *p* refunds * 1 proof verification per spend ~m*(200k + 7*21k) * 1 poseidon hash per refund ~p*50k * 2 transfer and balance calls per asset involved ~4.1k for transfer, ~1.4k for balanceOf (depends on ERC20 impl) * Total estimated overhead (up to 8 note commitments, (m + p) <= 8): ~1.4mil + m*(200k + 7* 21k) + p*50k #### `Operation` Costs In Different Situations: * Assuming **4 operations batched** (n = 4) --- 1 spend and 1 refund per operation (8 total potential note commitments commited in a batch to the merkle tree): * 1.4 million + 4*(200k + 147k) + 4*50k * = ~2.988 million gas for the bundle * = ~747k gas per user operation * Assuming **8 operations batched** (n = 8) --- 1 spend and 1 refund per operation (16 total potential note commitments commited in a batch to the merkle tree): * 1.6 million + 8*(200k + 147k) + 8*50k * = ~4.776 million gas for the bundle * = ~597k gas per user operation * Assuming **8 operations batched** (n=8) with **spend proof aggregation** --- 1 aggregate spend proof, 1 refund per operation (still 16 potential note commitments added to tree between spends and refunds): * 1.6 million + ~350k + 8*50k * = ~2.35 million gas for the bundle * = ~293k gas per user operation * Assuming **8 operations batched** (n=8) with **zk merkle tree updates** and **spend proof aggregation** --- 1 merkle tree update proof, 1 aggregate spend proof, 1 refund per operation: * ~350k + ~350k + 8*50k * = ~1.1 million gas for the bundle * = ~138k gas per user operation ### Proving time estimates Approach 1: 12k constraints, <5s with wasmsnark, per numbers provided here https://github.com/tornadocash/tornado-core/tree/master/circuits Approach 2: 16k constraints, ~5s with wasmsnark ### References * Original FLAX Paper - https://eprint.iacr.org/2021/1249.pdf * If you have questions or are interested jamming together, please reach out to luketchang00@gmail.com

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully