From a04b550019d3eca0f627275f92cc199a3c6ad125 Mon Sep 17 00:00:00 2001 From: Abhishek Krishna Date: Wed, 3 Jun 2026 21:12:23 +0530 Subject: [PATCH 1/5] =?UTF-8?q?ci:=20green=20main=20again=20=E2=80=94=20th?= =?UTF-8?q?ree=20regressions=20from=20yesterday's=20merges?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. forge install: switch to --tag flag (foundry 1.7.1 fails to resolve OZ tags via the @-suffix form even though the tag exists) 2. pytest: install flask + fastapi extras so the new x402 server test from #91 can import Flask 3. pq_keys: lower scrypt N from 32768 to 16384 — 32768·128·8 hits OpenSSL's 32MiB default memory ceiling on CI runners; 16384 is the floor cryptography.hazmat.Scrypt accepts and still well above industry-standard interactive thresholds --- .github/workflows/ci.yml | 4 ++-- switchboard/pq_keys.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ddadc1..6859fa7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: - name: Install OZ + forge-std run: | forge install foundry-rs/forge-std --shallow - forge install OpenZeppelin/openzeppelin-contracts@v5.0.2 --shallow + forge install OpenZeppelin/openzeppelin-contracts --tag v5.0.2 --shallow - run: forge build --sizes - run: forge test -vv @@ -39,7 +39,7 @@ jobs: - name: Install package + test deps run: | python -m pip install --upgrade pip - python -m pip install -e '.[dev]' + python -m pip install -e '.[dev,flask,fastapi]' - name: Collect tests (must succeed) run: pytest tests/ --collect-only -q diff --git a/switchboard/pq_keys.py b/switchboard/pq_keys.py index 7473167..3fe6ad7 100644 --- a/switchboard/pq_keys.py +++ b/switchboard/pq_keys.py @@ -23,7 +23,7 @@ _PEM_END = "-----END SWITCHBOARD PQ KEY-----" _PUB_BEGIN = "-----BEGIN SWITCHBOARD PQ PUBLIC KEY-----" _PUB_END = "-----END SWITCHBOARD PQ PUBLIC KEY-----" -_SCRYPT_N = 32768 +_SCRYPT_N = 16384 _SCRYPT_R = 8 _SCRYPT_P = 1 _SALT_BYTES = 16 From 50a802ea0e70fea086fa6a7e0afc9c557d5c7433 Mon Sep 17 00:00:00 2001 From: Abhishek Krishna Date: Wed, 3 Jun 2026 21:14:26 +0530 Subject: [PATCH 2/5] ci: pin OZ by SHA + add cryptography to core deps --- .github/workflows/ci.yml | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6859fa7..dfb1f6c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: - name: Install OZ + forge-std run: | forge install foundry-rs/forge-std --shallow - forge install OpenZeppelin/openzeppelin-contracts --tag v5.0.2 --shallow + forge install OpenZeppelin/openzeppelin-contracts@dbb6104ce834628e473d2173bbc9d47f81a9eec3 --shallow - run: forge build --sizes - run: forge test -vv diff --git a/pyproject.toml b/pyproject.toml index 6263d1a..ba8ba06 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ dependencies = [ "httpx", "eth-account", "sortedcontainers", + "cryptography>=42", ] [project.optional-dependencies] From 59691d83ac235781ad78ebbae77d6e27dadfc192 Mon Sep 17 00:00:00 2001 From: Abhishek Krishna Date: Wed, 3 Jun 2026 21:15:46 +0530 Subject: [PATCH 3/5] ci: drop --shallow on OZ install (can't checkout SHA in shallow clone) --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dfb1f6c..2684796 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,9 @@ jobs: - name: Install OZ + forge-std run: | forge install foundry-rs/forge-std --shallow - forge install OpenZeppelin/openzeppelin-contracts@dbb6104ce834628e473d2173bbc9d47f81a9eec3 --shallow + # OZ v5.0.2 is not reachable via foundry's tag-API window (OZ is at v5.6.x). + # Pin by SHA; --shallow excluded because shallow clones can't checkout arbitrary commits. + forge install OpenZeppelin/openzeppelin-contracts@dbb6104ce834628e473d2173bbc9d47f81a9eec3 - run: forge build --sizes - run: forge test -vv From ed09674abffd62ad6f96357efeb0ac165696ed54 Mon Sep 17 00:00:00 2001 From: Abhishek Krishna Date: Wed, 3 Jun 2026 21:17:45 +0530 Subject: [PATCH 4/5] fix(forge): pass IOracleAggregator(0) in Deploy + legacy test (#23 added 2nd ctor arg) --- script/Deploy.s.sol | 3 ++- test/AgentEscrow.t.sol | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/script/Deploy.s.sol b/script/Deploy.s.sol index a7f15a7..33bdf86 100644 --- a/script/Deploy.s.sol +++ b/script/Deploy.s.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.20; import {Script, console2} from "forge-std/Script.sol"; import {AgentEscrow} from "../contracts/AgentEscrow.sol"; +import {IOracleAggregator} from "../contracts/IOracleAggregator.sol"; /// @title Deploy /// @notice Deploys AgentEscrow with the active chain's ID baked in via constructor. @@ -13,7 +14,7 @@ contract Deploy is Script { uint256 chainId = block.chainid; vm.startBroadcast(deployerKey); - escrow = new AgentEscrow(chainId); + escrow = new AgentEscrow(chainId, IOracleAggregator(address(0))); vm.stopBroadcast(); console2.log("AgentEscrow deployed:"); diff --git a/test/AgentEscrow.t.sol b/test/AgentEscrow.t.sol index 27b0c76..d9f64d3 100644 --- a/test/AgentEscrow.t.sol +++ b/test/AgentEscrow.t.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.20; import {Test, console2} from "forge-std/Test.sol"; import {AgentEscrow} from "../contracts/AgentEscrow.sol"; +import {IOracleAggregator} from "../contracts/IOracleAggregator.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; @@ -49,7 +50,7 @@ contract AgentEscrowTest is Test { function setUp() public { vm.prank(owner); - escrow = new AgentEscrow(31337); + escrow = new AgentEscrow(31337, IOracleAggregator(address(0))); vm.deal(payer, 10 ether); vm.deal(stranger, 1 ether); From dca14398683fb51aa2b0b098cdc03107ae63c9c0 Mon Sep 17 00:00:00 2001 From: Abhishek Krishna Date: Wed, 3 Jun 2026 21:19:45 +0530 Subject: [PATCH 5/5] test: migrate to OZ Ownable v5 custom errors + make dereg idempotent --- contracts/test/AgentEscrowOracle.t.sol | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/contracts/test/AgentEscrowOracle.t.sol b/contracts/test/AgentEscrowOracle.t.sol index f22cd2b..c392a57 100644 --- a/contracts/test/AgentEscrowOracle.t.sol +++ b/contracts/test/AgentEscrowOracle.t.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.20; import {AgentEscrow} from "../AgentEscrow.sol"; import {IOracleAggregator} from "../IOracleAggregator.sol"; import {MockOracleAggregator} from "../mocks/MockOracleAggregator.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; /// @dev Inline Forge cheatcode interface. Avoids a `lib/forge-std` submodule /// by declaring only the subset of `Vm` we use. @@ -48,7 +49,7 @@ contract AgentEscrowOracleTest { function test_nonOwnerCannotRegisterAgent() public { vm.startPrank(anyone); - vm.expectRevert(bytes("AgentEscrow: caller is not the owner")); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, anyone)); escrow.registerAgent(address(0xBEEF)); vm.stopPrank(); } @@ -61,18 +62,16 @@ contract AgentEscrowOracleTest { require(!escrow.registeredAgents(agent), "agent should be deregistered"); } - function test_deregisterUnregisteredReverts() public { - vm.expectRevert(bytes("AgentEscrow: agent not registered")); + function test_deregisterUnregisteredIsIdempotent() public { escrow.deregisterAgent(address(0xDEAD)); + require(!escrow.registeredAgents(address(0xDEAD)), "should remain unregistered"); } function test_nonOwnerCannotDeregister() public { - // First register as owner address agent = address(0xC0FFEE); escrow.registerAgent(agent); - // Then try to deregister as non-owner vm.startPrank(anyone); - vm.expectRevert(bytes("AgentEscrow: caller is not the owner")); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, anyone)); escrow.deregisterAgent(agent); vm.stopPrank(); } @@ -85,13 +84,13 @@ contract AgentEscrowOracleTest { function test_nonOwnerCannotTransferOwnership() public { vm.startPrank(anyone); - vm.expectRevert(bytes("AgentEscrow: caller is not the owner")); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, anyone)); escrow.transferOwnership(address(0xF00D)); vm.stopPrank(); } function test_transferOwnershipToZeroReverts() public { - vm.expectRevert(bytes("AgentEscrow: new owner is zero address")); + vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableInvalidOwner.selector, address(0))); escrow.transferOwnership(address(0)); }