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

State transition manager test coverage #498

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ library Utils {
}

function getGettersSelectors() public pure returns (bytes4[] memory) {
bytes4[] memory selectors = new bytes4[](30);
bytes4[] memory selectors = new bytes4[](32);
selectors[0] = GettersFacet.getVerifier.selector;
selectors[1] = GettersFacet.getAdmin.selector;
selectors[2] = GettersFacet.getPendingAdmin.selector;
Expand Down Expand Up @@ -241,6 +241,8 @@ library Utils {
selectors[27] = GettersFacet.getTotalBatchesExecuted.selector;
selectors[28] = GettersFacet.getL2SystemContractsUpgradeTxHash.selector;
selectors[29] = GettersFacet.getChainId.selector;
selectors[30] = GettersFacet.baseTokenGasPriceMultiplierDenominator.selector;
selectors[31] = GettersFacet.baseTokenGasPriceMultiplierNominator.selector;
return selectors;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol";
import {console} from "forge-std/console.sol";
import {Unauthorized} from "contracts/common/L1ContractErrors.sol";

contract AdminManagement is StateTransitionManagerTest {
function setUp() public {
deploy();
}

function test_RevertWhen_IsNotAdminOrOwner() public {
address newAdmin = makeAddr("newAdmin");

vm.stopPrank();
vm.prank(newAdmin);
vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, newAdmin));
chainContractAddress.setPendingAdmin(newAdmin);
}

function test_SuccessfulSetPendingAdmin() public {
address newAdmin = makeAddr("newAdmin");

chainContractAddress.setPendingAdmin(newAdmin);
}

function test_RevertWhen_IsNotNewAdminSender() public {
address newAdmin = makeAddr("newAdmin");
address random = makeAddr("random");

chainContractAddress.setPendingAdmin(newAdmin);

vm.stopPrank();
vm.prank(random);
vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, random));
chainContractAddress.acceptAdmin();
}

function test_RevertWhen_PendingAdminNotExists() public {
address random = makeAddr("random");

vm.stopPrank();
vm.prank(random);
vm.expectRevert(abi.encodeWithSelector(Unauthorized.selector, random));
chainContractAddress.acceptAdmin();
}

