diff --git a/contracts/chain-adapters/ZkStack_Adapter.sol b/contracts/chain-adapters/ZkStack_Adapter.sol index 2bd0fa215..c8ebe76ba 100644 --- a/contracts/chain-adapters/ZkStack_Adapter.sol +++ b/contracts/chain-adapters/ZkStack_Adapter.sol @@ -198,8 +198,8 @@ contract ZkStack_Adapter is AdapterInterface, CircleCCTPAdapter { } } else { // An standard bridged ERC20, separate from WETH and Circle Bridged/Native USDC. - address sharedBridge = BRIDGE_HUB.sharedBridge(); - IERC20(l1Token).forceApprove(sharedBridge, amount); + address assetRouter = BRIDGE_HUB.assetRouter(); + IERC20(l1Token).forceApprove(assetRouter, amount); txHash = BRIDGE_HUB.requestL2TransactionTwoBridges{ value: txBaseCost }( BridgeHubInterface.L2TransactionRequestTwoBridgesOuter({ chainId: CHAIN_ID, @@ -208,7 +208,7 @@ contract ZkStack_Adapter is AdapterInterface, CircleCCTPAdapter { l2GasLimit: L2_GAS_LIMIT, l2GasPerPubdataByteLimit: L1_GAS_TO_L2_GAS_PER_PUB_DATA_LIMIT, refundRecipient: L2_REFUND_ADDRESS, - secondBridgeAddress: sharedBridge, + secondBridgeAddress: assetRouter, secondBridgeValue: 0, secondBridgeCalldata: _secondBridgeCalldata(to, l1Token, amount) }) diff --git a/contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol b/contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol index fbaae1513..97de2dacd 100644 --- a/contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol +++ b/contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol @@ -146,7 +146,7 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter { */ function relayMessage(address target, bytes memory message) external payable override { uint256 txBaseCost = _pullCustomGas(L2_GAS_LIMIT); - IERC20(CUSTOM_GAS_TOKEN).forceApprove(BRIDGE_HUB.sharedBridge(), txBaseCost); + IERC20(CUSTOM_GAS_TOKEN).forceApprove(BRIDGE_HUB.assetRouter(), txBaseCost); BRIDGE_HUB.requestL2TransactionDirect( BridgeHubInterface.L2TransactionRequestDirect({ @@ -180,7 +180,7 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter { address to ) external payable override { // The Hub Pool will always bridge via CCTP to a ZkStack network if CCTP is enabled for that network. Therefore, we can short-circuit ZkStack-specific logic - // like pulling custom gas or getting the shared bridge address if CCTP is enabled and we are bridging USDC. + // like pulling custom gas or getting the asset router address if CCTP is enabled and we are bridging USDC. if (l1Token == address(usdcToken) && _isCCTPEnabled()) { _transferUsdc(to, amount); emit TokensRelayed(l1Token, l2Token, amount, to); @@ -189,16 +189,16 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter { // A bypass proxy seems to no longer be needed to avoid deposit limits. The tracking of these limits seems to be deprecated. // See: https://github.com/matter-labs/era-contracts/blob/bce4b2d0f34bd87f1aaadd291772935afb1c3bd6/l1-contracts/contracts/bridge/L1ERC20Bridge.sol#L54-L55 uint256 txBaseCost = _pullCustomGas(L2_GAS_LIMIT); - address sharedBridge = BRIDGE_HUB.sharedBridge(); + address assetRouter = BRIDGE_HUB.assetRouter(); bytes32 txHash; if (l1Token == address(L1_WETH)) { // If the l1Token is WETH then unwrap it to ETH then send the ETH to the standard bridge along with the base // cost of custom gas tokens. L1_WETH.withdraw(amount); - IERC20(CUSTOM_GAS_TOKEN).forceApprove(sharedBridge, txBaseCost); - // Note: When bridging ETH with `L2TransactionRequestTwoBridgesOuter`, the second bridge must be 0 for the shared bridge call to not revert. - // https://github.com/matter-labs/era-contracts/blob/aafee035db892689df3f7afe4b89fd6467a39313/l1-contracts/contracts/bridge/L1SharedBridge.sol#L328 + IERC20(CUSTOM_GAS_TOKEN).forceApprove(assetRouter, txBaseCost); + // Note: When bridging ETH with `L2TransactionRequestTwoBridgesOuter`, the second bridge must be 0 for the asset router call to not revert. + // https://github.com/matter-labs/era-contracts/blob/aafee035db892689df3f7afe4b89fd6467a39313/l1-contracts/contracts/bridge/L1AssetRouter.sol#L328 txHash = BRIDGE_HUB.requestL2TransactionTwoBridges{ value: amount }( BridgeHubInterface.L2TransactionRequestTwoBridgesOuter({ chainId: CHAIN_ID, @@ -207,14 +207,14 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter { l2GasLimit: L2_GAS_LIMIT, l2GasPerPubdataByteLimit: L1_GAS_TO_L2_GAS_PER_PUB_DATA_LIMIT, refundRecipient: L2_REFUND_ADDRESS, - secondBridgeAddress: sharedBridge, + secondBridgeAddress: assetRouter, secondBridgeValue: amount, secondBridgeCalldata: _secondBridgeCalldata(to, ETH_TOKEN_ADDRESS, 0) }) ); } else if (l1Token == CUSTOM_GAS_TOKEN) { // The chain's custom gas token. - IERC20(l1Token).forceApprove(sharedBridge, txBaseCost + amount); + IERC20(l1Token).forceApprove(assetRouter, txBaseCost + amount); txHash = BRIDGE_HUB.requestL2TransactionDirect( BridgeHubInterface.L2TransactionRequestDirect({ chainId: CHAIN_ID, @@ -230,7 +230,7 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter { ); } else if (l1Token == address(usdcToken)) { // Since we already checked if we are bridging USDC via CCTP, if this conditional is hit, then we must be bridging USDC via the `USDC_SHARED_BRIDGE`. - IERC20(CUSTOM_GAS_TOKEN).forceApprove(sharedBridge, txBaseCost); + IERC20(CUSTOM_GAS_TOKEN).forceApprove(assetRouter, txBaseCost); IERC20(l1Token).forceApprove(USDC_SHARED_BRIDGE, amount); txHash = BRIDGE_HUB.requestL2TransactionTwoBridges( BridgeHubInterface.L2TransactionRequestTwoBridgesOuter({ @@ -247,8 +247,8 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter { ); } else { // An standard bridged ERC20, separate from WETH and Circle Bridged/Native USDC. - IERC20(CUSTOM_GAS_TOKEN).forceApprove(sharedBridge, txBaseCost); - IERC20(l1Token).forceApprove(sharedBridge, amount); + IERC20(CUSTOM_GAS_TOKEN).forceApprove(assetRouter, txBaseCost); + IERC20(l1Token).forceApprove(assetRouter, amount); txHash = BRIDGE_HUB.requestL2TransactionTwoBridges( BridgeHubInterface.L2TransactionRequestTwoBridgesOuter({ chainId: CHAIN_ID, @@ -257,7 +257,7 @@ contract ZkStack_CustomGasToken_Adapter is AdapterInterface, CircleCCTPAdapter { l2GasLimit: L2_GAS_LIMIT, l2GasPerPubdataByteLimit: L1_GAS_TO_L2_GAS_PER_PUB_DATA_LIMIT, refundRecipient: L2_REFUND_ADDRESS, - secondBridgeAddress: sharedBridge, + secondBridgeAddress: assetRouter, secondBridgeValue: 0, secondBridgeCalldata: _secondBridgeCalldata(to, l1Token, amount) }) diff --git a/contracts/interfaces/ZkStackBridgeHub.sol b/contracts/interfaces/ZkStackBridgeHub.sol index 91c0e07b0..441a3e490 100644 --- a/contracts/interfaces/ZkStackBridgeHub.sol +++ b/contracts/interfaces/ZkStackBridgeHub.sol @@ -19,9 +19,9 @@ interface BridgeHubInterface { } /** - * @notice the mailbox is called directly after the sharedBridge received the deposit. + * @notice the mailbox is called directly after the asset router received the deposit. * This assumes that either ether is the base token or the msg.sender has approved mintValue allowance for the - * sharedBridge. This means this is not ideal for contract calls, as the contract would have to handle token + * asset router. This means this is not ideal for contract calls, as the contract would have to handle token * allowance of the base Token. * @param _request the direct request. */ @@ -42,9 +42,9 @@ interface BridgeHubInterface { } /** - * @notice After depositing funds to the sharedBridge, the secondBridge is called to return the actual L2 message + * @notice After depositing funds to the asset router, the secondBridge is called to return the actual L2 message * which is sent to the Mailbox. This assumes that either ether is the base token or the msg.sender has approved - * the sharedBridge with the mintValue, and also the necessary approvals are given for the second bridge. The logic + * the asset router with the mintValue, and also the necessary approvals are given for the second bridge. The logic * of this bridge is to allow easy depositing for bridges. Each contract that handles the users ERC20 tokens needs * approvals from the user, this contract allows the user to approve for each token only its respective bridge. * This function is great for contract calls to L2, the secondBridge can be any contract. @@ -55,10 +55,10 @@ interface BridgeHubInterface { ) external payable returns (bytes32 canonicalTxHash); /** - * @notice Gets the shared bridge. - * @dev The shared bridge manages ERC20 tokens. + * @notice Gets the asset router. + * @dev The asset router manages ERC20 tokens. */ - function sharedBridge() external view returns (address); + function assetRouter() external view returns (address); /** * @notice Gets the base token for a chain. diff --git a/contracts/test/MockZkStackBridgeHub.sol b/contracts/test/MockZkStackBridgeHub.sol index 336472de2..559980937 100644 --- a/contracts/test/MockZkStackBridgeHub.sol +++ b/contracts/test/MockZkStackBridgeHub.sol @@ -4,10 +4,10 @@ pragma solidity ^0.8.0; import { BridgeHubInterface } from "../interfaces/ZkStackBridgeHub.sol"; contract MockBridgeHub is BridgeHubInterface { - address public immutable sharedBridge; + address public immutable assetRouter; - constructor(address _sharedBridge) { - sharedBridge = _sharedBridge; + constructor(address _assetRouter) { + assetRouter = _assetRouter; } mapping(uint256 => address) baseTokens; diff --git a/test/evm/foundry/local/ZkStack_Adapter.t.sol b/test/evm/foundry/local/ZkStack_Adapter.t.sol index 504c5a41d..fcaa5168c 100644 --- a/test/evm/foundry/local/ZkStack_Adapter.t.sol +++ b/test/evm/foundry/local/ZkStack_Adapter.t.sol @@ -9,7 +9,10 @@ import { IL1StandardBridge } from "@eth-optimism/contracts/L1/messaging/IL1Stand import { FinderInterface } from "../../../../contracts/external/uma/core/contracts/data-verification-mechanism/interfaces/FinderInterface.sol"; import { ZkStack_Adapter } from "../../../../contracts/chain-adapters/ZkStack_Adapter.sol"; -import { ZkStack_CustomGasToken_Adapter, FunderInterface } from "../../../../contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol"; +import { + ZkStack_CustomGasToken_Adapter, + FunderInterface +} from "../../../../contracts/chain-adapters/ZkStack_CustomGasToken_Adapter.sol"; import { AdapterInterface } from "../../../../contracts/chain-adapters/interfaces/AdapterInterface.sol"; import { WETH9Interface } from "../../../../contracts/external/interfaces/WETH9Interface.sol"; import { WETH9 } from "../../../../contracts/external/WETH9.sol"; @@ -116,7 +119,7 @@ contract ZkStackAdapterTest is Test { MockBridgeHub bridgeHub; address owner; - address sharedBridge; + address assetRouter; address usdcSharedBridge; uint256 baseCost; @@ -127,8 +130,8 @@ contract ZkStackAdapterTest is Test { function setUp() public { owner = makeAddr("owner"); - sharedBridge = makeAddr("sharedBridge"); - usdcSharedBridge = makeAddr("sharedBridge"); + assetRouter = makeAddr("assetRouter"); + usdcSharedBridge = makeAddr("usdcSharedBridge"); l1Token = new Token_ERC20("l1Token", "l1Token"); l2Token = new Token_ERC20("l2Token", "l2Token"); @@ -140,7 +143,7 @@ contract ZkStackAdapterTest is Test { l2Weth = new WETH9(); MockFunder funder = new MockFunder(); - bridgeHub = new MockBridgeHub(sharedBridge); + bridgeHub = new MockBridgeHub(assetRouter); bridgeHub.setBaseToken(ZK_ALT_CHAIN_ID, address(l1CustomGasToken)); baseCost = bridgeHub.l2TransactionBaseCost(0, 0, L2_GAS_LIMIT, L2_GAS_PER_PUBDATA_LIMIT); @@ -233,7 +236,7 @@ contract ZkStackAdapterTest is Test { vm.stopPrank(); } - // Sending USDC should construct a L2TransactionTwoBridges struct with the shared bridge as the USDC shared bridge. + // Sending USDC should construct a L2TransactionTwoBridges struct with the USDC shared bridge as the second bridge. function testRelayUsdc(uint256 amountToSend, address random) public { amountToSend = uint256(bound(amountToSend, 1, type(uint256).max)); l1Usdc.mint(address(zksAdapter), amountToSend); @@ -271,7 +274,7 @@ contract ZkStackAdapterTest is Test { l2GasLimit: L2_GAS_LIMIT, l2GasPerPubdataByteLimit: L2_GAS_PER_PUBDATA_LIMIT, refundRecipient: owner, - secondBridgeAddress: sharedBridge, + secondBridgeAddress: assetRouter, secondBridgeValue: 0, secondBridgeCalldata: abi.encode(address(l1Token), amountToSend, random) }) @@ -308,7 +311,7 @@ contract ZkStackAdapterTest is Test { emit AdapterInterface.MessageRelayed(target, message); zksCustomGasAdapter.relayMessage(target, message); // Approve only the amount of the fee of the custom gas token. Since we don't actually transferFrom, the approval should stand. - assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), sharedBridge), baseCost); + assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), assetRouter), baseCost); } // Sending Weth should be a TwoBridgesOuter struct, should withdraw weth that it owns, and then call the l2 bridge with the token address as address(1). @@ -329,7 +332,7 @@ contract ZkStackAdapterTest is Test { l2GasLimit: L2_GAS_LIMIT, l2GasPerPubdataByteLimit: L2_GAS_PER_PUBDATA_LIMIT, refundRecipient: owner, - secondBridgeAddress: sharedBridge, + secondBridgeAddress: assetRouter, secondBridgeValue: amountToSend, secondBridgeCalldata: abi.encode(address(1), 0, random) }) @@ -341,7 +344,7 @@ contract ZkStackAdapterTest is Test { zksCustomGasAdapter.relayTokens(address(l1Weth), address(l2Weth), amountToSend, random); vm.stopPrank(); // Approve only the amount of the fee of the custom gas token. Since we don't actually transferFrom, the approval should stand. - assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), sharedBridge), baseCost); + assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), assetRouter), baseCost); } // There should be a hash from L2TransactionTwoBridges with the USDC shared bridge as the second bridge address, an approval for the fee amount from the @@ -367,7 +370,7 @@ contract ZkStackAdapterTest is Test { emit AdapterInterface.TokensRelayed(address(l1Usdc), address(l2Usdc), amountToSend, random); zksCustomGasAdapter.relayTokens(address(l1Usdc), address(l2Usdc), amountToSend, random); // Approve only the amount of the fee of the custom gas token. Since we don't actually transferFrom, the approval should stand. - assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), usdcSharedBridge), baseCost); + assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), assetRouter), baseCost); assertEq(l1Usdc.allowance(address(zksCustomGasAdapter), usdcSharedBridge), amountToSend); } @@ -383,7 +386,7 @@ contract ZkStackAdapterTest is Test { l2GasLimit: L2_GAS_LIMIT, l2GasPerPubdataByteLimit: L2_GAS_PER_PUBDATA_LIMIT, refundRecipient: owner, - secondBridgeAddress: sharedBridge, + secondBridgeAddress: assetRouter, secondBridgeValue: 0, secondBridgeCalldata: abi.encode(address(l1Token), amountToSend, random) }) @@ -394,8 +397,8 @@ contract ZkStackAdapterTest is Test { emit AdapterInterface.TokensRelayed(address(l1Token), address(l2Token), amountToSend, random); zksCustomGasAdapter.relayTokens(address(l1Token), address(l2Token), amountToSend, random); // Approve only the amount of the fee of the custom gas token. Since we don't actually transferFrom, the approval should stand. - assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), sharedBridge), baseCost); - assertEq(l1Token.allowance(address(zksCustomGasAdapter), sharedBridge), amountToSend); + assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), assetRouter), baseCost); + assertEq(l1Token.allowance(address(zksCustomGasAdapter), assetRouter), amountToSend); } // There should be a hash of L2TransactionDirect and an approval for the custom gas token. @@ -421,7 +424,7 @@ contract ZkStackAdapterTest is Test { zksCustomGasAdapter.relayTokens(address(l1CustomGasToken), address(l2CustomGasToken), amountToSend, random); // Approve only the amount of the fee of the custom gas token. Since we don't actually transferFrom, the approval should stand. - assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), sharedBridge), baseCost + amountToSend); - assertEq(l1Token.allowance(address(zksCustomGasAdapter), sharedBridge), 0); + assertEq(l1CustomGasToken.allowance(address(zksCustomGasAdapter), assetRouter), baseCost + amountToSend); + assertEq(l1Token.allowance(address(zksCustomGasAdapter), assetRouter), 0); } }