Skip to content

Commit

Permalink
chore(test): Moved transaction validator tests to foundry (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
mm-zk authored Jan 3, 2024
1 parent 9ddf15d commit ab86cf9
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 232 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
pragma solidity 0.8.20;

import {TransactionValidatorSharedTest} from "./_TransactionValidator_Shared.t.sol";
import {IMailbox} from "solpp/zksync/interfaces/IMailbox.sol";
import {TransactionValidator} from "solpp/zksync/libraries/TransactionValidator.sol";

contract ValidateL1L2TxTest is TransactionValidatorSharedTest {
function test_BasicRequestL1L2() public pure {
IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction();
testTx.gasLimit = 500000;
validateL1ToL2Transaction(testTx, 500000);
}

function test_RevertWhen_GasLimitDoesntCoverOverhead() public {
IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction();
// The limit is so low, that it doesn't even cover the overhead
testTx.gasLimit = 0;
vm.expectRevert(bytes("my"));
validateL1ToL2Transaction(testTx, 500000);
}

function test_RevertWhen_GasLimitHigherThanMax() public {
IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction();
// We should fail, if user asks for too much gas.
// Notice, that we subtract the transaction overhead costs from the user's gas limit
// before checking that it is below the max gas limit.
uint256 priorityTxMaxGasLimit = 500000;
testTx.gasLimit = priorityTxMaxGasLimit + 1000000;
vm.expectRevert(bytes("ui"));
validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit);
}

function test_RevertWhen_TooMuchPubdata() public {
IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction();
// We should fail, if user's transaction could output too much pubdata.
// We can allow only 99k of pubdata (otherwise we'd exceed the ethereum calldata limits).

uint256 priorityTxMaxGasLimit = 500000;
testTx.gasLimit = priorityTxMaxGasLimit;
// So if the pubdata costs per byte is 1 - then this transaction could produce 500k of pubdata.
// (hypothetically, assuming all the gas was spent on writing).
testTx.gasPerPubdataByteLimit = 1;
vm.expectRevert(bytes("uk"));
validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit);
}

function test_RevertWhen_BelowMinimumCost() public {
IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction();
uint256 priorityTxMaxGasLimit = 500000;
testTx.gasLimit = 200000;
vm.expectRevert(bytes("up"));
validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit);
}

function test_RevertWhen_HugePubdata() public {
IMailbox.L2CanonicalTransaction memory testTx = createTestTransaction();
uint256 priorityTxMaxGasLimit = 500000;
testTx.gasLimit = 400000;
// Setting huge pubdata limit should cause the panic.
testTx.gasPerPubdataByteLimit = type(uint256).max;
vm.expectRevert();
validateL1ToL2Transaction(testTx, priorityTxMaxGasLimit);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
pragma solidity 0.8.20;

import {TransactionValidatorSharedTest} from "./_TransactionValidator_Shared.t.sol";
import {IMailbox} from "solpp/zksync/interfaces/IMailbox.sol";
import {TransactionValidator} from "solpp/zksync/libraries/TransactionValidator.sol";

contract ValidateUpgradeTxTest is TransactionValidatorSharedTest {
function test_BasicRequest() public pure {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_RequestNotFromSystemContract() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// only system contracts (address < 2^16) are allowed to send upgrade transactions.
testTx.from = uint256(1000000000);
vm.expectRevert(bytes("ua"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_RequestNotToSystemContract() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// Now the 'to' address it too large.
testTx.to = uint256(type(uint160).max) + 100;
vm.expectRevert(bytes("ub"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_PaymasterIsNotZero() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// Paymaster must be 0 - otherwise we revert.
testTx.paymaster = 1;
vm.expectRevert(bytes("uc"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_ValueIsNotZero() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// Value must be 0 - otherwise we revert.
testTx.value = 1;
vm.expectRevert(bytes("ud"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_Reserved0IsNonZero() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// reserved 0 must be 0 - otherwise we revert.
testTx.reserved[0] = 1;
vm.expectRevert(bytes("ue"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_Reserved1IsTooLarge() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// reserved 1 must be a valid address
testTx.reserved[1] = uint256(type(uint160).max) + 100;
vm.expectRevert(bytes("uf"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_Reserved2IsNonZero() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// reserved 2 must be 0 - otherwise we revert.
testTx.reserved[2] = 1;
vm.expectRevert(bytes("ug"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_Reserved3IsNonZero() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// reserved 3 be 0 - otherwise we revert.
testTx.reserved[3] = 1;
vm.expectRevert(bytes("uo"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_NonZeroSignature() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// Signature must be 0 - otherwise we revert.
testTx.signature = bytes("hello");
vm.expectRevert(bytes("uh"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_PaymasterInputNonZero() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// PaymasterInput must be 0 - otherwise we revert.
testTx.paymasterInput = bytes("hi");
vm.expectRevert(bytes("ul"));
TransactionValidator.validateUpgradeTransaction(testTx);
}

function test_RevertWhen_ReservedDynamicIsNonZero() public {
IMailbox.L2CanonicalTransaction memory testTx = createUpgradeTransaction();
// ReservedDynamic must be 0 - otherwise we revert.
testTx.reservedDynamic = bytes("something");
vm.expectRevert(bytes("um"));
TransactionValidator.validateUpgradeTransaction(testTx);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import {Test} from "forge-std/Test.sol";
import {IMailbox} from "solpp/zksync/interfaces/IMailbox.sol";
//import {TransactionValidator} from "solpp/zksync/libraries/TransactionValidator.sol";
import {TransactionValidator} from "cache/solpp-generated-contracts/zksync/libraries/TransactionValidator.sol";

contract TransactionValidatorSharedTest is Test {
constructor() {}

function createTestTransaction() public pure returns (IMailbox.L2CanonicalTransaction memory testTx) {
testTx = IMailbox.L2CanonicalTransaction({
txType: 0,
from: uint256(uint160(1_000_000_000)),
to: uint256(uint160(0)),
gasLimit: 500000,
gasPerPubdataByteLimit: 800,
maxFeePerGas: uint256(0),
maxPriorityFeePerGas: uint256(0),
paymaster: uint256(0),
nonce: uint256(0),
value: 0,
reserved: [uint256(0), uint256(0), uint256(0), uint256(0)],
data: new bytes(0),
signature: new bytes(0),
factoryDeps: new uint256[](0),
paymasterInput: new bytes(0),
reservedDynamic: new bytes(0)
});
}

function createUpgradeTransaction() public pure returns (IMailbox.L2CanonicalTransaction memory testTx) {
testTx = createTestTransaction();
testTx.from = uint256(0x8001);
testTx.to = uint256(0x8007);
}

function validateL1ToL2Transaction(
IMailbox.L2CanonicalTransaction memory _transaction,
uint256 _priorityTxMaxGasLimit
) public pure {
TransactionValidator.validateL1ToL2Transaction(_transaction, abi.encode(_transaction), _priorityTxMaxGasLimit);
}
}
Loading

0 comments on commit ab86cf9

Please sign in to comment.