Skip to content

Commit

Permalink
feat: add Base bridge adapter (#874)
Browse files Browse the repository at this point in the history
* feat: add Base constants/defaults

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* feat: add Base bridge adapter

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* feat: Add ZkSync function to AtomicWethDepositor (#875)

* feat: Add ZkSync function to AtomicWethDepositor

* Update AtomicWethDepositor.sol

* Update AtomicWethDepositor.sol

* Update AtomicWethDepositor.sol

* Update AtomicWethDepositor.sol

* Update AtomicWethDepositor.sol

* Update AtomicWethDepositor.sol

* Update src/clients/bridges/OpStackAdapter.ts

Co-authored-by: nicholaspai <9457025+nicholaspai@users.noreply.github.com>

* new deployment

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* lint

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* updated deployment with Nick's fix

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* lint

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* update address

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* Update contracts/AtomicWethDepositor.sol

Co-authored-by: James Morris, MS <96435344+james-a-morris@users.noreply.github.com>

* Update AtomicWethDepositor.sol

* inherit optimism adapter

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* lint

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* lint

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* restructured

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* fix

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

* WIP

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>

---------

Signed-off-by: Matt Rice <matthewcrice32@gmail.com>
Co-authored-by: nicholaspai <9457025+nicholaspai@users.noreply.github.com>
Co-authored-by: James Morris, MS <96435344+james-a-morris@users.noreply.github.com>
Co-authored-by: nicholaspai <npai.nyc@gmail.com>
  • Loading branch information
4 people committed Aug 18, 2023
1 parent 913dcff commit 6898263
Show file tree
Hide file tree
Showing 25 changed files with 947 additions and 247 deletions.
19 changes: 16 additions & 3 deletions contracts/AtomicWethDepositor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,32 @@ interface ZkSyncL1Bridge {

/**
* @notice Contract deployed on Ethereum helps relay bots atomically unwrap and bridge WETH over the canonical chain
* bridges for OVM chains, ZkSync and Polygon. Needed as these chains only support bridging of ETH, not WETH.
* bridges for Optimism, Base, Boba, ZkSync, and Polygon. Needed as these chains only support bridging of ETH, not WETH.
*/

contract AtomicWethDepositor {
Weth public immutable weth = Weth(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);
OvmL1Bridge public immutable optimismL1Bridge = OvmL1Bridge(0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1);
OvmL1Bridge public immutable bobaL1Bridge = OvmL1Bridge(0xdc1664458d2f0B6090bEa60A8793A4E66c2F1c00);
OvmL1Bridge public immutable baseL1Bridge = OvmL1Bridge(0x3154Cf16ccdb4C6d922629664174b904d80F2C35);
PolygonL1Bridge public immutable polygonL1Bridge = PolygonL1Bridge(0xA0c68C638235ee32657e8f720a23ceC1bFc77C77);
ZkSyncL1Bridge public immutable zkSyncL1Bridge = ZkSyncL1Bridge(0x32400084C286CF3E17e7B677ea9583e60a000324);

event ZkSyncEthDepositInitiated(address indexed from, address indexed to, uint256 amount);

function bridgeWethToOvm(address to, uint256 amount, uint32 l2Gas, uint256 chainId) public {
require(chainId == 10 || chainId == 288, "Can only bridge to Optimism Or boba");
weth.transferFrom(msg.sender, address(this), amount);
weth.withdraw(amount);
(chainId == 10 ? optimismL1Bridge : bobaL1Bridge).depositETHTo{ value: amount }(to, l2Gas, "");

if (chainId == 10) {
optimismL1Bridge.depositETHTo{ value: amount }(to, l2Gas, "");
} else if (chainId == 8453) {
baseL1Bridge.depositETHTo{ value: amount }(to, l2Gas, "");
} else if (chainId == 288) {
bobaL1Bridge.depositETHTo{ value: amount }(to, l2Gas, "");
} else {
revert("Invalid OVM chainId");
}
}

function bridgeWethToPolygon(address to, uint256 amount) public {
Expand Down Expand Up @@ -96,4 +105,8 @@ contract AtomicWethDepositor {
}

fallback() external payable {}

// Included to remove a compilation warning.
// NOTE: this should not affect behavior.
receive() external payable {}
}
18 changes: 18 additions & 0 deletions deploy/001_deploy_atomic_depositor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { DeployFunction } from "hardhat-deploy/types";

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const {
deployments: { deploy },
getNamedAccounts,
} = hre;

const { deployer } = await getNamedAccounts();

await deploy("AtomicWethDepositor", {
from: deployer,
log: true,
skipIfAlreadyDeployed: true,
});
};
module.exports = func;
func.tags = ["AtomicWethDepositor"];
1 change: 1 addition & 0 deletions deployments/mainnet/.chainId
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
232 changes: 232 additions & 0 deletions deployments/mainnet/AtomicWethDepositor.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"language": "Solidity",
"sources": {
"contracts/AtomicWethDepositor.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-only\npragma solidity ^0.8.0;\n\ninterface Weth {\n function withdraw(uint256 _wad) external;\n\n function transferFrom(address _from, address _to, uint256 _wad) external;\n}\n\ninterface OvmL1Bridge {\n function depositETHTo(address _to, uint32 _l2Gas, bytes calldata _data) external payable;\n}\n\ninterface PolygonL1Bridge {\n function depositEtherFor(address _to) external payable;\n}\n\ninterface ZkSyncL1Bridge {\n function requestL2Transaction(\n address _contractL2,\n uint256 _l2Value,\n bytes calldata _calldata,\n uint256 _l2GasLimit,\n uint256 _l2GasPerPubdataByteLimit,\n bytes[] calldata _factoryDeps,\n address _refundRecipient\n ) external payable;\n\n function l2TransactionBaseCost(\n uint256 _gasPrice,\n uint256 _l2GasLimit,\n uint256 _l2GasPerPubdataByteLimit\n ) external pure returns (uint256);\n}\n\n/**\n * @notice Contract deployed on Ethereum helps relay bots atomically unwrap and bridge WETH over the canonical chain\n * bridges for OVM chains, ZkSync and Polygon. Needed as these chains only support bridging of ETH, not WETH.\n */\n\ncontract AtomicWethDepositor {\n Weth public immutable weth = Weth(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2);\n OvmL1Bridge public immutable optimismL1Bridge = OvmL1Bridge(0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1);\n OvmL1Bridge public immutable bobaL1Bridge = OvmL1Bridge(0xdc1664458d2f0B6090bEa60A8793A4E66c2F1c00);\n OvmL1Bridge public immutable baseL1Bridge = OvmL1Bridge(0x3154Cf16ccdb4C6d922629664174b904d80F2C35);\n PolygonL1Bridge public immutable polygonL1Bridge = PolygonL1Bridge(0xA0c68C638235ee32657e8f720a23ceC1bFc77C77);\n ZkSyncL1Bridge public immutable zkSyncL1Bridge = ZkSyncL1Bridge(0x32400084C286CF3E17e7B677ea9583e60a000324);\n\n event ZkSyncEthDepositInitiated(address indexed from, address indexed to, uint256 amount);\n\n function bridgeWethToOvm(address to, uint256 amount, uint32 l2Gas, uint256 chainId) public {\n weth.transferFrom(msg.sender, address(this), amount);\n weth.withdraw(amount);\n\n if (chainId == 10) {\n optimismL1Bridge.depositETHTo{ value: amount }(to, l2Gas, \"\");\n } else if (chainId == 8453) {\n baseL1Bridge.depositETHTo{ value: amount }(to, l2Gas, \"\");\n } else if (chainId == 288) {\n bobaL1Bridge.depositETHTo{ value: amount }(to, l2Gas, \"\");\n } else {\n revert(\"Invalid OVM chainId\");\n }\n }\n\n function bridgeWethToPolygon(address to, uint256 amount) public {\n weth.transferFrom(msg.sender, address(this), amount);\n weth.withdraw(amount);\n polygonL1Bridge.depositEtherFor{ value: amount }(to);\n }\n\n function bridgeWethToZkSync(\n address to,\n uint256 amount,\n uint256 l2GasLimit,\n uint256 l2GasPerPubdataByteLimit,\n address refundRecipient\n ) public {\n // The ZkSync Mailbox contract checks that the msg.value of the transaction is enough to cover the transaction base\n // cost. The transaction base cost can be queried from the Mailbox by passing in an L1 \"executed\" gas price,\n // which is the priority fee plus base fee. This is the same as calling tx.gasprice on-chain as the Mailbox\n // contract does here:\n // https://github.com/matter-labs/era-contracts/blob/3a4506522aaef81485d8abb96f5a6394bd2ba69e/ethereum/contracts/zksync/facets/Mailbox.sol#L287\n uint256 l2TransactionBaseCost = zkSyncL1Bridge.l2TransactionBaseCost(\n tx.gasprice,\n l2GasLimit,\n l2GasPerPubdataByteLimit\n );\n uint256 valueToSubmitXChainMessage = l2TransactionBaseCost + amount;\n weth.transferFrom(msg.sender, address(this), valueToSubmitXChainMessage);\n weth.withdraw(valueToSubmitXChainMessage);\n zkSyncL1Bridge.requestL2Transaction{ value: valueToSubmitXChainMessage }(\n to,\n amount,\n \"\",\n l2GasLimit,\n l2GasPerPubdataByteLimit,\n new bytes[](0),\n refundRecipient\n );\n\n // Emit an event that we can easily track in the ZkSyncAdapter because otherwise there is no easy event to\n // track ETH deposit initiations.\n emit ZkSyncEthDepositInitiated(msg.sender, to, amount);\n }\n\n fallback() external payable {}\n\n receive() external payable {}\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 1000000
},
"viaIR": true,
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": ["ast"]
}
},
"metadata": {
"useLiteralContent": true
}
}
}
6 changes: 6 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ const config: HardhatUserConfig = {
},
networks: {
hardhat: { accounts: { accountsBalance: "1000000000000000000000000" } },
mainnet: {
url: getNodeUrl("mainnet", true, 1),
accounts: { mnemonic },
saveDeployments: true,
chainId: 1,
},
kovan: {
url: getNodeUrl("kovan", true, 42),
accounts: { mnemonic },
Expand Down
4 changes: 4 additions & 0 deletions src/clients/bridges/AdapterManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { SpokePoolClient, HubPoolClient } from "../";
import { OptimismAdapter, ArbitrumAdapter, PolygonAdapter, BaseAdapter, ZKSyncAdapter } from "./";
import { OutstandingTransfers } from "../../interfaces";
import { utils } from "@across-protocol/sdk-v2";
import { BaseChainAdapter } from "./op-stack/base/BaseChainAdapter";
export class AdapterManager {
public adapters: { [chainId: number]: BaseAdapter } = {};

Expand Down Expand Up @@ -36,6 +37,9 @@ export class AdapterManager {
if (this.spokePoolClients[324] !== undefined) {
this.adapters[324] = new ZKSyncAdapter(logger, spokePoolClients, monitoredAddresses);
}
if (this.spokePoolClients[8453] !== undefined) {
this.adapters[8453] = new BaseChainAdapter(logger, spokePoolClients, monitoredAddresses);
}

logger.debug({
at: "AdapterManager#constructor",
Expand Down
1 change: 1 addition & 0 deletions src/clients/bridges/BaseAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ interface Events {

const { TOKEN_SYMBOLS_MAP } = sdkConstants;

// TODO: make these generic arguments to BaseAdapter.
type SupportedL1Token = string;
type SupportedTokenSymbol = string;

Expand Down
237 changes: 0 additions & 237 deletions src/clients/bridges/OptimismAdapter.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/clients/bridges/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from "./BaseAdapter";
export * from "./AdapterManager";
export * from "./OptimismAdapter";
export * from "./op-stack/optimism/OptimismAdapter";
export * from "./ArbitrumAdapter";
export * from "./PolygonAdapter";
export * from "./CrossChainTransferClient";
Expand Down
Loading

0 comments on commit 6898263

Please sign in to comment.