Permissionless Blockchains offer a compelling solution for novel applications that operate in a permissionless environment. However, they currently face a daunting dichotomy - although they’re permissionless, they’re notoriously hard to access. Whereas applications that are native to blockchains are already decentralized, users are unable to interact with them without first acquiring cryptocurrency from a centralized, trusted exchange. The process is tedious and error-prone - users need to send funds to often sparsely regulated entities from their own bank account. Further, processes often take multiple days, and incur unfavourable exchange rate.
The core problem motivating this dichotomy is a mismatch in trust models. Whereas regulatory guardrails usually enforce well behavior in existing financial systems, decentralized systems operate in a hostile environment across multiple jurisdictions without clearly enforcable boundaries. Any solution that offers true decentralization needs to offer strong, baked-in security from the get-go, and thereby demands for a well-designed threat model.
Initial solutions propose solving the Onboarding Problem through decentralized acquisition of cryptocurrencies by relying on a Peer to Peer (P2P) exchange, where the SELLER
of a cryptocurrency embeds a specific amount X
tokens in an escrow smart contract. The BUYER
of a the X
tokens sends Y
amount of FIAT currency to the SELLER
on a legacy platform (e.g. Venmo, bank transfer, etc.), and successively creates a proof $\pi$ that attests that the transaction on the legacy platform has successively been executed.
The proof $\pi$ can be obtained in multiple ways - either through proof that an email confirms the transaction (https://prove.email/), or through a notarization of a TLS session, which can verify the authenticity of TLS data while protecting privacy (https://tlsnotary.org/, i.e. in this case querying the API of the legacy platform to validate the correct execution of transactions, numerous academic works like ORIGO that aim to trade off security assumptions with latency to make this practial).
Why previous solutions do not suffice to solve the Onboarding Problem
Any of the above solutions are only able to realize a general One-Sided Limit-Order Book, where the order book is maintained by the on-chain escrow contract. Users that want to acquire a specific order partially / fully are demanded to be online when executing the transaction - hence they are generally unable to post an ASK
. This is due to the fundamental inability of the above proof techniques to execute a transaction on behalf of the user.
A two-sided limit-order book offers significant advantages that address the above shortcomings in regards to liquidity. By allowing both buyers and sellers to post limit orders, it enhances liquidity and improves price discovery mechanisms. Buyers can post bids and sellers can post asks, enabling the matching of orders without the need for both parties to be online simultaneously. This asynchronous matching increases the efficiency of the market by facilitating smoother transactions and better aligning supply and demand by allowing market makers to make a deterministic profit from the spread.
Additionally, a two-sided order book can mitigate challenges associated with price impact and market manipulation that are more prevalent in one-sided books. The presence of both buy and sell orders creates a more balanced and competitive trading environment, reducing the likelihood of extreme price movements caused by large orders consuming the available liquidity on one side of the book. This balance helps in maintaining fairer prices and provides a more stable market structure, which is particularly important in a P2P onboarding platform where trust and reliability are crucial.
A two-sided limit-order book is only possible if smart contracts are not only able to RECEIVE transfers from legacy payment providers, but if they are also able to SEND transfers, i.e. trigger off-chain transactions based on events that are emitted upon smart contract interaction.
Now, theoretically, this is trivial - a payment provider, like a major bank, remains online consistently, listens to a set of smart contract events, processes a payment, and issues a signature that the payment has been executed correctly, which can be verified in a smart contract. However, this practice would require trust into the centralized payment provider to execute the transaction under the correct conditions, which is fundamentally at odds with the ethos of blockchain and decentralized technologies, which prioritize trustlessness and distributed control.
So what would be measures that can be taken to mitigate this issue?
Approach 1: Custodial - User sends money to a bank. Bank holds USD in a custodial fashion, with a user-determined trigger upon which to process a payment. Smart Contract Event occurs, which triggers the payment. Bank computes a ZKP of SEPA transfer. Bank interacts with Smart Contract, which verifies the proof that SEPA transfer occured.
Approach 2: Non-Custodial - User delegates a secret to a Trusted Execution Environment (TEE), under a pre-described policy which outlines under which condition to utilize the secret to execute a payment. Smart Contract Event occurs, which triggers the TEE to use the secret to execute a payment. Another (or the same) TEE uses another (or the same) secret to continuously trigger the endpoint provided by the payment provider, to check whenever the payment has been executed. Whenever this is the case, the TEE (or TEEs) provide a signature. Smart Contract verifies the proof that off-chain payment occured and acts accordingly.
As a matter of fact, both approaches outlined are complementary. Approach 1 is significantly harder to operationalize, but would have to use the same techniques as Approach 2 to support the described product offering of trustless payment processing.
Figure 1 - Visual Depiction of Approach 2
One of the biggest problems the above solution faces is ensuring the integrity od WRITE
executions based on OAuth2.0. In our first PoC we will aim for clear separation of READ
and WRITE
access. I.e., the scope of operation is simple - a middleware operator can only 1) execute whatever is specfied in the scope or 2) refuse service. Successively, we will explore ways to delegate secrets that do not require a restricted scope, whilst maintaining high integrity guarantees, without relying on TEEs for integrity protection, but only for privacy protection.
Further, there is a lot of nuance in utilizing TEEs - let alone utilizing them in a permissionless network. Especially, if obtaining additional information about trading information can lead to information assymetry and thereby additional malicious but deterministic profits from adversarial actors. Luckily, there is many efforts driving efforts forward on all fronts - from mitigation of memory access patterns with ORAM, to the mistakes that Secret Network already did when deplokying in practice, to first initiatives and open-source tooling that enables decentralized verification of remote attestations and permissionless operation of TEE networks.
Zwift is our approach in tackling the above vision, which enables users to post bids to buy cryptocurrencies in a permissionless setting by leveraging secure computing and programmable, permissionless blockchains. Zwift’s methodology centers around creating a secure, efficient, and user-centric platform for P2P cryptocurrency exchanges with optimal UX and a “one-click” onboarding process.
Figure 2 - Zwift PoC Architecture
Zwift needs several components to work in a seamless fashion. A set of smart contracts that exposes the relevant logic for escrowing funds, and for verifying signatures (contracts
). An indexer
, which fetches emitted smart contract events and writes them to a database. A paypal
backend hosted in a TEE (might be any API the is enabled by OAUTH 2.0). A frontend (zwift-dapp
) which allows posting a BID
or and ASK
to the smart contract and the TEE-enabled backend respectively.
In the following we outline the core component in our architecture - the backend that allows payments through a payment provider by delegating access tokens - in the following relevant steps:
Figure 3 - Registration Flow PayPal Backend
Registration Flow with PayPal. In Zwift, user registration leverages PayPal’s OAuth2 authentication, mediated by a backend running in a Trusted Execution Environment (TEE). The frontend initiates the process by requesting an authorization URL from the backend. The backend, operating securely within the TEE, generates this URL and responds to the frontend. The frontend then redirects the user to PayPal for authentication. After successful login, PayPal returns an authorization code to the frontend, which forwards it to the backend.
Within the TEE, the backend exchanges the authorization code for an access token via PayPal’s API. The access token is used in a one-time operation to fetch the user’s email address. The backend creates a session, uniquely identified within the TEE, and associates it with the user’s email. The session identifier is returned to the frontend, enabling subsequent requests to authenticate the user without requiring repeated interaction with PayPal. By enforcing a strict one-time read and write policy within the TEE, Zwift ensures that sensitive data is handled minimally and securely, aligning with its broader design principles of trust and decentralization.
Figure 4 - Payment Execution PayPal Backend
The checkout process in Zwift manages payment interactions, while adhering to strict separation of read and write operations, leveraging the capabilities of the backend running within a Trusted Execution Environment (TEE). The process begins when the frontend sends a request to the backend to create a new checkout session. The backend, isolated in the TEE, generates a PayPal order by interacting with the PayPal API and returns the order details, including a checkout URL and orderID, to the frontend. The user is redirected to the PayPal checkout URL to complete the payment.
Once the payment is confirmed, PayPal redirects the user back to the frontend, which forwards the orderID to the backend for verification. The backend captures the payment using the orderID through a write operation, ensuring that the transaction is atomically processed. The payment details are then retrieved in a separate read operation to verify the transaction’s status, including seller protection and final capture status. Sensitive details are immediately discarded after use, ensuring that they are not retained in memory or storage.
This strict delineation between read and write operations ensures that any data used in the write path is ephemeral, reducing the attack surface. Additionally, by isolating sensitive operations within the TEE, Zwift ensures that even compromised frontend components cannot tamper with the integrity of payment execution.
Given a two-sided order-book, market makers are incentivized to fulfill trades as they can deterministically make a profit from the spread. The following outlines the profitability in a simple calculation, where a market maker intermediates the liquidity between the SELLER
and BUYER
of a stablecoin.
1. Initial Positions
The market maker (MM) starts with:
- 1,000 USDC in inventory (to sell at $1.0025).
- $1,000 USD in cash (to buy at $0.9975).
2. Transactions Two users interact with the market maker:
User A (Seller) Wants to Sell USDC for USD:
- User A sells 1,000 USDC to the MM at $0.9975/USDC.
- MM's Action: The MM buys 1,000 USDC from User A, paying:
- Amount Paid by MM=1,000×0.9975=997.50 USD
The MM's updated inventory:
USDC: 2,000 (1,000 original + 1,000 bought)
USD: $2.50 (remaining cash after the purchase)
Simplified Payment Flow: MM has PayPal account, executes transaction on PayPal, gets signature from TEE, calls escrow to unlock payment.
User B (Buyer) Wants to Buy USDC with USD:
User B buys 1,000 USDC from the MM at $1.0025/USDC.
MM's Action: The MM sells 1,000 USDC to User B, receiving:
Amount Received by MM=1,000×1.0025=1,002.50 USD
The MM's updated inventory:
USDC: 1,000 (2,000 original - 1,000 sold)
USD: $1,005 (2.50 remaining + 1,002.50 earned)
Simplified Payment Flow: Public onboarding intent exists in off-chain transaction pool to send a paypal tx for $1.0025/USDC. MM has on-chain account, posts offboarding intent for $1.0025/USDC, TEE indexer fetches event emitted by the smart contract, realizes that a matching onboarding intent exists, and autonomously executes the payment in the off-chain payment platform.
For this, the MM needs to interact with the Zwift Smart Contract to publicly reveal 1) the tx that attests successful completion of an off-chain payment and 2) the intent to offboard (ideally both atomically in one block)- another entity could copy the offboard intent, place a tx with higher bid, and frontrun the transaction. It’s important for the MM that the offboarding intent is included 1) swiftly, 2) privately, and 3) with high probability of inclusion. PROF is the only system that provides all 3.
3. Profit Calculation
The MM started with 1,000 USDC and $1,000 USD.
After both transactions, the MM holds:
- 1,000 USDC and $1,005 USD.
Profit from Spread:
Profit = (Sell Price−Buy Price)×Volume Traded
Profit = (1.0025−0.9975)×1,000=0.005×1,000 = 5USD