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

chore(test): Moved transaction validator tests to foundry #151

Merged
merged 7 commits into from
Jan 3, 2024
Merged
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

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
Loading