Skip to content

Commit

Permalink
Merge pull request #240 from matter-labs/ra/improving-test-coverage
Browse files Browse the repository at this point in the history
feat: Improving test coverage of SCs
  • Loading branch information
vladbochok authored Mar 5, 2024
2 parents 2ca69f0 + cf31bb8 commit 39c5451
Show file tree
Hide file tree
Showing 20 changed files with 649 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.20;

import "../../vendor/AddressAliasHelper.sol";

contract AddressAliasHelperTest {
function applyL1ToL2Alias(address _l1Address) external pure returns (address) {
return AddressAliasHelper.applyL1ToL2Alias(_l1Address);
}

function undoL1ToL2Alias(address _l2Address) external pure returns (address) {
return AddressAliasHelper.undoL1ToL2Alias(_l2Address);
}
}
19 changes: 7 additions & 12 deletions l1-contracts/contracts/dev-contracts/test/PriorityQueueTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,33 @@ pragma solidity 0.8.20;
import "../../state-transition/libraries/PriorityQueue.sol";

contract PriorityQueueTest {
// add this to be excluded from coverage report
function test() internal virtual {}

using PriorityQueue for PriorityQueue.Queue;

PriorityQueue.Queue priorityQueue;

function getFirstUnprocessedPriorityTx() external view returns (uint256) {
return priorityQueue.getFirstUnprocessedPriorityTx();
return PriorityQueue.getFirstUnprocessedPriorityTx(priorityQueue);
}

function getTotalPriorityTxs() external view returns (uint256) {
return priorityQueue.getTotalPriorityTxs();
return PriorityQueue.getTotalPriorityTxs(priorityQueue);
}

function getSize() external view returns (uint256) {
return priorityQueue.getSize();
return PriorityQueue.getSize(priorityQueue);
}

function isEmpty() external view returns (bool) {
return priorityQueue.isEmpty();
return PriorityQueue.isEmpty(priorityQueue);
}

function pushBack(PriorityOperation memory _operation) external {
return priorityQueue.pushBack(_operation);
return PriorityQueue.pushBack(priorityQueue, _operation);
}

function front() external view returns (PriorityOperation memory) {
return priorityQueue.front();
return PriorityQueue.front(priorityQueue);
}

function popFront() external returns (PriorityOperation memory operation) {
return priorityQueue.popFront();
return PriorityQueue.popFront(priorityQueue);
}
}
15 changes: 15 additions & 0 deletions l1-contracts/contracts/dev-contracts/test/UncheckedMathTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.20;

import "../../common/libraries/UncheckedMath.sol";

