-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Draft implementation of the
L2BitcoinDepositor
contract
Here we present a draft implementation of the `L2BitcoinDepositor` contract that acts as an entrypoint of the tBTC direct bridging feature on the given L2 chain. This contract exposes the `initializeDeposit` function that takes the deposit data (funding tx, reveal info, original depositor) and relays it to the `L1BitcoinDepositor` contract using the Wormhole Relayer infrastructure.
- Loading branch information
1 parent
9e047d1
commit dbeb072
Showing
1 changed file
with
139 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,139 @@ | ||
// SPDX-License-Identifier: GPL-3.0-only | ||
|
||
// ██████████████ ▐████▌ ██████████████ | ||
// ██████████████ ▐████▌ ██████████████ | ||
// ▐████▌ ▐████▌ | ||
// ▐████▌ ▐████▌ | ||
// ██████████████ ▐████▌ ██████████████ | ||
// ██████████████ ▐████▌ ██████████████ | ||
// ▐████▌ ▐████▌ | ||
// ▐████▌ ▐████▌ | ||
// ▐████▌ ▐████▌ | ||
// ▐████▌ ▐████▌ | ||
// ▐████▌ ▐████▌ | ||
// ▐████▌ ▐████▌ | ||
|
||
pragma solidity ^0.8.17; | ||
|
||
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; | ||
|
||
import "../integrator/IBridge.sol"; | ||
|
||
/// @title IWormholeRelayer | ||
/// @notice Wormhole Relayer interface. Contains only selected functions | ||
/// used by L2BitcoinDepositor. | ||
/// @dev See: https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/2b7db51f99b49eda99b44f4a044e751cb0b2e8ea/src/interfaces/IWormholeRelayer.sol#L74 | ||
interface IWormholeRelayer { | ||
/// @dev See: https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/2b7db51f99b49eda99b44f4a044e751cb0b2e8ea/src/interfaces/IWormholeRelayer.sol#L122 | ||
function sendPayloadToEvm( | ||
uint16 targetChain, | ||
address targetAddress, | ||
bytes memory payload, | ||
uint256 receiverValue, | ||
uint256 gasLimit, | ||
uint16 refundChain, | ||
address refundAddress | ||
) external payable returns (uint64 sequence); | ||
|
||
/// @dev See: https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/2b7db51f99b49eda99b44f4a044e751cb0b2e8ea/src/interfaces/IWormholeRelayer.sol#L442 | ||
function quoteEVMDeliveryPrice( | ||
uint16 targetChain, | ||
uint256 receiverValue, | ||
uint256 gasLimit | ||
) | ||
external | ||
view | ||
returns ( | ||
uint256 nativePriceQuote, | ||
uint256 targetChainRefundPerGasUnused | ||
); | ||
} | ||
|
||
// TODO: Document this contract. | ||
contract L2BitcoinDepositor is OwnableUpgradeable { | ||
// TODO: Document state variables. | ||
IWormholeRelayer public wormholeRelayer; | ||
uint16 public l2ChainId; | ||
uint16 public l1ChainId; | ||
address public l1BitcoinDepositor; | ||
uint256 public l1InitializeDepositGasLimit; | ||
|
||
event DepositInitialized( | ||
bytes32 payloadHash, | ||
uint64 sequence, | ||
address indexed depositOwner, | ||
address indexed sender | ||
); | ||
|
||
event L1InitializeDepositGasLimitUpdated(uint256 l1InitializeDepositGasLimit); | ||
|
||
/// @custom:oz-upgrades-unsafe-allow constructor | ||
constructor() { | ||
_disableInitializers(); | ||
} | ||
|
||
function initialize( | ||
address _wormholeRelayer, | ||
uint16 _l2ChainId, | ||
uint16 _l1ChainId, | ||
address _l1BitcoinDepositor | ||
) external initializer { | ||
__Ownable_init(); | ||
|
||
wormholeRelayer = IWormholeRelayer(_wormholeRelayer); | ||
l2ChainId = _l2ChainId; | ||
l1ChainId = _l1ChainId; | ||
l1BitcoinDepositor = _l1BitcoinDepositor; | ||
l1InitializeDepositGasLimit = 200_000; | ||
} | ||
|
||
// TODO: Document this function. | ||
function updateL1InitializeDepositGasLimit(uint256 _l1InitializeDepositGasLimit) | ||
external | ||
onlyOwner | ||
{ | ||
l1InitializeDepositGasLimit = _l1InitializeDepositGasLimit; | ||
emit L1InitializeDepositGasLimitUpdated(_l1InitializeDepositGasLimit); | ||
} | ||
|
||
// TODO: Document this function. | ||
function initializeDeposit( | ||
IBridgeTypes.BitcoinTxInfo calldata fundingTx, | ||
IBridgeTypes.DepositRevealInfo calldata reveal, | ||
address depositOwner | ||
) external payable { | ||
// Cost of requesting a `initializeDeposit` message to be sent to | ||
// `l1Chain` with a gasLimit of `l1InitializeDepositGasLimit`. | ||
uint256 cost = quoteInitializeDeposit(); | ||
|
||
require(msg.value == cost, "Payment for Wormhole Relayer is too low"); | ||
|
||
bytes memory payload = abi.encode(fundingTx, reveal, depositOwner); | ||
|
||
uint64 sequence = wormholeRelayer.sendPayloadToEvm{value: cost}( | ||
l1ChainId, | ||
l1BitcoinDepositor, | ||
payload, | ||
0, // No receiver value needed. | ||
l1InitializeDepositGasLimit, | ||
l2ChainId, // Set this L2 chain as the refund chain. | ||
msg.sender // Set the caller as the refund receiver. | ||
); | ||
|
||
emit DepositInitialized( | ||
keccak256(payload), | ||
sequence, | ||
depositOwner, | ||
msg.sender | ||
); | ||
} | ||
|
||
// TODO: Document this function. | ||
function quoteInitializeDeposit() public view returns (uint256 cost) { | ||
(cost, ) = wormholeRelayer.quoteEVMDeliveryPrice( | ||
l1ChainId, | ||
0, // No receiver value needed. | ||
l1InitializeDepositGasLimit | ||
); | ||
} | ||
} |