Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ability to recover from failed migration #715

Merged
merged 17 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion l1-contracts/contracts/bridgehub/Bridgehub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,23 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus
bytes32 _assetId,
address _depositSender,
bytes calldata _data
) external payable override onlyAssetRouter onlyL1 {}
) external payable override onlyAssetRouter onlyL1 {
delete settlementLayer[_chainId];

IStateTransitionManager(stateTransitionManager[_chainId]).bridgeClaimFailedBurn({
koloz193 marked this conversation as resolved.
Show resolved Hide resolved
_chainId: _chainId,
_assetInfo: _assetId,
_prevMsgSender: _depositSender,
koloz193 marked this conversation as resolved.
Show resolved Hide resolved
_data: _data
});

IZkSyncHyperchain(getHyperchain(_chainId)).forwardedBridgeClaimFailedBurn({
_chainId: _chainId,
_assetInfo: _assetId,
_prevMsgSender: _depositSender,
_data: _data
});
}

/*//////////////////////////////////////////////////////////////
PAUSE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,22 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin {

/// @inheritdoc IAdmin
function forwardedBridgeClaimFailedBurn(
uint256 _chainId,
bytes32 _assetInfo,
uint256 /* _chainId */,
bytes32 /* _assetInfo */,
address _prevMsgSender,
koloz193 marked this conversation as resolved.
Show resolved Hide resolved
bytes calldata _data
) external payable override onlyBridgehub {}
bytes calldata /* _data */
) external payable override onlyBridgehub {
require(s.settlementLayer != address(0), "Af: not migrated");
require(_prevMsgSender == s.admin, "Af: not chainAdmin");
koloz193 marked this conversation as resolved.
Show resolved Hide resolved
IStateTransitionManager stm = IStateTransitionManager(s.stateTransitionManager);

uint256 currentProtocolVersion = s.protocolVersion;
uint256 protocolVersion = stm.protocolVersion();
koloz193 marked this conversation as resolved.
Show resolved Hide resolved

require(currentProtocolVersion == protocolVersion, "STM: protocolVersion not up to date");

s.settlementLayer = address(0);
}

/// @notice Returns the commitment for a chain.
/// @dev Note, that this is a getter method helpful for debugging and should not be relied upon by clients.
Expand Down
60 changes: 60 additions & 0 deletions l1-contracts/test/foundry/integration/GatewayTests.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@ import {L2Message} from "contracts/common/Messaging.sol";
import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol";
import {L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR} from "contracts/common/L2ContractAddresses.sol";
import {IL1ERC20Bridge} from "contracts/bridge/interfaces/IL1ERC20Bridge.sol";
import {IL1AssetRouter} from "contracts/bridge/interfaces/IL1AssetRouter.sol";

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol";
import {IStateTransitionManager} from "contracts/state-transition/IStateTransitionManager.sol";
import {AdminFacet} from "contracts/state-transition/chain-deps/facets/Admin.sol";
import {AddressAliasHelper} from "contracts/vendor/AddressAliasHelper.sol";
import {TxStatus} from "contracts/common/Messaging.sol";

contract GatewayTests is L1ContractDeployer, HyperchainDeployer, TokenDeployer, L2TxMocker, GatewayDeployer {
uint256 constant TEST_USERS_COUNT = 10;
Expand Down Expand Up @@ -164,6 +166,64 @@ contract GatewayTests is L1ContractDeployer, HyperchainDeployer, TokenDeployer,
vm.stopBroadcast();
}

function test_recoverFromFailedChainMigration() public {
gatewayScript.registerGateway();
gatewayScript.moveChainToGateway();

// Setup
IBridgehub bridgehub = IBridgehub(l1Script.getBridgehubProxyAddress());
address chainAdmin = IZkSyncHyperchain(bridgehub.getHyperchain(migratingChainId)).getAdmin();
IL1AssetRouter assetRouter = bridgehub.sharedBridge();
bytes32 assetId = bridgehub.stmAssetIdFromChainId(migratingChainId);
bytes32 l2TxHash = keccak256("l2TxHash");
uint256 l2BatchNumber = 5;
uint256 l2MessageIndex = 0;
uint16 l2TxNumberInBatch = 0;
bytes32[] memory merkleProof = new bytes32[](1);
TxStatus status = TxStatus.Failure;
bytes memory transferData = abi.encode(1, address(0));
bytes32 txDataHash = keccak256(bytes.concat(bytes1(0x01), abi.encode(chainAdmin, assetId, transferData)));

// Mock Call for Msg Inclusion
vm.mockCall(
address(bridgehub),
abi.encodeWithSelector(
IBridgehub.proveL1ToL2TransactionStatus.selector,
migratingChainId,
l2TxHash,
l2BatchNumber,
l2MessageIndex,
l2TxNumberInBatch,
merkleProof,
status
),
abi.encode(true)
);

// Set Deposit Happened
vm.startBroadcast(address(bridgeHub));
assetRouter.bridgehubConfirmL2Transaction({
koloz193 marked this conversation as resolved.
Show resolved Hide resolved
_chainId: migratingChainId,
_txDataHash: txDataHash,
_txHash: l2TxHash
});
vm.stopBroadcast();

vm.startBroadcast();
assetRouter.bridgeRecoverFailedTransfer({
_chainId: migratingChainId,
_depositSender: chainAdmin,
_assetId: assetId,
_assetData: transferData,
_l2TxHash: l2TxHash,
_l2BatchNumber: l2BatchNumber,
_l2MessageIndex: l2MessageIndex,
_l2TxNumberInBatch: l2TxNumberInBatch,
_merkleProof: merkleProof
});
vm.stopBroadcast();
}

function finishMoveChain() public {
IBridgehub bridgehub = IBridgehub(l1Script.getBridgehubProxyAddress());
IStateTransitionManager stm = IStateTransitionManager(l1Script.getSTM());
Expand Down
Loading