contract UncheckedMathTest {
function uncheckedInc(uint256 _number) external pure returns (uint256) {
return UncheckedMath.uncheckedInc(_number);
}

function uncheckedAdd(uint256 _lhs, uint256 _rhs) external pure returns (uint256) {
return UncheckedMath.uncheckedAdd(_lhs, _rhs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ struct InitializeData {
address blobVersionedHashRetriever;
}

/// @param verifier address of Verifier contract
/// @param verifierParams Verifier config parameters that describes the circuit to be verified
/// @param l2BootloaderBytecodeHash The hash of bootloader L2 bytecode
/// @param l2DefaultAccountBytecodeHash The hash of default account L2 bytecode
/// @param priorityTxMaxGasLimit maximum number of the L2 gas that a user can request for L1 -> L2 transactions
/// @param feeParams Fee parameters to be used for L1->L2 transactions
/// @param blobVersionedHashRetriever Address of contract used to pull the blob versioned hash for a transaction.
struct InitializeDataNewChain {
IVerifier verifier;
VerifierParams verifierParams;
bytes32 l2BootloaderBytecodeHash;
bytes32 l2DefaultAccountBytecodeHash;
uint256 priorityTxMaxGasLimit;
FeeParams feeParams;
address blobVersionedHashRetriever;
}

interface IDiamondInit {
function initialize(InitializeData calldata _initData) external returns (bytes32);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {Test} from "forge-std/Test.sol";
import {AddressAliasHelperTest} from "solpp/dev-contracts/test/AddressAliasHelperTest.sol";

contract AddressAliasHelperSharedTest is Test {
AddressAliasHelperTest addressAliasHelper;

function setUp() public {
addressAliasHelper = new AddressAliasHelperTest();
}

// add this to be excluded from coverage report
function test() internal virtual {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {AddressAliasHelperSharedTest} from "./_AddressAliasHelper_Shared.t.sol";

contract applyL1ToL2AliasTest is AddressAliasHelperSharedTest {
function testL1toL2AddressConversion() public {
address[2] memory l1Addresses = [
0xEEeEfFfffffFffFFFFffFFffFfFfFfffFfFFEEeE,
0x0000000000000000000000000000081759a874B3
];
address[2] memory l2ExpectedAddresses = [
0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF,
0x1111000000000000000000000000081759a885c4
];

for (uint i; i < l1Addresses.length; i++) {
address l2Address = addressAliasHelper.applyL1ToL2Alias(l1Addresses[i]);

assertEq(l2Address, l2ExpectedAddresses[i], "L1 to L2 address conversion is not correct");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {AddressAliasHelperSharedTest} from "./_AddressAliasHelper_Shared.t.sol";

contract undoL1ToL2AliasTest is AddressAliasHelperSharedTest {
function testL2toL1AddressConversion() public {
address[2] memory l2Addresses = [
0x1111000000000000000000000000000000001110,
0x1111000000000000000000000000081759a885c4
];
address[2] memory l1ExpectedAddresses = [
0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF,
0x0000000000000000000000000000081759a874B3
];

for (uint i; i < l2Addresses.length; i++) {
address l1Address = addressAliasHelper.undoL1ToL2Alias(l2Addresses[i]);

assertEq(l1Address, l1ExpectedAddresses[i], "L2 to L1 address conversion is not correct");
}
}
}
60 changes: 59 additions & 1 deletion l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import {UtilsFacet} from "../Utils/UtilsFacet.sol";
import {Diamond} from "solpp/state-transition/libraries/Diamond.sol";
import {DiamondInit} from "solpp/state-transition/chain-deps/DiamondInit.sol";
import {DiamondProxy} from "solpp/state-transition/chain-deps/DiamondProxy.sol";
import {AdminFacet} from "solpp/state-transition/chain-deps/facets/Admin.sol";
import {ExecutorFacet} from "solpp/state-transition/chain-deps/facets/Executor.sol";
import {GettersFacet} from "solpp/state-transition/chain-deps/facets/Getters.sol";
import {MailboxFacet} from "solpp/state-transition/chain-deps/facets/Mailbox.sol";
import {IVerifier, VerifierParams} from "solpp/state-transition/chain-deps/ZkSyncStateTransitionStorage.sol";
import {FeeParams, PubdataPricingMode} from "solpp/state-transition/chain-deps/ZkSyncStateTransitionStorage.sol";
import {InitializeData} from "solpp/state-transition/chain-interfaces/IDiamondInit.sol";
import {InitializeData, InitializeDataNewChain} from "solpp/state-transition/chain-interfaces/IDiamondInit.sol";
import {IExecutor, SystemLogKey} from "solpp/state-transition/chain-interfaces/IExecutor.sol";

bytes32 constant DEFAULT_L2_LOGS_TREE_ROOT_HASH = 0x0000000000000000000000000000000000000000000000000000000000000000;
Expand Down Expand Up @@ -92,6 +94,23 @@ library Utils {
return logs;
}

function createSystemLogsWithUpgradeTransaction(
bytes32 _expectedSystemContractUpgradeTxHash
) public pure returns (bytes[] memory) {
bytes[] memory logsWithoutUpgradeTx = createSystemLogs();
bytes[] memory logs = new bytes[](logsWithoutUpgradeTx.length + 1);
for (uint256 i = 0; i < logsWithoutUpgradeTx.length; i++) {
logs[i] = logsWithoutUpgradeTx[i];
}
logs[logsWithoutUpgradeTx.length] = constructL2Log(
true,
L2_BOOTLOADER_ADDRESS,
uint256(SystemLogKey.EXPECTED_SYSTEM_CONTRACT_UPGRADE_TX_HASH_KEY),
_expectedSystemContractUpgradeTxHash
);
return logs;
}

function createStoredBatchInfo() public pure returns (IExecutor.StoredBatchInfo memory) {
return
IExecutor.StoredBatchInfo({
Expand Down Expand Up @@ -141,6 +160,31 @@ library Utils {
return result;
}

function getAdminSelectors() public view returns (bytes4[] memory) {
bytes4[] memory selectors = new bytes4[](11);
selectors[0] = AdminFacet.setPendingAdmin.selector;
selectors[1] = AdminFacet.acceptAdmin.selector;
selectors[2] = AdminFacet.setValidator.selector;
selectors[3] = AdminFacet.setPorterAvailability.selector;
selectors[4] = AdminFacet.setPriorityTxMaxGasLimit.selector;
selectors[5] = AdminFacet.changeFeeParams.selector;
selectors[6] = AdminFacet.setTokenMultiplier.selector;
selectors[7] = AdminFacet.upgradeChainFromVersion.selector;
selectors[8] = AdminFacet.executeUpgrade.selector;
selectors[9] = AdminFacet.freezeDiamond.selector;
selectors[10] = AdminFacet.unfreezeDiamond.selector;
return selectors;
}

function getExecutorSelectors() public view returns (bytes4[] memory) {
bytes4[] memory selectors = new bytes4[](4);
selectors[0] = ExecutorFacet.commitBatches.selector;
selectors[1] = ExecutorFacet.proveBatches.selector;
selectors[2] = ExecutorFacet.executeBatches.selector;
selectors[3] = ExecutorFacet.revertBatches.selector;
return selectors;
}

function getGettersSelectors() public pure returns (bytes4[] memory) {
bytes4[] memory selectors = new bytes4[](29);
selectors[0] = GettersFacet.getVerifier.selector;
Expand Down Expand Up @@ -171,6 +215,7 @@ library Utils {
selectors[25] = GettersFacet.getTotalBatchesCommitted.selector;
selectors[26] = GettersFacet.getTotalBatchesVerified.selector;
selectors[27] = GettersFacet.getTotalBatchesExecuted.selector;
selectors[28] = GettersFacet.getL2SystemContractsUpgradeTxHash.selector;
return selectors;
}

Expand Down Expand Up @@ -321,6 +366,19 @@ library Utils {
});
}

function makeInitializeDataForNewChain() public pure returns (InitializeDataNewChain memory) {
return
InitializeDataNewChain({
verifier: makeVerifier(),
verifierParams: makeVerifierParams(),
l2BootloaderBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000,
l2DefaultAccountBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000,
priorityTxMaxGasLimit: 80000000,
feeParams: makeFeeParams(),
blobVersionedHashRetriever: address(0x23746765237749923040872834)
});
}

function makeDiamondProxy(Diamond.FacetCut[] memory facetCuts) public returns (address) {
DiamondInit diamondInit = new DiamondInit();
bytes memory diamondInitData = abi.encodeWithSelector(diamondInit.initialize.selector, makeInitializeData());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {UncheckedMathTest} from "./_UncheckedMath_Shared.t.sol";

import {UncheckedMath} from "solpp/common/libraries/UncheckedMath.sol";

contract UncheckedAddTest is UncheckedMathTest {
using UncheckedMath for uint256;
import {UncheckedMathSharedTest} from "./_UncheckedMath_Shared.t.sol";

contract UncheckedAddTest is UncheckedMathSharedTest {
function test_Add() public {
uint256 a = 1234;
uint256 b = 4321;
uint256 c = a.uncheckedAdd(b);
uint256 c = uncheckedMath.uncheckedAdd(a, b);
assertEq(c, 5555);
}

Expand All @@ -20,7 +16,7 @@ contract UncheckedAddTest is UncheckedMathTest {
uint256 b = 1;

// uncheckedAdd does not fail
uint256 c = a.uncheckedAdd(b);
uint256 c = uncheckedMath.uncheckedAdd(a, b);
assertEq(c, 0);

// regular addition fails with overflow
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {UncheckedMathTest} from "./_UncheckedMath_Shared.t.sol";

import {UncheckedMath} from "solpp/common/libraries/UncheckedMath.sol";

contract UncheckedIncTest is UncheckedMathTest {
using UncheckedMath for uint256;
import {UncheckedMathSharedTest} from "./_UncheckedMath_Shared.t.sol";

contract UncheckedIncTest is UncheckedMathSharedTest {
function test_Inc() public {
uint256 a = 1234;
uint256 c = a.uncheckedInc();
uint256 c = uncheckedMath.uncheckedInc(a);
assertEq(c, 1235);
}

function test_IncWithOverflow() public {
uint256 a = type(uint256).max;

// uncheckedInc does not fail
uint256 c = a.uncheckedInc();
uint256 c = uncheckedMath.uncheckedInc(a);
assertEq(c, 0);

// regular addition fails with overflow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,15 @@
pragma solidity 0.8.20;

import {Test} from "forge-std/Test.sol";
import {UncheckedMathTest} from "solpp/dev-contracts/test/UncheckedMathTest.sol";

contract UncheckedMathTest is Test {}
contract UncheckedMathSharedTest is Test {
UncheckedMathTest uncheckedMath;

function setUp() public {
uncheckedMath = new UncheckedMathTest();
}

// add this to be excluded from coverage report
function test() internal virtual {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// // SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol";
import {Diamond} from "solpp/state-transition/libraries/Diamond.sol";
import {DiamondProxy} from "solpp/state-transition/chain-deps/DiamondProxy.sol";

contract createNewChainTest is StateTransitionManagerTest {
function test_RevertWhen_InitialDiamondCutHashMismatch() public {
Diamond.DiamondCutData memory initialDiamondCutData = getDiamondCutData(sharedBridge);

vm.expectRevert(bytes("StateTransition: initial cutHash mismatch"));

createNewChain(initialDiamondCutData);
}

function test_RevertWhen_CalledNotByBridgehub() public {
Diamond.DiamondCutData memory initialDiamondCutData = getDiamondCutData(diamondInit);

vm.expectRevert(bytes("StateTransition: only bridgehub"));

chainContractAddress.createNewChain(chainId, baseToken, sharedBridge, admin, abi.encode(initialDiamondCutData));
}

function test_SuccessfulCreationOfNewChain() public {
createNewChain(getDiamondCutData(diamondInit));

address admin = chainContractAddress.getChainAdmin(chainId);
address newChainAddress = chainContractAddress.stateTransition(chainId);

assertEq(newChainAdmin, admin);
assertNotEq(newChainAddress, address(0));
}
}
Loading

0 comments on commit 39c5451

Please sign in to comment.