-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into add-signer-for-ledger-live-app
- Loading branch information
Showing
1 changed file
with
252 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
:toc: macro | ||
|
||
= RFC 11: Solana tBTC | ||
|
||
:icons: font | ||
:numbered: | ||
toc::[] | ||
|
||
== Background | ||
|
||
There is a clear massive demand funnel present in Solana ecosystem for tBTC. | ||
This RFC aims at providing a bespoke user experience for minting tBTC on Solana. | ||
|
||
=== Current functionality | ||
|
||
Even today it is possible to bridge tBTC to Solana with Wormhole. The whole user | ||
experience is far from perfect, though. | ||
|
||
First, the user has to deposit their BTC using Threshold Dashboard on Ethereum. | ||
This requires executing one Ethereum transaction. Next, once tBTC is minted on | ||
Ethereum, the user has to go to the Wormhole Token Bridge portal and bridge | ||
their Ethereum tBTC to Solana. This requires several transactions - one | ||
transaction on Ethereum and several transactions on Solana. | ||
|
||
There is a significant cognitive effort on the user's side. Users are required | ||
to use two applications and execute transactions on three networks: Bitcoin, | ||
Ethereum, and Solana between them. Moreover, there is a period of time between | ||
the time BTC was deposited and the time tBTC is minted on Ethereum that requires | ||
the user to wait idly before they can bridge their Ethereum tBTC to Solana. | ||
|
||
== Proposal | ||
|
||
=== Goal | ||
|
||
Users should mint tBTC on Solana in the Threshold Dashboard with two | ||
transactions: one transaction on BTC and one transaction on Solana. | ||
|
||
The redemption process should require just one Solana transaction from the user | ||
executed in the Threshold Dashboard. | ||
|
||
=== Implementation | ||
|
||
The implementation is based on the Wormhole token bridge and does not require | ||
the off-chain client to work with Solana. Ethereum `Bank` contract remains | ||
the center of the gravity of tBTC bridge and tBTC token is still minted | ||
"centrally" on Ethereum. | ||
|
||
There are two main design challenges. The first challenge is how to represent | ||
32-byte Solana addresses in the process of depositing and redeeming. The entire | ||
design of the Bridge is oriented around 20-byte Ethereum addresses. Bridge | ||
expects a 20-byte depositor address in the reveal function and passes 20-byte | ||
depositor addresses to the Bank when providing the sweep proof. The second | ||
challenge is optimistic minting. Only `TBTCVault` can mint tBTC and the | ||
optimistic minting has to happen in `TBTCVault`. Having another vault be | ||
responsible for Solana minting and bridging would mean we have to tightly couple | ||
vaults together, complicate optimistic minting code, or not allow for optimistic | ||
minting on Solana at all. | ||
|
||
The proposed design is oriented around a depositor contract that will reveal | ||
deposits to the bridge, map Solana addresses with revealed deposits, receive | ||
tBTC (optimistically minted or not), and perform bridging to Solana. | ||
|
||
==== P2SH deposit script | ||
|
||
The P2SH deposit script has to be enhanced to include optional extra data. The | ||
extra data will be used by depositors who are smart contracts. In the context of | ||
this proposal, we will use the extra data to associate the Bitcoin deposit with | ||
an address on a foreign (non-Ethereum) chain. | ||
|
||
``` | ||
<depositor-address> DROP | ||
<depositor-extra-data> DROP | ||
<blinding-factor> DROP | ||
DUP HASH160 <signingGroupPubkeyHash> EQUAL | ||
IF | ||
CHECKSIG | ||
ELSE | ||
DUP HASH160 <refundPubkeyHash> EQUALVERIFY | ||
<locktime> CHECKLOCKTIMEVERIFY DROP | ||
CHECKSIG | ||
ENDIF | ||
``` | ||
|
||
==== Reveal with depositor extra data | ||
|
||
`DepositRevealInfo` struct will gain an additional optional field. Since this | ||
structure is not persisted in the storage, the new field is not a concern for | ||
the contract upgrade: | ||
|
||
``` | ||
/// @notice Represents data which must be revealed by the depositor during | ||
/// deposit reveal. | ||
struct DepositRevealInfo { | ||
// (...) | ||
|
||
// Optional extra data used by depositors who are smart contracts. The smart | ||
// contract depositor can use the extra data to represent additional | ||
// information, such as the depositor's address on a foreign (non-Ethereum) | ||
// chain. | ||
bytes32 depositorExtraData; | ||
// This struct doesn't contain `__gap` property as the structure is not | ||
// stored, it is used as a function's calldata argument. | ||
} | ||
``` | ||
|
||
The `DepositRequest` function will gain the same field. Since mapping values are | ||
stored in different slots we only need to make sure the new field comes after | ||
the existing ones to address upgradeability concerns. | ||
|
||
``` | ||
/// @notice Represents tBTC deposit request data. | ||
struct DepositRequest { | ||
// (...) | ||
|
||
// Optional extra data used by depositors who are smart contracts. The smart | ||
// contract depositor can use the extra data to represent additional | ||
// information, such as the depositor's address on a foreign (non-Ethereum) | ||
// chain. | ||
bytes32 depositorExtraData; | ||
} | ||
``` | ||
|
||
To maintain backward compatibility with the existing deposit flow, we will | ||
implement another reveal function in the `Bridge` contract. The function will be | ||
mostly identical to the existing `revealDeposit` except that it will respect the | ||
alternative P2SH deposit script version allowing to pass 32 bytes of extra data. | ||
The extra data will not be stored in the Bridge. It is the depositor's | ||
responsibility to make the use of them. | ||
|
||
==== Solana gateway | ||
|
||
`SolanaGateway` contract will be deployed on Solana and should be placed in | ||
`tbtc-v2/cross-chain/solana` project. The contract will communicate with | ||
Ethereum L1 using link:https://docs.wormhole.com/wormhole/explore-wormhole/vaa[Wormhole VAAs (Verified Action Approvals)] | ||
to reveal Bitcoin deposits. The contract will use Wormhole Token Bridge to | ||
request Bitcoin redemption on Ethereum. | ||
|
||
For the implementation, we should consider using the | ||
link:https://solang.readthedocs.io/en/latest/index.html[Solang compiler]. | ||
|
||
The contract needs to be upgradeable. | ||
|
||
==== Solana depositor | ||
|
||
`SolanaDepositor` contract will act as tBTC depositor on Ethereum and should | ||
be placed in `tbtc-v2/solidity` project. The contract will receive Wormhole VAAs | ||
from Solana and reveal Bitcoin deposits to the tBTC `Bridge` contract. The | ||
contract will map the revealed deposit to the Solana address. It will also | ||
bridge the received tBTC once the deposit is swept or tBTC is optimistically | ||
minted. | ||
|
||
This contract needs to have a reference to the `TBTCVault` to inspect the | ||
`optimisticMintingRequests` mapping and to the `Bridge` to inspect the | ||
`deposits` mapping to confirm the state when it is notified tBTC has been minted | ||
for the given deposit. | ||
|
||
The contract needs to be upgradeable. | ||
|
||
==== Solana redeemer | ||
|
||
`SolanaRedeemer` contract will act as tBTC redeemer on Ethereum and should be | ||
placed in `tbtc-v2/solidity` project. The contract will receive tBTC from Solana | ||
via Wormhole Token Bridge and request redemption in the tBTC `Bridge` contract. | ||
|
||
The contract needs to be upgradeable. | ||
|
||
==== Relayer bot | ||
|
||
To optimize the user experience, a relayer bot needs to be implemented. The | ||
relayer's responsibility will be: | ||
|
||
- Deliver Wormhole VAA to `SolanaDepositor` contract once the deposit was | ||
revealed on Solana. | ||
- Request bridging tBTC from Ethereum to Solana once the tBTC for the deposit | ||
has been optimistically minted or the deposit was swept on Bitcoin and the | ||
SPV sweep proof was submitted to Ethereum. | ||
- Redeem bridged tBTC on Solana from the Wormhole Token Bridge contract to the | ||
depositor address once the tBTC minted on Ethereum has been successfully | ||
bridged to Solana. | ||
- Redeem bridged tBTC on Ethereum from the Wormhole Token Bridge contract to the | ||
`SolanaRedeemer` contract once the redemption was requested on Solana and | ||
tBTC was bridged back via the Wormhole Token Bridge. | ||
|
||
==== Optimistic minting changes | ||
|
||
Currently, the optimistic minting fee is evaluated at the moment of finalizing | ||
the mint. The `SolanaDepositor` needs to know how much tBTC should be bridged to | ||
Solana to the given depositor address. To evaluate the amount, the | ||
`SolanaDepositor` contract needs to know if the deposit was optimistically | ||
minted and what was the fee during the mint. The `OptimisticMintingRequest` | ||
struct has to be enhanced with fee information captured at the moment of | ||
requesting or finalizing the mint. | ||
|
||
==== Deposit flow | ||
|
||
From the user's perspective: | ||
|
||
1. The user generates a Bitcoin deposit address in the Threshold Dashboard. | ||
2. The user makes a Bitcoin deposit. | ||
3. The user reveals their deposit with transaction on Solana in the Threshold | ||
Dashboard. | ||
4. After some time, the user receives their tBTC under the Solana address. | ||
|
||
With smart contract interactions: | ||
|
||
1. The user generates a Bitcoin deposit address in the Threshold Dashboard. | ||
2. The user makes a Bitcoin deposit. | ||
3. The user reveals their deposit with transaction on Solana in the Threshold | ||
Dashboard. | ||
4. `SolanaGateway` contract sends Wormhole VAA from Solana to Ethereum informing | ||
about the revealed deposit. | ||
5. Relayer bot submits the Wormhole VAA on Ethereum to the `SolanaDepositor` | ||
contract. | ||
6. `SolanaDepositor` contract evaluates `depositID = keccak256(fundingTxHash | fundingOutputIndex)` | ||
and associates it with Solana depositor address. | ||
7. `SolanaDepositor` contract reveals the deposit to the `Bridge` | ||
8. tBTC is optimistically minted to `SolanaDepositor` contract address. | ||
9. Relayer bot notifies `SolanaDepositor` contract the deposit was | ||
optimistically minted. `SolanaDepositor` inspects `TBTCVault.optimisticMintingRequests` | ||
to confirm the amount and requests bridging tBTC from its own balance to the | ||
Solana depositor address associated with the given deposit using Wormhole | ||
Token Bridge. The same happens when the deposit was not optimistically minted | ||
but swept. | ||
10. Relayer bot redeems the tBTC bridged to Solana from the Wormhole Token Bridge | ||
contract to the depositor's Solana address. | ||
11. The user reveals their tBTC under the Solana address. | ||
|
||
==== Redemption flow | ||
|
||
From the user's perspective: | ||
|
||
1. The user requests redemption on Solana sending their tBTC to a smart contract. | ||
2. After some time, the user receives their BTC to the address they provided. | ||
|
||
With smart contract interactions: | ||
|
||
1. The user requests redemption on Solana sending their tBTC to a smart contract. | ||
2. `SolanaGateway` takes the tBTC from the user and bridges tBTC back to | ||
Ethereum using Wormhole Token Bridge and `transferTokensWithPayload` passing | ||
the BTC redemption address as a payload. | ||
3. The relayer bot redeems tBTC on Ethereum from the Wormhole Token Bridge | ||
contract to the `SolanaRedeemer` contract. | ||
4. `SolanaRedeemer` contract uses the received tBTC to request redemption in the | ||
tBTC `Bridge` contract using the BTC address obtained from the payload. | ||
5. After some time, the user receives their BTC to the address they provided. | ||
|
||
=== Future work | ||
|
||
This RFC does not explore: | ||
- UX of the Threshold Dashboard and how to integrate Solana wallet. | ||
- How the relayer bot is being paid for transactions. | ||
- The recovery path in `SolanaRedeemer` when the redemption request timed out. |