Error in Test of ZksyncMinimAccount Abstraction #4422
-
ErrorError: Compiler run failed:
Error: Cannot swap Variable headStart with Variable tail: too deep in the stack by 1 slots in [ headStart RET value13 headStart value12 value11 value10 value9 value8 value7 value6 value5 value4 value3 value2 value1 value0 tail ]
No memoryguard was present. Consider using memory-safe assembly only and annotating it via 'assembly ("memory-safe") { ... }'.
--> lib/foundry-era-contracts/src/system-contracts/contracts/libraries/MemoryTransactionHelper.sol:98:53:Test file// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import {Test} from "forge-std/Test.sol";
import {ZksyncMinimalAccount} from "../src/zksync/ZksyncMinimalAccount.sol";
import {ERC20Mock} from "lib/openzeppelin-contracts/contracts/mocks/token/ERC20Mock.sol";
import {Transaction} from "lib/foundry-era-contracts/src/system-contracts/contracts/libraries/MemoryTransactionHelper.sol";
contract ZksyncMinimalAccountTest is Test {
ZksyncMinimalAccount zksyncMinimalAccount;
ERC20Mock usdc;
// bytes4 constant EIP1271_SUCCESS_RETURN_VALUE = 0x1626ba7e;
// uint256 constant AMOUNT = 1e18;
bytes32 constant EMPTY_BYTES32 = bytes32(0);
address constant ANVIL_DEFAULT_ACCOUNT = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266;
function setUp() public {
zksyncMinimalAccount = new ZksyncMinimalAccount();
usdc = new ERC20Mock();
}
function testZkOwnerCanExecuteCommands() public {
// Arrange
// address dest = address(usdc);
// uint256 value = 0;
// bytes memory functionData = abi.encodeWithSelector(ERC20Mock.mint.selector, address(zksyncMinimalAccount), 1e18);
Transaction memory transaction =
_createUnsignedTransaction(zksyncMinimalAccount.owner(), 113, address(usdc), 0, abi.encodeWithSelector(ERC20Mock.mint.selector, address(zksyncMinimalAccount), 1e18));
// Act
vm.prank(zksyncMinimalAccount.owner());
zksyncMinimalAccount.executeTransaction(EMPTY_BYTES32, EMPTY_BYTES32, transaction);
// Assert
assertEq(usdc.balanceOf(address(zksyncMinimalAccount)), 1e18);
}
// Add assertions to check the state after execution
// function testNonOwnerCannotExecuteCommands() public {
// address dest = address(this);
// uint256 value = 1e18;
// bytes memory funcData = abi.encodeWithSignature("receive()");
// vm.prank(address(0x123));
// vm.expectRevert("Not owner");
// zksyncMinimalAccount.execute(dest, value, funcData);
// }
function _createUnsignedTransaction(
address from,
uint8 transactionType,
address to,
uint256 value,
bytes memory data
) internal view returns (Transaction memory) {
// Fetch the nonce for the 'minimalAccount' (our smart contract account)
// Note: vm.getNonce is a Foundry cheatcode. In a real zkSync environment,
// you'd query the NonceHolder system contract.
uint256 nonce = vm.getNonce(address(zksyncMinimalAccount));
// Initialize an empty array for factory dependencies
bytes32[] memory factoryDeps = new bytes32[](0);
return Transaction({
txType: transactionType, // e.g., 113 for zkSync AA
from: uint256(uint160(from)), // Cast 'from' address to uint256
to: uint256(uint160(to)), // Cast 'to' address to uint256
gasLimit: 16777216, // Placeholder value (adjust as needed)
gasPerPubdataByteLimit: 16777216, // Placeholder value
maxFeePerGas: 16777216, // Placeholder value
maxPriorityFeePerGas: 16777216, // Placeholder value
paymaster: 0, // No paymaster for this example
nonce: nonce, // Use the fetched nonce
value: value, // Value to be transferred
reserved: [uint256(0), uint256(0), uint256(0), uint256(0)], // Default empty
data: data, // Transaction calldata
signature: hex"", // Empty signature for an unsigned transaction
factoryDeps: factoryDeps, // Empty factory dependencies
paymasterInput: hex"", // No paymaster input
reservedDynamic: hex"" // Empty reserved dynamic field
});
}
}Used --via-ir=true - still same error. without it also use |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
|
The stack too deep error happens because you're creating a struct with too many fields at once. The main issue was that Solidity's stack can only hold ~16 variables at once. Your original function was trying to create a struct with many fields all in one go, which exceeded this limit Instead of creating the Transaction struct in one go, create an empty struct first, then assign each field individually. |
Beta Was this translation helpful? Give feedback.
-
|
Got the solution from the AI. added these lines in the |
Beta Was this translation helpful? Give feedback.
Got the solution from the AI.
added these lines in the
.tomlfileviaIR = trueoptimizer = trueoptimizer_runs = 200