Skip to content

Commit

Permalink
Merge branch 'kl/sync-layer-reorg' into sb-better-governance-protection
Browse files Browse the repository at this point in the history
  • Loading branch information
StanislavBreadless authored Sep 26, 2024
2 parents b18032a + d7ee927 commit 5c5c967
Show file tree
Hide file tree
Showing 11 changed files with 441 additions and 268 deletions.
3 changes: 2 additions & 1 deletion l1-contracts/contracts/bridge/ntv/IL1NativeTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ pragma solidity 0.8.24;

import {IL1Nullifier} from "../interfaces/IL1Nullifier.sol";
import {INativeTokenVault} from "./INativeTokenVault.sol";
import {IL1AssetDeploymentTracker} from "../interfaces/IL1AssetDeploymentTracker.sol";

/// @title L1 Native token vault contract interface
/// @author Matter Labs
/// @custom:security-contact [email protected]
/// @notice The NTV is an Asset Handler for the L1AssetRouter to handle native tokens
// is IL1AssetHandler, IL1BaseTokenAssetHandler {
interface IL1NativeTokenVault is INativeTokenVault {
interface IL1NativeTokenVault is INativeTokenVault, IL1AssetDeploymentTracker {
/// @notice The L1Nullifier contract
function L1_NULLIFIER() external view returns (IL1Nullifier);

Expand Down
12 changes: 12 additions & 0 deletions l1-contracts/contracts/bridge/ntv/L1NativeTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {IL1Nullifier} from "../interfaces/IL1Nullifier.sol";
import {IL1AssetRouter} from "../asset-router/IL1AssetRouter.sol";

import {ETH_TOKEN_ADDRESS} from "../../common/Config.sol";
import {L2_NATIVE_TOKEN_VAULT_ADDR} from "../../common/L2ContractAddresses.sol";
import {DataEncoding} from "../../common/libraries/DataEncoding.sol";

import {Unauthorized, ZeroAddress, NoFundsTransferred, InsufficientChainBalance, WithdrawFailed} from "../../common/L1ContractErrors.sol";
Expand Down Expand Up @@ -123,6 +124,17 @@ contract L1NativeTokenVault is IL1NativeTokenVault, IL1AssetHandler, NativeToken
L1_NULLIFIER.nullifyChainBalanceByNTV(_targetChainId, _token);
}

/// @notice Used to register the Asset Handler asset in L2 AssetRouter.
/// @param _assetHandlerAddressOnCounterpart the address of the asset handler on the counterpart chain.
function bridgeCheckCounterpartAddress(
uint256,
bytes32,
address,
address _assetHandlerAddressOnCounterpart
) external view override onlyAssetRouter {
require(_assetHandlerAddressOnCounterpart == L2_NATIVE_TOKEN_VAULT_ADDR, "NTV: wrong counterpart");
}

/*//////////////////////////////////////////////////////////////
Start transaction Functions
//////////////////////////////////////////////////////////////*/
Expand Down
2 changes: 1 addition & 1 deletion l1-contracts/contracts/bridge/ntv/NativeTokenVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ abstract contract NativeTokenVault is INativeTokenVault, IAssetHandler, Ownable2
}
_handleChainBalanceIncrease(_chainId, _assetId, amount, true);
if (_depositAmount != amount) {
revert ValueMismatch(amount, msg.value);
revert ValueMismatch(_depositAmount, amount);
}
} else {
// The Bridgehub also checks this, but we want to be sure
Expand Down
2 changes: 0 additions & 2 deletions l1-contracts/contracts/common/L1ContractErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ error DepositDoesNotExist();
error DepositExists();
// 0x79cacff1
error DepositFailed();
// 0xae08e4af
error DepositIncorrectAmount(uint256 expectedAmt, uint256 providedAmt);
// 0x0e7ee319
error DiamondAlreadyFrozen();
// 0x682dabb4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {L1AssetRouterTest} from "./_L1SharedBridge_Shared.t.sol";
import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol";
import {IERC20} from "@openzeppelin/contracts-v4/token/ERC20/IERC20.sol";

import {SET_ASSET_HANDLER_COUNTERPART_ENCODING_VERSION} from "contracts/bridge/asset-router/IAssetRouterBase.sol";
import {L1AssetRouter} from "contracts/bridge/asset-router/L1AssetRouter.sol";
import {L1NativeTokenVault} from "contracts/bridge/ntv/L1NativeTokenVault.sol";
import {ETH_TOKEN_ADDRESS} from "contracts/common/Config.sol";
Expand All @@ -20,7 +21,7 @@ import {INativeTokenVault} from "contracts/bridge/ntv/INativeTokenVault.sol";
import {L1NativeTokenVault} from "contracts/bridge/ntv/L1NativeTokenVault.sol";
import {L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR} from "contracts/common/L2ContractAddresses.sol";
import {IGetters} from "contracts/state-transition/chain-interfaces/IGetters.sol";
import {AddressAlreadyUsed, WithdrawFailed, Unauthorized, AssetIdNotSupported, SharedBridgeKey, SharedBridgeValueNotSet, L2WithdrawalMessageWrongLength, InsufficientChainBalance, ZeroAddress, ValueMismatch, NonEmptyMsgValue, DepositExists, ValueMismatch, NonEmptyMsgValue, TokenNotSupported, EmptyDeposit, L2BridgeNotDeployed, DepositIncorrectAmount, InvalidProof, NoFundsTransferred, InsufficientFunds, DepositDoesNotExist, WithdrawalAlreadyFinalized, InsufficientFunds, MalformedMessage, InvalidSelector, TokensWithFeesNotSupported} from "contracts/common/L1ContractErrors.sol";
import {AddressAlreadyUsed, WithdrawFailed, Unauthorized, AssetIdNotSupported, SharedBridgeKey, SharedBridgeValueNotSet, L2WithdrawalMessageWrongLength, InsufficientChainBalance, ZeroAddress, ValueMismatch, NonEmptyMsgValue, DepositExists, ValueMismatch, NonEmptyMsgValue, TokenNotSupported, EmptyDeposit, L2BridgeNotDeployed, InvalidProof, NoFundsTransferred, InsufficientFunds, DepositDoesNotExist, WithdrawalAlreadyFinalized, InsufficientFunds, MalformedMessage, InvalidSelector, TokensWithFeesNotSupported} from "contracts/common/L1ContractErrors.sol";
import {StdStorage, stdStorage} from "forge-std/Test.sol";

/// We are testing all the specified revert and require cases.
Expand Down Expand Up @@ -96,37 +97,23 @@ contract L1AssetRouterFailTest is L1AssetRouterTest {
sharedBridge.setNativeTokenVault(INativeTokenVault(address(0)));
}

// function test_setAssetHandlerAddressOnCounterpart_notOwnerOrADT() public {
// uint256 l2TxGasLimit = 100000;
// uint256 l2TxGasPerPubdataByte = 100;
// address refundRecipient = address(0);

// vm.prank(alice);
// vm.expectRevert("L1N: only ADT or owner");
// sharedBridge.setAssetHandlerAddressOnCounterpart(
// eraChainId,
// mintValue,
// l2TxGasLimit,
// l2TxGasPerPubdataByte,
// refundRecipient,
// tokenAssetId,
// address(token)
// );
// }

// function test_transferFundsToSharedBridge_Eth_CallFailed() public {
// vm.mockCall(address(nativeTokenVault), "0x", abi.encode(""));
// vm.prank(address(nativeTokenVault));
// vm.expectRevert("L1N: eth transfer failed");
// nativeTokenVault.transferFundsFromSharedBridge(ETH_TOKEN_ADDRESS);
// }

// function test_transferFundsToSharedBridge_Eth_CallFailed() public {
// vm.mockCall(address(nativeTokenVault), "0x", abi.encode(""));
// vm.prank(address(nativeTokenVault));
// vm.expectRevert("L1N: eth transfer failed");
// nativeTokenVault.transferFundsFromSharedBridge(ETH_TOKEN_ADDRESS);
// }
function test_setAssetHandlerAddressOnCounterpart_wrongCounterPartAddress() public {
bytes memory data = bytes.concat(
SET_ASSET_HANDLER_COUNTERPART_ENCODING_VERSION,
abi.encode(tokenAssetId, address(token))
);

vm.prank(bridgehubAddress);
vm.expectRevert("NTV: wrong counterpart");
sharedBridge.bridgehubDeposit(eraChainId, owner, 0, data);
}

function test_transferFundsToSharedBridge_Eth_CallFailed() public {
vm.mockCallRevert(address(nativeTokenVault), "", "eth transfer failed");
vm.prank(address(nativeTokenVault));
vm.expectRevert("L1N: eth transfer failed");
l1Nullifier.transferTokenToNTV(ETH_TOKEN_ADDRESS);
}

function test_transferFundsToSharedBridge_Eth_0_AmountTransferred() public {
vm.deal(address(l1Nullifier), 0);
Expand Down Expand Up @@ -155,12 +142,12 @@ contract L1AssetRouterFailTest is L1AssetRouterTest {
sharedBridge.bridgehubDepositBaseToken{value: amount}(chainId, ETH_TOKEN_ASSET_ID, alice, amount);
}

// function test_bridgehubDepositBaseToken_EthwrongMsgValue() public {
// vm.deal(bridgehubAddress, amount);
// vm.prank(bridgehubAddress);
// vm.expectRevert(abi.encodeWithSelector(ValueMismatch.selector, amount, uint256(1)));
// sharedBridge.bridgehubDepositBaseToken(chainId, ETH_TOKEN_ASSET_ID, alice, amount);
// }
function test_bridgehubDepositBaseToken_EthwrongMsgValue() public {
vm.deal(bridgehubAddress, amount);
vm.prank(bridgehubAddress);
vm.expectRevert(abi.encodeWithSelector(ValueMismatch.selector, amount, uint256(1)));
sharedBridge.bridgehubDepositBaseToken{value: 1}(chainId, ETH_TOKEN_ASSET_ID, alice, amount);
}

function test_bridgehubDepositBaseToken_ErcWrongMsgValue() public {
vm.deal(bridgehubAddress, amount);
Expand Down Expand Up @@ -199,18 +186,18 @@ contract L1AssetRouterFailTest is L1AssetRouterTest {
sharedBridge.bridgehubDeposit(chainId, alice, 0, abi.encode(ETH_TOKEN_ADDRESS, 0, bob));
}

// function test_bridgehubDeposit_Eth_wrongDepositAmount() public {
// _setBaseTokenAssetId(tokenAssetId);
// vm.prank(bridgehubAddress);
// vm.mockCall(
// bridgehubAddress,
// abi.encodeWithSelector(IBridgehub.baseTokenAssetId.selector),
// abi.encode(tokenAssetId)
// );
// vm.expectRevert(abi.encodeWithSelector(DepositIncorrectAmount.selector, 0, amount));
// // solhint-disable-next-line func-named-parameters
// sharedBridge.bridgehubDeposit(chainId, alice, 0, abi.encode(ETH_TOKEN_ADDRESS, amount, bob));
// }
function test_bridgehubDeposit_Eth_wrongDepositAmount() public {
_setBaseTokenAssetId(tokenAssetId);
vm.prank(bridgehubAddress);
vm.mockCall(
bridgehubAddress,
abi.encodeWithSelector(IBridgehub.baseTokenAssetId.selector),
abi.encode(tokenAssetId)
);
vm.expectRevert(abi.encodeWithSelector(ValueMismatch.selector, amount, 0));
// solhint-disable-next-line func-named-parameters
sharedBridge.bridgehubDeposit(chainId, alice, 0, abi.encode(ETH_TOKEN_ADDRESS, amount, bob));
}

function test_bridgehubDeposit_Erc_msgValue() public {
vm.prank(bridgehubAddress);
Expand Down Expand Up @@ -623,27 +610,31 @@ contract L1AssetRouterFailTest is L1AssetRouterTest {
});
}

// function test_finalizeWithdrawal_TokenOnEth_legacyUpgradeFirstBatchNotSet() public {
// vm.store(address(sharedBridge), bytes32(isWithdrawalFinalizedStorageLocation - 6), bytes32(uint256(0)));
// vm.deal(address(sharedBridge), amount);

// bytes memory message = abi.encodePacked(
// IL1ERC20Bridge.finalizeWithdrawal.selector,
// alice,
// address(token),
// amount
// );

// vm.expectRevert(abi.encodeWithSelector(SharedBridgeValueNotSet.selector, SharedBridgeKey.PostUpgradeFirstBatch));
// sharedBridge.finalizeWithdrawal({
// _chainId: eraChainId,
// _l2BatchNumber: l2BatchNumber,
// _l2MessageIndex: l2MessageIndex,
// _l2TxNumberInBatch: l2TxNumberInBatch,
// _message: message,
// _merkleProof: merkleProof
// });
// }
function test_finalizeWithdrawal_TokenOnEth_legacyUpgradeFirstBatchNotSet() public {
vm.store(address(l1Nullifier), bytes32(isWithdrawalFinalizedStorageLocation - 7), bytes32(uint256(0)));
vm.deal(address(nativeTokenVault), amount);

bytes memory message = abi.encodePacked(
IL1ERC20Bridge.finalizeWithdrawal.selector,
alice,
address(token),
amount
);

vm.mockCall(bridgehubAddress, abi.encode(IBridgehub.proveL2MessageInclusion.selector), abi.encode(true));

vm.expectRevert(
abi.encodeWithSelector(SharedBridgeValueNotSet.selector, SharedBridgeKey.PostUpgradeFirstBatch)
);
sharedBridge.finalizeWithdrawal({
_chainId: eraChainId,
_l2BatchNumber: l2BatchNumber,
_l2MessageIndex: l2MessageIndex,
_l2TxNumberInBatch: l2TxNumberInBatch,
_message: message,
_merkleProof: merkleProof
});
}

function test_finalizeWithdrawal_chainBalance() public {
bytes memory message = abi.encodePacked(IMailbox.finalizeEthWithdrawal.selector, alice, amount);
Expand Down
Loading

0 comments on commit 5c5c967

Please sign in to comment.