Skip to content

Commit

Permalink
Merge branch 'main' into fix-jrigada-simulation-fail-zero-balance-wit…
Browse files Browse the repository at this point in the history
…h-paymaster
  • Loading branch information
Jrigada authored Nov 20, 2024
2 parents c8eebf7 + 0c43026 commit fde7881
Show file tree
Hide file tree
Showing 14 changed files with 141 additions and 29 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install foundry-zksync
run: |
cd /tmp && curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash
run: cp ./install-foundry-zksync ./foundryup-zksync/* /tmp/ && cd /tmp && ./install-foundry-zksync
- name: Verify installation
run: forge --version
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/common/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ impl ProjectCompiler {
let is_target_file =
self.files.is_empty() || self.files.iter().any(|f| artifact_id.path == *f);
if is_target_file {
if let Some(mls) = &artifact.missing_libraries {
if let Some(mls) = artifact.missing_libraries() {
missing_libs_unique.extend(mls.clone());
}
}
Expand Down Expand Up @@ -422,7 +422,7 @@ impl ProjectCompiler {
ZkMissingLibrary {
contract_path: contract_path.to_string(),
contract_name: contract_name.to_string(),
missing_libraries: art.missing_libraries.clone().unwrap_or_default(),
missing_libraries: art.missing_libraries().cloned().unwrap_or_default(),
}
})
.collect();
Expand Down
30 changes: 24 additions & 6 deletions crates/forge/bin/cmd/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,28 @@ impl CreateArgs {
let ZkContractArtifact { bytecode, hash, factory_dependencies, abi, .. } = artifact;

let abi = abi.expect("Abi not found");

let bin = bytecode.expect("Bytecode not found");

let bytecode = match bin.object() {
BytecodeObject::Bytecode(bytes) => bytes.to_vec(),
_ => {
let link_refs = bin
.missing_libraries
.iter()
.map(|library| {
let mut parts = library.split(':');
let path = parts.next().unwrap();
let name = parts.next().unwrap();
format!("\t{name}: {path}")
})
.collect::<HashSet<String>>()
.into_iter()
.collect::<Vec<String>>()
.join("\n");
eyre::bail!("Dynamic linking not supported in `create` command - deploy the following library contracts first, then provide the address to link at compile time\n{}", link_refs)
}
};
let bytecode_hash = H256::from_str(&hash.expect("Contract hash not found"))?;
let bytecode = bin.object.clone().into_bytes().unwrap().to_vec();

// Add arguments to constructor
let config = self.eth.try_load_config_emit_warnings()?;
Expand Down Expand Up @@ -221,12 +239,12 @@ impl CreateArgs {
queue.push_back(dep.clone())
}

// TODO(zk): ensure factory deps are also linked
let fdep_bytecode = fdep_art
.bytecode
.clone()
.expect("Bytecode not found for factory dependency")
.object
.clone()
.object()
.into_bytes()
.unwrap()
.to_vec();
Expand All @@ -243,7 +261,7 @@ impl CreateArgs {
let sender = self.eth.wallet.from.expect("required");
self.deploy_zk(
abi,
bin.object,
bin.object(),
params,
provider,
chain_id,
Expand All @@ -262,7 +280,7 @@ impl CreateArgs {
let provider = ProviderBuilder::<_, _, AnyNetwork>::default().on_provider(provider);
self.deploy_zk(
abi,
bin.object,
bin.object(),
params,
provider,
chain_id,
Expand Down
3 changes: 2 additions & 1 deletion crates/forge/src/multi_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,8 @@ impl MultiContractRunnerBuilder {
if let Some(abi) = contract.abi {
let bytecode = contract.bytecode.as_ref();

if let Some(bytecode_object) = bytecode.map(|b| b.object.clone()) {
// TODO(zk): retrieve link_references
if let Some(bytecode_object) = bytecode.map(|b| b.object()) {
let compact_bytecode = CompactBytecode {
object: bytecode_object.clone(),
source_map: None,
Expand Down
13 changes: 13 additions & 0 deletions crates/forge/tests/fixtures/zk/Libraries.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.8.7 <0.9.0;

import {UsesFoo} from "../src/WithLibraries.sol";
import "forge-std/Script.sol";

contract DeployUsesFoo is Script {
function run () external {
// should fail because `UsesFoo` is unlinked
bytes memory _code = vm.getCode("UsesFoo");
}
}
2 changes: 1 addition & 1 deletion crates/forge/tests/it/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl ForgeTestProfile {
zk_config.zksync.startup = true;
zk_config.zksync.fallback_oz = true;
zk_config.zksync.optimizer_mode = '3';
zk_config.zksync.zksolc = Some(foundry_config::SolcReq::Version(Version::new(1, 5, 4)));
zk_config.zksync.zksolc = Some(foundry_config::SolcReq::Version(Version::new(1, 5, 7)));
zk_config.fuzz.no_zksync_reserved_addresses = true;

zk_config
Expand Down
54 changes: 54 additions & 0 deletions crates/forge/tests/it/zk/linking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use foundry_test_utils::{forgetest_async, util, TestProject};

use crate::test_helpers::{deploy_zk_contract, run_zk_script_test};

// TODO(zk): add test that actually does the deployment
// of the unlinked contract via script, once recursive linking is supported
// and once we also support doing deploy-time linking

forgetest_async!(
#[should_panic = "no bytecode for contract; is it abstract or unlinked?"]
script_using_unlinked_fails,
|prj, cmd| {
setup_libs_prj(&mut prj);
run_zk_script_test(
prj.root(),
&mut cmd,
"./script/Libraries.s.sol",
"DeployUsesFoo",
None,
1,
Some(&["-vvvvv"]),
);
}
);

forgetest_async!(
#[should_panic = "Dynamic linking not supported"]
create_using_unlinked_fails,
|prj, cmd| {
setup_libs_prj(&mut prj);

// we don't really connect to the rpc because
// we expect to fail before that point
let foo_address = deploy_zk_contract(
&mut cmd,
"127.0.0.1:1234",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"./src/WithLibraries.sol:UsesFoo",
)
.expect("Failed to deploy UsesFoo contract");

assert!(!foo_address.is_empty(), "Deployed address should not be empty");
}
);

fn setup_libs_prj(prj: &mut TestProject) {
util::initialize(prj.root());
prj.add_script("Libraries.s.sol", include_str!("../../fixtures/zk/Libraries.s.sol")).unwrap();
prj.add_source(
"WithLibraries.sol",
include_str!("../../../../../testdata/zk/WithLibraries.sol"),
)
.unwrap();
}
1 change: 1 addition & 0 deletions crates/forge/tests/it/zk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ mod factory_deps;
mod fork;
mod fuzz;
mod invariant;
mod linking;
mod logs;
mod nft;
mod ownership;
Expand Down
3 changes: 2 additions & 1 deletion crates/script/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,8 @@ impl LinkedBuildData {
for (id, contract) in zk_contracts {
if let Some(abi) = contract.abi {
let bytecode = contract.bytecode.as_ref();
if let Some(bytecode_object) = bytecode.map(|b| b.object.clone()) {
// TODO(zk): retrieve link_references
if let Some(bytecode_object) = bytecode.map(|b| b.object()) {
let compact_bytecode = CompactBytecode {
object: bytecode_object.clone(),
source_map: None,
Expand Down
2 changes: 1 addition & 1 deletion crates/zksync/compiler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub fn config_create_project(
{
zksolc
} else if !config.offline {
let default_version = semver::Version::new(1, 5, 4);
let default_version = semver::Version::new(1, 5, 7);
let mut zksolc = ZkSolc::find_installed_version(&default_version)?;
if zksolc.is_none() {
ZkSolc::blocking_install(&default_version)?;
Expand Down
4 changes: 2 additions & 2 deletions crates/zksync/compiler/src/zksolc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ impl DualCompiledContracts {
// at this stage for zksolc, and BytecodeObject as ref will get the bytecode bytes.
// We should be careful however and check/handle errors in
// case an Unlinked BytecodeObject gets here somehow
let bytes = bytecode.object.clone().into_bytes().unwrap();
let bytes = bytecode.object().into_bytes().unwrap();
zksolc_all_bytecodes.insert(hash.clone(), bytes.to_vec());
}
}
Expand Down Expand Up @@ -167,7 +167,7 @@ impl DualCompiledContracts {
// bytes. However, we should check and
// handle errors in case an Unlinked BytecodeObject gets
// here somehow
let bytecode_vec = bytecode.object.clone().into_bytes().unwrap().to_vec();
let bytecode_vec = bytecode.object().into_bytes().unwrap().to_vec();
let mut factory_deps_vec: Vec<Vec<u8>> = factory_deps_map
.keys()
.map(|factory_hash| {
Expand Down
22 changes: 15 additions & 7 deletions install-foundry-zksync
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ set -e
INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/foundryup-zksync/install"
FOUNDRYUP_ZKSYNC_URL="https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/foundryup-zksync/foundryup-zksync"

# Download the install script
echo "Downloading the install script..."
curl -L "$INSTALL_SCRIPT_URL" -o install
if [ -n "${CI}" ]; then
echo "Using local install script..."
else
# Download the install script
echo "Downloading the install script..."
curl -L "$INSTALL_SCRIPT_URL" -o install
fi

echo "Making install script executable..."
chmod +x ./install
Expand All @@ -19,11 +23,11 @@ echo "Running the installation script..."
# Extract the exact path from the install.log
# Use sed to precisely capture the path after 'source' and before the next apostrophe
SHELL_CONFIG_FILE=$(sed -n "s/.*Run 'source \(.*\)'.*/\1/p" install.log)
FOUNDRY_BIN_DIR="${XDG_CONFIG_HOME:-$HOME}/.foundry/bin"