function test_SuccessfulAcceptPendingAdmin() public {
address newAdmin = makeAddr("newAdmin");

chainContractAddress.setPendingAdmin(newAdmin);

vm.stopPrank();
vm.prank(newAdmin);
chainContractAddress.acceptAdmin();

assertEq(chainContractAddress.admin(), newAdmin);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// // SPDX-License-Identifier: MIT
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol";
import {Diamond} from "contracts/state-transition/libraries/Diamond.sol";
import {Unauthorized, HashMismatch} from "contracts/common/L1ContractErrors.sol";
import {Unauthorized, HashMismatch, ZeroAddress, HyperchainLimitReached} from "contracts/common/L1ContractErrors.sol";
import {StateTransitionManager} from "contracts/state-transition/StateTransitionManager.sol";

contract createNewChainTest is StateTransitionManagerTest {
function setUp() public {
Expand Down Expand Up @@ -46,4 +47,50 @@ contract createNewChainTest is StateTransitionManagerTest {
assertEq(newChainAdmin, admin);
assertNotEq(newChainAddress, address(0));
}

function test_SuccessfulCreationOfNewChainAndReturnChainIds() public {
createNewChain(getDiamondCutData(diamondInit));
createNewChainWithId(getDiamondCutData(diamondInit), 10);

uint256[] memory chainIds = chainContractAddress.getAllHyperchainChainIDs();
assertEq(chainIds.length, 2);
assertEq(chainIds[0], chainId);
assertEq(chainIds[1], 10);
}

function test_SuccessfulCreationOfNewChainAndReturnChainAddresses() public {
createNewChain(getDiamondCutData(diamondInit));
createNewChainWithId(getDiamondCutData(diamondInit), 10);

address[] memory hyperchainAddresses = chainContractAddress.getAllHyperchains();
assertEq(hyperchainAddresses.length, 2);
assertEq(hyperchainAddresses[0], chainContractAddress.getHyperchain(chainId));
assertEq(hyperchainAddresses[1], chainContractAddress.getHyperchain(10));
}

function test_RevertWhen_AlreadyDeployedHyperchainAddressIsZero() public {
vm.expectRevert(ZeroAddress.selector);

chainContractAddress.registerAlreadyDeployedHyperchain(chainId, address(0));
}

function test_SuccessfulRegisterAlreadyDeployedHyperchain() public {
address randomHyperchain = makeAddr("randomHyperchain");

chainContractAddress.registerAlreadyDeployedHyperchain(10, randomHyperchain);

assertEq(chainContractAddress.getHyperchain(10), randomHyperchain);
}

function test_RevertWhen_HyperchainLimitReached() public {
for (uint256 i = 0; i < MAX_NUMBER_OF_HYPERCHAINS; i++) {
createNewChainWithId(getDiamondCutData(diamondInit), 10 + i);
}

uint256[] memory chainIds = chainContractAddress.getAllHyperchainChainIDs();
assertEq(chainIds.length, MAX_NUMBER_OF_HYPERCHAINS);

vm.expectRevert(HyperchainLimitReached.selector);
chainContractAddress.registerAlreadyDeployedHyperchain(100, makeAddr("randomHyperchain"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ contract freezeChainTest is StateTransitionManagerTest {
bool isChainFrozen = gettersFacet.isDiamondStorageFrozen();
assertEq(isChainFrozen, false);

vm.stopPrank();
vm.startPrank(governor);

chainContractAddress.freezeChain(block.chainid);

// Repeated call should revert
Expand All @@ -32,4 +29,19 @@ contract freezeChainTest is StateTransitionManagerTest {
vm.expectRevert(bytes("q1"));
isChainFrozen = gettersFacet.isDiamondStorageFrozen();
}

function test_RevertWhen_UnfreezingChain() public {
uint256 newChainid = 10;
createNewChainWithId(getDiamondCutData(diamondInit), newChainid);

address newChainAddress = chainContractAddress.getHyperchain(newChainid);
GettersFacet gettersFacet = GettersFacet(newChainAddress);
bool isChainFrozen = gettersFacet.isDiamondStorageFrozen();
assertEq(isChainFrozen, false);

chainContractAddress.freezeChain(newChainid);

vm.expectRevert(bytes.concat("q1"));
chainContractAddress.unfreezeChain(newChainid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol";
import {StateTransitionManager} from "contracts/state-transition/StateTransitionManager.sol";
import {StateTransitionManagerInitializeData, ChainCreationParams} from "contracts/state-transition/IStateTransitionManager.sol";
import {GenesisUpgradeZero, GenesisBatchHashZero, GenesisIndexStorageZero, GenesisBatchCommitmentZero} from "contracts/common/L1ContractErrors.sol";
import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol";

contract StateTransitionManagerInitializeTest is StateTransitionManagerTest {
function setUp() public {
deploy();
}

modifier asBridgeHub() {
vm.stopPrank();
vm.startPrank(address(bridgehub));

_;
}

function _deployStmWithParams(ChainCreationParams memory params, bytes4 err) internal {
StateTransitionManagerInitializeData memory stmInitializeData = StateTransitionManagerInitializeData({
owner: governor,
validatorTimelock: validator,
chainCreationParams: params,
protocolVersion: 0
});

StateTransitionManager stm = new StateTransitionManager(address(bridgehub), MAX_NUMBER_OF_HYPERCHAINS);

vm.expectRevert(err);
TransparentUpgradeableProxy transparentUpgradeableProxy = new TransparentUpgradeableProxy(
address(stm),
admin,
abi.encodeCall(StateTransitionManager.initialize, stmInitializeData)
);

StateTransitionManager(address(transparentUpgradeableProxy));
}

function test_RevertWhen_genesisUpgradeIsZero() public asBridgeHub {
ChainCreationParams memory chainCreationParams = ChainCreationParams({
genesisUpgrade: address(0),
genesisBatchHash: bytes32(uint256(0x01)),
genesisIndexRepeatedStorageChanges: 0x01,
genesisBatchCommitment: bytes32(uint256(0x01)),
diamondCut: getDiamondCutData(address(diamondInit))
});

_deployStmWithParams(chainCreationParams, GenesisUpgradeZero.selector);
}

function test_RevertWhen_genesBatchHashIsZero() public asBridgeHub {
ChainCreationParams memory chainCreationParams = ChainCreationParams({
genesisUpgrade: address(genesisUpgradeContract),
genesisBatchHash: bytes32(uint256(0)),
genesisIndexRepeatedStorageChanges: 0x01,
genesisBatchCommitment: bytes32(uint256(0x01)),
diamondCut: getDiamondCutData(address(diamondInit))
});

_deployStmWithParams(chainCreationParams, GenesisBatchHashZero.selector);
}

function test_RevertWhen_genesisIndexRepeatedStorageChangesIsZero() public asBridgeHub {
ChainCreationParams memory chainCreationParams = ChainCreationParams({
genesisUpgrade: address(genesisUpgradeContract),
genesisBatchHash: bytes32(uint256(0x01)),
genesisIndexRepeatedStorageChanges: 0,
genesisBatchCommitment: bytes32(uint256(0x01)),
diamondCut: getDiamondCutData(address(diamondInit))
});

_deployStmWithParams(chainCreationParams, GenesisIndexStorageZero.selector);
}

function test_RevertWhen_genesisBatchCommitmentIsZero() public asBridgeHub {
ChainCreationParams memory chainCreationParams = ChainCreationParams({
genesisUpgrade: address(genesisUpgradeContract),
genesisBatchHash: bytes32(uint256(0x01)),
genesisIndexRepeatedStorageChanges: 0x01,
genesisBatchCommitment: bytes32(uint256(0)),
diamondCut: getDiamondCutData(address(diamondInit))
});

_deployStmWithParams(chainCreationParams, GenesisBatchCommitmentZero.selector);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol";
import {Diamond} from "contracts/state-transition/libraries/Diamond.sol";
import {ProtocolIdNotGreater} from "contracts/common/L1ContractErrors.sol";
import {SemVer} from "contracts/common/libraries/SemVer.sol";

contract ProtocolVersion is StateTransitionManagerTest {
function setUp() public {
deploy();
}

// setNewVersionUpgrade
function test_SuccessfulSetNewVersionUpgrade() public {
createNewChain(getDiamondCutData(diamondInit));

uint256 oldProtocolVersion = chainContractAddress.protocolVersion();
uint256 oldProtocolVersionDeadline = chainContractAddress.protocolVersionDeadline(oldProtocolVersion);

assertEq(oldProtocolVersion, 0);
assertEq(oldProtocolVersionDeadline, type(uint256).max);

uint256 newProtocolVersionSemVer = SemVer.packSemVer(0, 1, 0);

chainContractAddress.setNewVersionUpgrade(
getDiamondCutData(diamondInit),
oldProtocolVersion,
1000,
newProtocolVersionSemVer
);

uint256 newProtocolVersion = chainContractAddress.protocolVersion();
uint256 newProtocolVersionDeadline = chainContractAddress.protocolVersionDeadline(newProtocolVersion);

oldProtocolVersionDeadline = chainContractAddress.protocolVersionDeadline(oldProtocolVersion);

(uint32 major, uint32 minor, uint32 patch) = chainContractAddress.getSemverProtocolVersion();

assertEq(major, 0);
assertEq(minor, 1);
assertEq(patch, 0);
assertEq(newProtocolVersion, newProtocolVersionSemVer);
assertEq(newProtocolVersionDeadline, type(uint256).max);
assertEq(oldProtocolVersionDeadline, 1000);
}

// protocolVersionIsActive
function test_SuccessfulProtocolVersionIsActive() public {
createNewChain(getDiamondCutData(diamondInit));

chainContractAddress.setNewVersionUpgrade(getDiamondCutData(diamondInit), 0, 0, 1);

assertEq(chainContractAddress.protocolVersionIsActive(0), false);
assertEq(chainContractAddress.protocolVersionIsActive(1), true);
}

// setProtocolVersionDeadline
function test_SuccessfulSetProtocolVersionDeadline() public {
createNewChain(getDiamondCutData(diamondInit));

uint256 deadlineBefore = chainContractAddress.protocolVersionDeadline(0);
assertEq(deadlineBefore, type(uint256).max);

uint256 newDeadline = 1000;
chainContractAddress.setProtocolVersionDeadline(0, newDeadline);

uint256 deadline = chainContractAddress.protocolVersionDeadline(0);
assertEq(deadline, newDeadline);
}

// executeUpgrade
function test_SuccessfulExecuteUpdate() public {
createNewChain(getDiamondCutData(diamondInit));

Diamond.FacetCut[] memory customFacetCuts = new Diamond.FacetCut[](1);
customFacetCuts[0] = Diamond.FacetCut({
facet: facetCuts[2].facet,
action: Diamond.Action.Replace,
isFreezable: true,
selectors: facetCuts[2].selectors
});

chainContractAddress.executeUpgrade(chainId, getDiamondCutDataWithCustomFacets(address(0), customFacetCuts));
}

// upgradeChainFromVersion
function test_SuccessfulUpgradeChainFromVersion() public {
createNewChain(getDiamondCutData(diamondInit));

Diamond.FacetCut[] memory customFacetCuts = new Diamond.FacetCut[](1);
customFacetCuts[0] = Diamond.FacetCut({
facet: facetCuts[2].facet,
action: Diamond.Action.Replace,
isFreezable: true,
selectors: facetCuts[2].selectors
});

chainContractAddress.setNewVersionUpgrade(
getDiamondCutDataWithCustomFacets(address(0), customFacetCuts),
0,
0,
1
);

vm.expectRevert(ProtocolIdNotGreater.selector);
chainContractAddress.upgradeChainFromVersion(
chainId,
0,
getDiamondCutDataWithCustomFacets(address(0), customFacetCuts)
);
}
}
Loading