Skip to content

Commit

Permalink
test: add unit test for mark bootstrap
Browse files Browse the repository at this point in the history
In the case where Bootstrap call first fails and then succeeds.
  • Loading branch information
MaxMustermann2 committed Sep 3, 2024
1 parent 88d41a3 commit 31fc163
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 22 deletions.
7 changes: 5 additions & 2 deletions src/core/Bootstrap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,11 @@ contract Bootstrap is
return;
}
// bootstrapped = true is only actioned by the clientchaingateway after upgrade
// so no need to check for that here
// so no need to check for that here but better to be safe.
if (bootstrapped) {
emit BootstrappedAlready();
return;
}
try ICustomProxyAdmin(customProxyAdmin).changeImplementation(
// address(this) is storage address and not logic address. so it is a proxy.
ITransparentUpgradeableProxy(address(this)),
Expand All @@ -575,7 +579,6 @@ contract Bootstrap is
// to allow retries, never fail
emit BootstrapUpgradeFailed();
}
emit Bootstrapped();
}

/// @notice Sets a new client chain gateway logic and its initialization data.
Expand Down
5 changes: 5 additions & 0 deletions src/storage/BootstrapStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ contract BootstrapStorage is GatewayStorage {
/// intentionally to prevent blocking the system.
event BootstrapUpgradeFailed();

/// @notice Emitted when the contract is already bootstrapped.
/// @dev This event is triggered when the contract is already bootstrapped and an attempt is made to bootstrap it
/// again. It is not an error intentionally to prevent blocking the system.
event BootstrappedAlready();

/// @notice Emitted when the client chain gateway logic + implementation are updated.
/// @dev This event is triggered whenever the client chain gateway logic and implementation are updated. It may be
/// used, before bootstrapping is complete, to upgrade the client chain gateway logic for upgrades or other bugs.
Expand Down
48 changes: 28 additions & 20 deletions test/foundry/unit/Bootstrap.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ contract BootstrapTest is Test {
address exocoreValidatorSet = vm.addr(uint256(0x8));
address undeployedExocoreGateway = vm.addr(uint256(0x9));
address undeployedExocoreLzEndpoint = vm.addr(uint256(0xb));
address constant lzActor = address(0x20);

IVault vaultImplementation;
IExoCapsule capsuleImplementation;
Expand Down Expand Up @@ -889,36 +890,35 @@ contract BootstrapTest is Test {
}

function test12_MarkBootstrapped() public {
// go after spawn time
vm.warp(spawnTime + 1);
vm.startPrank(address(0x20));
_markBootstrapped(1, true);
}

function _markBootstrapped(uint64 nonce, bool success) internal {
vm.startPrank(lzActor);
clientChainLzEndpoint.lzReceive(
Origin(exocoreChainId, bytes32(bytes20(undeployedExocoreGateway)), uint64(1)),
Origin(exocoreChainId, bytes32(bytes20(undeployedExocoreGateway)), nonce),
address(bootstrap),
generateUID(1),
abi.encodePacked(GatewayStorage.Action.REQUEST_MARK_BOOTSTRAP, ""),
bytes("")
);
vm.stopPrank();
assertTrue(bootstrap.bootstrapped());
// ensure that it cannot be upgraded ever again.
assertTrue(bootstrap.customProxyAdmin() == address(0));
assertTrue(proxyAdmin.bootstrapper() == address(0));
assertTrue(bootstrap.owner() == exocoreValidatorSet);
// getDepositorsCount is no longer a function so can't check the count.
// assertTrue(bootstrap.getDepositorsCount() == 0);
if (success) {
assertTrue(bootstrap.bootstrapped());
// no more upgrades are possible
assertTrue(bootstrap.customProxyAdmin() == address(0));
assertTrue(proxyAdmin.bootstrapper() == address(0));
assertTrue(bootstrap.owner() == exocoreValidatorSet);
} else {
assertFalse(bootstrap.bootstrapped());
}
}

function test12_MarkBootstrapped_NotTime() public {
vm.startPrank(address(0x20));
clientChainLzEndpoint.lzReceive(
Origin(exocoreChainId, bytes32(bytes20(undeployedExocoreGateway)), uint64(1)),
address(bootstrap),
generateUID(1),
abi.encodePacked(GatewayStorage.Action.REQUEST_MARK_BOOTSTRAP, ""),
bytes("")
);
vm.stopPrank();
assertFalse(bootstrap.bootstrapped());
// spawn time is 1 hour later, so this will fail.
_markBootstrapped(1, false);
}

function test12_MarkBootstrapped_AlreadyBootstrapped() public {
Expand All @@ -940,13 +940,21 @@ contract BootstrapTest is Test {
}

function test12_MarkBootstrapped_DirectCall() public {
vm.startPrank(address(0x20));
// can be any adddress but for clarity use non lz actor
vm.startPrank(address(0x21));
vm.warp(spawnTime + 2);
vm.expectRevert(Errors.BootstrapLzReceiverOnlyCalledFromThis.selector);
bootstrap.markBootstrapped();
vm.stopPrank();
}

function test12_MarkBootstrapped_FailThenSucceed() public {
vm.warp(spawnTime - 5);
_markBootstrapped(1, false);
vm.warp(spawnTime + 1);
_markBootstrapped(2, true);
}

function test13_OperationAllowed() public {
vm.warp(spawnTime - offsetDuration);
vm.startPrank(addrs[0]);
Expand Down

0 comments on commit 31fc163

Please sign in to comment.