if [ -n "$SHELL_CONFIG_FILE" ]; then
if [ -n "${CI}" ]; then
# Add manually to $PATH in CI mode as GHA does not work with `.`
FOUNDRY_BIN_DIR="${XDG_CONFIG_HOME:-$HOME}/.foundry/bin"
echo "adding '${FOUNDRY_BIN_DIR}' to PATH and GITHUB_PATH"
export PATH="$PATH:$FOUNDRY_BIN_DIR"
echo "${FOUNDRY_BIN_DIR}" >> $GITHUB_PATH
Expand All @@ -36,8 +40,12 @@ else
echo "No shell configuration file detected. Please source your shell manually or start a new terminal session."
fi

echo "Downloading foundryup-zksync..."
curl -L "$FOUNDRYUP_ZKSYNC_URL" -o foundryup-zksync
if [ -n "${CI}" ]; then
echo "Using local foundryup-zksync script..."
else
echo "Downloading foundryup-zksync..."
curl -L "$FOUNDRYUP_ZKSYNC_URL" -o foundryup-zksync
fi

echo "Making foundryup-zksync executable..."
chmod +x ./foundryup-zksync
Expand All @@ -54,7 +62,7 @@ echo "Cleanup completed."
echo "Installation completed successfully!"

echo "Verifying installation..."
if "$HOME/.foundry/bin/forge" --version | grep -q "0.0.2"; then
if "${FOUNDRY_BIN_DIR}/forge" --version | grep -q "0.0.2"; then
echo "Forge version 0.0.2 is successfully installed."
else
echo "Installation verification failed. Forge is not properly installed."
Expand Down
17 changes: 17 additions & 0 deletions testdata/zk/WithLibraries.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: UNLICENSED

pragma solidity >=0.8.7 <0.9.0;

library Foo {
function add(uint256 a, uint256 b) external pure returns (uint256 c) {
c = a + b;
}
}

contract UsesFoo {
uint256 number;

constructor() {
number = Foo.add(42, 0);
}
}

0 comments on commit fde7881

Please sign in to comment.