diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 9bceec4..3edf373 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -69,11 +69,21 @@ jobs: #runs-on: ubuntu-latest runs-on: namespace-profile-btp-scs steps: + - name: Setup 1Password + uses: 1password/load-secrets-action/configure@v2 + with: + service-account-token: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} + + - name: Load secrets + uses: 1password/load-secrets-action@v2 + env: + NPM_TOKEN: op://platform/npmjs/credential + PAT_TOKEN: op://platform/github-commit-pat/credential + - name: Checkout uses: namespacelabs/nscloud-checkout-action@v5 with: - submodules: recursive - token: ${{ secrets.PAT_TOKEN }} + token: ${{ env.PAT_TOKEN }} - name: Setup caches uses: namespacelabs/nscloud-cache-action@v1 @@ -97,119 +107,6 @@ jobs: - name: Install Node dependencies run: bun install - - name: Install circom - if: github.repository == 'settlemint/solidity-zeto' - run: | - curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh -s -- -y - git clone https://github.com/iden3/circom.git - cd circom - cargo build --release - cargo install --path circom - - - name: Install snarkjs - if: github.repository == 'settlemint/solidity-zeto' - run: | - bun install -g snarkjs@latest - - - name: Install zeto - if: github.repository == 'settlemint/solidity-zeto' - run: | - git clone https://github.com/victoryeo/zeto.git - cd zeto - cd zkp/circuits - bun install - cd .. - circom circuits/anon_enc_nullifier.circom --output ./js/lib --sym --wasm - circom circuits/anon_enc.circom --output ./js/lib --sym --wasm - circom circuits/anon_nullifier.circom --output ./js/lib --sym --wasm - circom circuits/anon.circom --output ./js/lib --sym --wasm - circom circuits/check-nullifiers.circom --output ./js/lib --sym --wasm - circom circuits/nf_anon_nullifier.circom --output ./js/lib --sym --wasm - circom circuits/nf_anon.circom --output ./js/lib --sym --wasm - - - name: Create folders - if: github.repository == 'settlemint/solidity-zeto' - run: | - mkdir -p ./zeto/proving-keys - mkdir -p ./zeto/contracts-lib - - - name: Download ptau - if: github.repository == 'settlemint/solidity-zeto' - working-directory: zeto/proving-keys/ - run: | - wget -nv https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_12.ptau - wget -nv https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_13.ptau - wget -nv https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_16.ptau - wget -nv https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_11.ptau - wget -nv https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_15.ptau - - - name: Generate R1CS circuit format - if: github.repository == 'settlemint/solidity-zeto' - working-directory: zeto/zkp/ - run: | - circom circuits/anon_enc_nullifier.circom --output ../proving-keys --r1cs - circom circuits/anon_enc.circom --output ../proving-keys --r1cs - circom circuits/anon_nullifier.circom --output ../proving-keys --r1cs - circom circuits/anon.circom --output ../proving-keys --r1cs - circom circuits/check-nullifiers.circom --output ../proving-keys --r1cs - circom circuits/nf_anon_nullifier.circom --output ../proving-keys --r1cs - circom circuits/nf_anon.circom --output ../proving-keys --r1cs - - - name: Generate proving keys - if: github.repository == 'settlemint/solidity-zeto' - working-directory: zeto/zkp/ - run: | - snarkjs groth16 setup ../proving-keys/anon.r1cs ../proving-keys/powersOfTau28_hez_final_12.ptau ../proving-keys/anon.zkey - snarkjs groth16 setup ../proving-keys/anon_enc.r1cs ../proving-keys/powersOfTau28_hez_final_13.ptau ../proving-keys/anon_enc.zkey - snarkjs groth16 setup ../proving-keys/anon_nullifier.r1cs ../proving-keys/powersOfTau28_hez_final_16.ptau ../proving-keys/anon_nullifier.zkey - snarkjs groth16 setup ../proving-keys/anon_enc_nullifier.r1cs ../proving-keys/powersOfTau28_hez_final_16.ptau ../proving-keys/anon_enc_nullifier.zkey - snarkjs groth16 setup ../proving-keys/nf_anon.r1cs ../proving-keys/powersOfTau28_hez_final_11.ptau ../proving-keys/nf_anon.zkey - snarkjs groth16 setup ../proving-keys/nf_anon_nullifier.r1cs ../proving-keys/powersOfTau28_hez_final_15.ptau ../proving-keys/nf_anon_nullifier.zkey - - - name: Per-circuit set up ceremony on proving keys - if: github.repository == 'settlemint/solidity-zeto' - working-directory: zeto/zkp/ - run: | - snarkjs zkey contribute ../proving-keys/anon.zkey ../proving-keys/anon_new.zkey --name="contribution" -v -e="random entropy" - snarkjs zkey contribute ../proving-keys/anon_enc.zkey ../proving-keys/anon_enc_new.zkey --name="contribution" -v -e="random entropy" - snarkjs zkey contribute ../proving-keys/anon_nullifier.zkey ../proving-keys/anon_nullifier_new.zkey --name="contribution" -v -e="random entropy" - snarkjs zkey contribute ../proving-keys/anon_enc_nullifier.zkey ../proving-keys/anon_enc_nullifier_new.zkey --name="contribution" -v -e="random entropy" - snarkjs zkey contribute ../proving-keys/nf_anon.zkey ../proving-keys/nf_anon_new.zkey --name="contribution" -v -e="random entropy" - snarkjs zkey contribute ../proving-keys/nf_anon_nullifier.zkey ../proving-keys/nf_anon_nullifier_new.zkey --name="contribution" -v -e="random entropy" - - - name: Generate verfication keys - if: github.repository == 'settlemint/solidity-zeto' - working-directory: zeto/zkp/ - run: | - snarkjs zkey export verificationkey ../proving-keys/anon_new.zkey ../proving-keys/anon-vkey.json - snarkjs zkey export verificationkey ../proving-keys/anon_enc_new.zkey ../proving-keys/anon_enc-vkey.json - snarkjs zkey export verificationkey ../proving-keys/anon_nullifier_new.zkey ../proving-keys/anon_nullifier-vkey.json - snarkjs zkey export verificationkey ../proving-keys/anon_enc_nullifier_new.zkey ../proving-keys/anon_enc_nullifier-vkey.json - snarkjs zkey export verificationkey ../proving-keys/nf_anon_new.zkey ../proving-keys/nf_anon-vkey.json - snarkjs zkey export verificationkey ../proving-keys/nf_anon_nullifier_new.zkey ../proving-keys/nf_anon_nullifier-vkey.json - - - name: Generate solidity verifier library - if: github.repository == 'settlemint/solidity-zeto' - working-directory: zeto/zkp/ - run: | - snarkjs zkey export solidityverifier ../proving-keys/anon_new.zkey ../contracts-lib/verifier_anon.sol - snarkjs zkey export solidityverifier ../proving-keys/anon_enc_new.zkey ../contracts-lib/verifier_anon_enc.sol - snarkjs zkey export solidityverifier ../proving-keys/anon_nullifier_new.zkey ../contracts-lib/verifier_anon_nullifier.sol - snarkjs zkey export solidityverifier ../proving-keys/anon_enc_nullifier_new.zkey ../contracts-lib/verifier_anon_enc_nullifier.sol - snarkjs zkey export solidityverifier ../proving-keys/nf_anon_new.zkey ../contracts-lib/verifier_nf_anon.sol - snarkjs zkey export solidityverifier ../proving-keys/nf_anon_nullifier_new.zkey ../contracts-lib/verifier_nf_anon_nullifier.sol - - - name: Edit solidity files - if: github.repository == 'settlemint/solidity-zeto' - working-directory: zeto/contracts-lib/ - run: | - sed 's/Groth16Verifier/Groth16Verifier_Anon/' verifier_anon.sol > ../solidity/contracts/lib/verifier_anon.sol - sed 's/Groth16Verifier/Groth16Verifier_AnonEnc/' verifier_anon_enc.sol > ../solidity/contracts/lib/verifier_anon_enc.sol - sed 's/Groth16Verifier/Groth16Verifier_AnonNullifier/' verifier_anon_nullifier.sol > ../solidity/contracts/lib/verifier_anon_nullifier.sol - sed 's/Groth16Verifier/Groth16Verifier_AnonEncNullifier/' verifier_anon_enc_nullifier.sol > ../solidity/contracts/lib/verifier_anon_enc_nullifier.sol - sed 's/Groth16Verifier/Groth16Verifier_NFAnon/' verifier_nf_anon.sol > ../solidity/contracts/lib/verifier_nf_anon.sol - sed 's/Groth16Verifier/Groth16Verifier_NFAnonNullifier/' verifier_nf_anon_nullifier.sol > ../solidity/contracts/lib/verifier_nf_anon_nullifier.sol - - name: Run Forge build run: | forge --version @@ -275,14 +172,6 @@ jobs: echo "IPFS hashes: $ipfs_hashes" - for hash in $ipfs_hashes; do - echo "Processing IPFS hash: $hash" - echo "Pinning $hash to Infura" - curl -s -X POST -u "${{ secrets.INFURA_IPFS_API_KEY }}:${{ secrets.INFURA_IPFS_API_SECRET }}" "https://ipfs.infura.io:5001/api/v0/pin/add?arg=$hash" || true - echo "Pinning $hash to Chainstack" - curl -s --request POST --url https://api.chainstack.com/v1/ipfs/pins/pinbycid --header 'accept: application/json' --header 'authorization: Bearer ${{ secrets.CHAINSTACK_API_KEY }}' --header 'content-type: application/json' --data "{\"bucket_id\": \"BUCK-8412-8292-8457\", \"cid\": \"$hash\"}" || true - done - # Write IPFS hashes to a file echo "$ipfs_hashes" | sed 's/^/"/;s/$/"/' | paste -sd ',' > ipfs_hashes.txt fi @@ -290,7 +179,7 @@ jobs: - name: Report code coverage if: github.event_name == 'pull_request' - uses: zgosalvez/github-actions-report-lcov@v4.1.19 + uses: zgosalvez/github-actions-report-lcov@4.1.20 continue-on-error: true with: coverage-files: lcov.info @@ -355,7 +244,7 @@ jobs: - uses: JS-DevTools/npm-publish@v3 with: - token: ${{ secrets.NPM_TOKEN }} + token: ${{ env.NPM_TOKEN }} package: ./package.json access: public provenance: false diff --git a/Dockerfile b/Dockerfile index f829aac..ed1b1a7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM node:22.11.0 AS build -COPY --from=oven/bun:1.1.34-debian --chmod=0777 /usr/local/bin/bun /bin/bun +COPY --from=oven/bun:1.1.37-debian --chmod=0777 /usr/local/bin/bun /bin/bun ENV BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 ENV BUN_INSTALL_BIN=/bin @@ -24,6 +24,7 @@ WORKDIR /usecase USER root RUN bun install +RUN if [ -f "scripts/decompress.js" ]; then bun scripts/decompress.js; fi RUN forge build RUN bun hardhat compile diff --git a/lib/forge-std/src/Vm.sol b/lib/forge-std/src/Vm.sol index 73fc47e..9216369 100644 --- a/lib/forge-std/src/Vm.sol +++ b/lib/forge-std/src/Vm.sol @@ -70,6 +70,16 @@ interface VmSafe { Unknown } + /// The transaction type (`txType`) of the broadcast. + enum BroadcastTxType { + // Represents a CALL broadcast tx. + Call, + // Represents a CREATE broadcast tx. + Create, + // Represents a CREATE2 broadcast tx. + Create2 + } + /// An Ethereum log. Returned by `getRecordedLogs`. struct Log { // The topics of the log, including the signature, if any. @@ -264,16 +274,6 @@ interface VmSafe { address contractAddr; } - /// The transaction type (`txType`) of the broadcast. - enum BroadcastTxType { - // Represents a CALL broadcast tx. - Call, - // Represents a CREATE broadcast tx. - Create, - // Represents a CREATE2 broadcast tx. - Create2 - } - /// Represents a transaction's broadcast details. struct BroadcastTxSummary { // The hash of the transaction that was broadcasted @@ -289,6 +289,22 @@ interface VmSafe { bool success; } + /// Holds a signed EIP-7702 authorization for an authority account to delegate to an implementation. + struct SignedDelegation { + // The y-parity of the recovered secp256k1 signature (0 or 1). + uint8 v; + // First 32 bytes of the signature. + bytes32 r; + // Second 32 bytes of the signature. + bytes32 s; + // The current nonce of the authority account at signing time. + // Used to ensure signature can't be replayed after account nonce changes. + uint64 nonce; + // Address of the contract implementation that will be delegated to. + // Gets encoded into delegation code: 0xef0100 || implementation. + address implementation; + } + // ======== Crypto ======== /// Derives a private key from the name, labels the account with that name, and returns the wallet. @@ -332,14 +348,12 @@ interface VmSafe { function rememberKey(uint256 privateKey) external returns (address keyAddr); /// Derive a set number of wallets from a mnemonic at the derivation path `m/44'/60'/0'/0/{0..count}`. - /// /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. function rememberKeys(string calldata mnemonic, string calldata derivationPath, uint32 count) external returns (address[] memory keyAddrs); /// Derive a set number of wallets from a mnemonic in the specified language at the derivation path `m/44'/60'/0'/0/{0..count}`. - /// /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. function rememberKeys( string calldata mnemonic, @@ -686,7 +700,7 @@ interface VmSafe { returns (address deployedAddress); /// Returns true if the given path points to an existing entity, else returns false. - function exists(string calldata path) external returns (bool result); + function exists(string calldata path) external view returns (bool result); /// Performs a foreign function call via the terminal. function ffi(string[] calldata commandInput) external returns (bytes memory result); @@ -700,6 +714,29 @@ interface VmSafe { /// Gets the artifact path from deployed code (aka. runtime code). function getArtifactPathByDeployedCode(bytes calldata deployedCode) external view returns (string memory path); + /// Returns the most recent broadcast for the given contract on `chainId` matching `txType`. + /// For example: + /// The most recent deployment can be fetched by passing `txType` as `CREATE` or `CREATE2`. + /// The most recent call can be fetched by passing `txType` as `CALL`. + function getBroadcast(string calldata contractName, uint64 chainId, BroadcastTxType txType) + external + view + returns (BroadcastTxSummary memory); + + /// Returns all broadcasts for the given contract on `chainId` with the specified `txType`. + /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. + function getBroadcasts(string calldata contractName, uint64 chainId, BroadcastTxType txType) + external + view + returns (BroadcastTxSummary[] memory); + + /// Returns all broadcasts for the given contract on `chainId`. + /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. + function getBroadcasts(string calldata contractName, uint64 chainId) + external + view + returns (BroadcastTxSummary[] memory); + /// Gets the creation bytecode from an artifact file. Takes in the relative path to the json file or the path to the /// artifact in the form of :: where and parts are optional. function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); @@ -708,11 +745,28 @@ interface VmSafe { /// artifact in the form of :: where and parts are optional. function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); + /// Returns the most recent deployment for the current `chainId`. + function getDeployment(string calldata contractName) external view returns (address deployedAddress); + + /// Returns the most recent deployment for the given contract on `chainId` + function getDeployment(string calldata contractName, uint64 chainId) + external + view + returns (address deployedAddress); + + /// Returns all deployments for the given contract on `chainId` + /// Sorted in descending order of deployment time i.e descending order of BroadcastTxSummary.blockNumber. + /// The most recent deployment is the first element, and the oldest is the last. + function getDeployments(string calldata contractName, uint64 chainId) + external + view + returns (address[] memory deployedAddresses); + /// Returns true if the path exists on disk and is pointing at a directory, else returns false. - function isDir(string calldata path) external returns (bool result); + function isDir(string calldata path) external view returns (bool result); /// Returns true if the path exists on disk and is pointing at a regular file, else returns false. - function isFile(string calldata path) external returns (bool result); + function isFile(string calldata path) external view returns (bool result); /// Get the path of the current project root. function projectRoot() external view returns (string memory path); @@ -782,7 +836,7 @@ interface VmSafe { function tryFfi(string[] calldata commandInput) external returns (FfiResult memory result); /// Returns the time since unix epoch in milliseconds. - function unixTime() external returns (uint256 milliseconds); + function unixTime() external view returns (uint256 milliseconds); /// Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. /// `path` is relative to the project root. @@ -796,46 +850,6 @@ interface VmSafe { /// `path` is relative to the project root. function writeLine(string calldata path, string calldata data) external; - /// Returns the most recent broadcast for the given contract on `chainId` matching `txType`. - /// - /// For example: - /// - /// The most recent deployment can be fetched by passing `txType` as `CREATE` or `CREATE2`. - /// - /// The most recent call can be fetched by passing `txType` as `CALL`. - function getBroadcast(string calldata contractName, uint64 chainId, BroadcastTxType txType) - external - returns (BroadcastTxSummary memory); - - /// Returns all broadcasts for the given contract on `chainId` with the specified `txType`. - /// - /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. - function getBroadcasts(string calldata contractName, uint64 chainId, BroadcastTxType txType) - external - returns (BroadcastTxSummary[] memory); - - /// Returns all broadcasts for the given contract on `chainId`. - /// - /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. - function getBroadcasts(string calldata contractName, uint64 chainId) - external - returns (BroadcastTxSummary[] memory); - - /// Returns the most recent deployment for the current `chainId`. - function getDeployment(string calldata contractName) external returns (address deployedAddress); - - /// Returns the most recent deployment for the given contract on `chainId` - function getDeployment(string calldata contractName, uint64 chainId) external returns (address deployedAddress); - - /// Returns all deployments for the given contract on `chainId` - /// - /// Sorted in descending order of deployment time i.e descending order of BroadcastTxSummary.blockNumber. - /// - /// The most recent deployment is the first element, and the oldest is the last. - function getDeployments(string calldata contractName, uint64 chainId) - external - returns (address[] memory deployedAddresses); - // ======== JSON ======== /// Checks if `key` exists in a JSON object. @@ -1022,6 +1036,9 @@ interface VmSafe { // ======== Scripting ======== + /// Designate the next call as an EIP-7702 transaction + function attachDelegation(SignedDelegation calldata signedDelegation) external; + /// Takes a signed transaction and broadcasts it to the network. function broadcastRawTransaction(bytes calldata data) external; @@ -1041,7 +1058,17 @@ interface VmSafe { function broadcast(uint256 privateKey) external; /// Returns addresses of available unlocked wallets in the script environment. - function getScriptWallets() external returns (address[] memory wallets); + function getWallets() external returns (address[] memory wallets); + + /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction + function signAndAttachDelegation(address implementation, uint256 privateKey) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization for delegation + function signDelegation(address implementation, uint256 privateKey) + external + returns (SignedDelegation memory signedDelegation); /// Has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain. /// Broadcasting address is determined by checking the following in order: @@ -1061,11 +1088,11 @@ interface VmSafe { /// Stops collecting onchain transactions. function stopBroadcast() external; - /// Returns addresses of available unlocked wallets in the script environment. - function getWallets() external returns (address[] memory wallets); - // ======== String ======== + /// Returns true if `search` is found in `subject`, false otherwise. + function contains(string calldata subject, string calldata search) external returns (bool result); + /// Returns the index of the first occurrence of a `key` in an `input` string. /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `key` is not found. /// Returns 0 in case of an empty `key`. @@ -1861,6 +1888,14 @@ interface Vm is VmSafe { function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) external; + /// Reverts a call to an address with specified revert data. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCallRevert(address callee, bytes4 data, bytes calldata revertData) external; + + /// Reverts a call to an address with a specific `msg.value`, with specified revert data. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCallRevert(address callee, uint256 msgValue, bytes4 data, bytes calldata revertData) external; + /// Mocks a call to an address, returning specified data. /// Calldata can either be strict or a partial match, e.g. if you only /// pass a Solidity selector to the expected calldata, then the entire Solidity @@ -1871,6 +1906,18 @@ interface Vm is VmSafe { /// Calldata match takes precedence over `msg.value` in case of ambiguity. function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; + /// Mocks a call to an address, returning specified data. + /// Calldata can either be strict or a partial match, e.g. if you only + /// pass a Solidity selector to the expected calldata, then the entire Solidity + /// function will be mocked. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCall(address callee, bytes4 data, bytes calldata returnData) external; + + /// Mocks a call to an address with a specific `msg.value`, returning specified data. + /// Calldata match takes precedence over `msg.value` in case of ambiguity. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCall(address callee, uint256 msgValue, bytes4 data, bytes calldata returnData) external; + /// Mocks multiple calls to an address, returning specified data for each call. function mockCalls(address callee, bytes calldata data, bytes[] calldata returnData) external; @@ -1891,6 +1938,12 @@ interface Vm is VmSafe { /// Sets the *next* call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. function prank(address msgSender, address txOrigin) external; + /// Sets the *next* delegate call's `msg.sender` to be the input address. + function prank(address msgSender, bool delegateCall) external; + + /// Sets the *next* delegate call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. + function prank(address msgSender, address txOrigin, bool delegateCall) external; + /// Sets `block.prevrandao`. /// Not available on EVM versions before Paris. Use `difficulty` instead. /// If used on unsupported EVM versions it will revert. @@ -1980,6 +2033,12 @@ interface Vm is VmSafe { /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. function startPrank(address msgSender, address txOrigin) external; + /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called. + function startPrank(address msgSender, bool delegateCall) external; + + /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. + function startPrank(address msgSender, address txOrigin, bool delegateCall) external; + /// Start a snapshot capture of the current gas usage by name. /// The group name is derived from the contract name. function startSnapshotGas(string calldata name) external; diff --git a/lib/forge-std/test/StdChains.t.sol b/lib/forge-std/test/StdChains.t.sol index 48130da..7d96666 100644 --- a/lib/forge-std/test/StdChains.t.sol +++ b/lib/forge-std/test/StdChains.t.sol @@ -105,9 +105,8 @@ contract StdChainsTest is Test { StdChainsMock stdChainsMock = new StdChainsMock(); stdChainsMock.exposed_setChain("needs_undefined_env_var", ChainData("", 123456789, "")); - vm.expectRevert( - "Failed to resolve env var `UNDEFINED_RPC_URL_PLACEHOLDER` in `${UNDEFINED_RPC_URL_PLACEHOLDER}`: environment variable not found" - ); + // Forge environment variable error. + vm.expectRevert(); stdChainsMock.exposed_getChain("needs_undefined_env_var"); } diff --git a/lib/forge-std/test/Vm.t.sol b/lib/forge-std/test/Vm.t.sol index 8b6113c..f1c37bd 100644 --- a/lib/forge-std/test/Vm.t.sol +++ b/lib/forge-std/test/Vm.t.sol @@ -9,10 +9,10 @@ import {Vm, VmSafe} from "../src/Vm.sol"; // added to or removed from Vm or VmSafe. contract VmTest is Test { function test_VmInterfaceId() public pure { - assertEq(type(Vm).interfaceId, bytes4(0x329891d9), "Vm"); + assertEq(type(Vm).interfaceId, bytes4(0x21af9696), "Vm"); } function test_VmSafeInterfaceId() public pure { - assertEq(type(VmSafe).interfaceId, bytes4(0x590bc2b4), "VmSafe"); + assertEq(type(VmSafe).interfaceId, bytes4(0x92fe99ad), "VmSafe"); } }