Skip to content
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
344 changes: 172 additions & 172 deletions .gas-snapshot

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ jobs:
# `fork` needs an archive-node RPC and is not run here. The fuzz seed is
# pinned so a failure is reproducible from the log alone.
run: forge test -vvv --no-match-test "fork" --fuzz-seed 672679878

6 changes: 3 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
branch = v1.5.3
branch = v1.11.0
[submodule "lib/cowprotocol"]
path = lib/cowprotocol
url = https://github.com/cowprotocol/contracts
branch = main
[submodule "lib/safe"]
path = lib/safe
url = https://github.com/cowdao-grants/extensible-fallback-handler
branch = main
url = https://github.com/safe-global/safe-smart-account
branch = v1.5.0
[submodule "lib/solady"]
path = lib/solady
url = https://github.com/vectorized/solady
17 changes: 11 additions & 6 deletions docs/discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -639,12 +639,17 @@ recomputing the root.
- `leafEncoding: "v1"` pins the full tree construction, byte-exact against
`_auth`: `leaf = keccak256(abi.encode(ConditionalOrderParams))`; the tree is
built bottom-up over the ascending-sorted leaf array; each internal node is
`keccak256(sorted-pair(a, b))`; an
odd trailing node at any level is promoted unchanged to the next level.
Sorted-pair hashing alone does not determine tree shape — implementations
MUST follow this construction (note: OpenZeppelin's `StandardMerkleTree`
double-hashes leaves and yields different roots; it is NOT this encoding).
Reference test vectors are published alongside the contracts.
`keccak256(sorted-pair(a, b))`; an odd trailing node at any level is promoted
unchanged to the next level. Sorted-pair hashing alone does not determine
tree shape, so implementations MUST follow this construction. Neither
OpenZeppelin's `StandardMerkleTree` (it double-hashes leaves) nor Solady's
`MerkleTreeLib` (it builds a complete `2n-1` node tree, diverging wherever
the odd-promotion rule fires, such as at 5, 7 or 9 leaves) produces this
shape. The mismatch is silent under verification: `MerkleProofLib.verify` is
sorted-pair and therefore shape-agnostic, so a non-conforming tree still
verifies against its own root, and the divergence surfaces only when a
consumer recomputes `root` from `leaves`. Reference test vectors are
published alongside the contracts.
- `leaves` MUST be sorted ascending by leaf hash and deduplicated; consumers
MUST reject on the first out-of-order or duplicate leaf.
- Producers MUST serialize with RFC 8785; content addresses and digests commit
Expand Down
8 changes: 4 additions & 4 deletions foundry.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
},
"lib/forge-std": {
"branch": {
"name": "v1.5.3",
"rev": "73a504d2cf6f37b7ce285b479f4c681f76e95f1b"
"name": "v1.11.0",
"rev": "8e40513d678f392f398620b3ef2b418648b33e89"
}
},
"lib/safe": {
"branch": {
"name": "main",
"rev": "11273c1f08eda18ed8ff49ec1d4abec5e451ff21"
"name": "v1.5.0",
"rev": "dc437e8fba8b4805d76bcbd1c668c9fd3d1e83be"
}
},
"lib/solady": {
Expand Down
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ solc_version = "0.8.30"
evm_version = "cancun"
optimizer = true
optimizer_runs = 20000
via_ir = true

# Descriptor documents are read by test/ComposableCow.descriptorDoc.t.sol
fs_permissions = [{ access = "read", path = "./descriptors" }]
Expand Down
2 changes: 1 addition & 1 deletion lib/forge-std
Submodule forge-std updated 61 files
+1 −0 .gitattributes
+1 −0 .github/CODEOWNERS
+6 −0 .github/dependabot.yml
+114 −64 .github/workflows/ci.yml
+36 −0 .github/workflows/sync.yml
+0 −3 .gitmodules
+193 −0 CONTRIBUTING.md
+21 −5 README.md
+12 −0 RELEASE_CHECKLIST.md
+11 −5 foundry.toml
+0 −1 lib/ds-test
+2 −2 package.json
+646 −0 scripts/vm.py
+25 −10 src/Base.sol
+60 −0 src/Config.sol
+477 −0 src/LibVariable.sol
+5 −3 src/Script.sol
+590 −202 src/StdAssertions.sol
+85 −31 src/StdChains.sol
+221 −21 src/StdCheats.sol
+612 −0 src/StdConfig.sol
+30 −0 src/StdConstants.sol
+34 −4 src/StdInvariant.sol
+129 −25 src/StdJson.sol
+245 −99 src/StdStorage.sol
+2 −2 src/StdStyle.sol
+283 −0 src/StdToml.sol
+55 −36 src/StdUtils.sol
+8 −6 src/Test.sol
+2,428 −353 src/Vm.sol
+635 −608 src/console.sol
+1 −1,543 src/console2.sol
+1 −1 src/interfaces/IERC1155.sol
+3 −3 src/interfaces/IERC4626.sol
+72 −0 src/interfaces/IERC6909.sol
+1 −1 src/interfaces/IERC721.sol
+150 −0 src/interfaces/IERC7540.sol
+241 −0 src/interfaces/IERC7575.sol
+13,937 −0 src/safeconsole.sol
+44 −0 test/CommonBase.t.sol
+352 −0 test/Config.t.sol
+434 −0 test/LibVariable.t.sol
+40 −853 test/StdAssertions.t.sol
+134 −67 test/StdChains.t.sol
+277 −49 test/StdCheats.t.sol
+38 −0 test/StdConstants.t.sol
+15 −13 test/StdError.t.sol
+49 −0 test/StdJson.t.sol
+31 −26 test/StdMath.t.sol
+251 −46 test/StdStorage.t.sol
+5 −5 test/StdStyle.t.sol
+49 −0 test/StdToml.t.sol
+81 −36 test/StdUtils.t.sol
+18 −0 test/Vm.t.sol
+1 −1 test/compilation/CompilationScript.sol
+1 −1 test/compilation/CompilationScriptBase.sol
+1 −1 test/compilation/CompilationTest.sol
+1 −1 test/compilation/CompilationTestBase.sol
+81 −0 test/fixtures/config.toml
+8 −0 test/fixtures/test.json
+6 −0 test/fixtures/test.toml
2 changes: 1 addition & 1 deletion lib/safe
Submodule safe updated from 11273c to dc437e
2 changes: 1 addition & 1 deletion script/deploy_AnvilStack.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {GPv2Authentication} from "cowprotocol/contracts/interfaces/GPv2Authentic

// Safe contracts
import {Safe} from "safe/Safe.sol";
import {Enum} from "safe/common/Enum.sol";
import {Enum} from "safe/libraries/Enum.sol";
import {SafeProxyFactory, SafeProxy} from "safe/proxies/SafeProxyFactory.sol";
import {CompatibilityFallbackHandler} from "safe/handler/CompatibilityFallbackHandler.sol";
import {MultiSend} from "safe/libraries/MultiSend.sol";
Expand Down
2 changes: 1 addition & 1 deletion script/deploy_ProdStack.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity >=0.8.0 <0.9.0;
import {Script} from "forge-std/Script.sol";

// ExtensibleFallbackHandler
import {ExtensibleFallbackHandler} from "../lib/safe/contracts/handler/ExtensibleFallbackHandler.sol";
import {ExtensibleFallbackHandler} from "safe/handler/ExtensibleFallbackHandler.sol";

// ComposableCow
import {ComposableCow} from "../src/ComposableCow.sol";
Expand Down
2 changes: 1 addition & 1 deletion script/submit_SingleOrder.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {IERC20} from "cowprotocol/contracts/interfaces/IERC20.sol";

// Safe contracts
import {Safe} from "safe/Safe.sol";
import {Enum} from "safe/common/Enum.sol";
import {Enum} from "safe/libraries/Enum.sol";
import {SafeProxyFactory} from "safe/proxies/SafeProxyFactory.sol";
import {CompatibilityFallbackHandler} from "safe/handler/CompatibilityFallbackHandler.sol";
import {MultiSend} from "safe/libraries/MultiSend.sol";
Expand Down
13 changes: 3 additions & 10 deletions src/ComposableCow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,8 @@
pragma solidity >=0.8.0 <0.9.0;

import {MerkleProofLib} from "solady/utils/MerkleProofLib.sol";
import {
ExtensibleFallbackHandler,
ERC1271,
ISignatureVerifierMuxer,
ISafeSignatureVerifier,
Safe
} from "safe/handler/ExtensibleFallbackHandler.sol";

import {IERC165, ERC1271, ISignatureVerifierMuxer, ISafeSignatureVerifier, Safe} from "./vendor/Safe.sol";

import {IConditionalOrder, IConditionalOrderGenerator, GPv2Order} from "./interfaces/IConditionalOrder.sol";
import {ISwapGuard} from "./interfaces/ISwapGuard.sol";
Expand Down Expand Up @@ -557,9 +552,7 @@ contract ComposableCow is ISafeSignatureVerifier {
GPv2Order.Data memory order
) internal view returns (bytes memory signature) {
// Get the signature for the order
try ExtensibleFallbackHandler(owner).supportsInterface(type(ISignatureVerifierMuxer).interfaceId) returns (
bool supported
) {
try IERC165(owner).supportsInterface(type(ISignatureVerifierMuxer).interfaceId) returns (bool supported) {
if (!supported) {
revert InvalidFallbackHandler();
}
Expand Down
2 changes: 1 addition & 1 deletion src/ERC1271Forwarder.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

import {ERC1271, Safe} from "safe/handler/extensible/SignatureVerifierMuxer.sol";
import {ERC1271, Safe} from "./vendor/Safe.sol";
import {GPv2Order} from "cowprotocol/contracts/libraries/GPv2Order.sol";

import {ComposableCow} from "./ComposableCow.sol";
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IConditionalOrder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity >=0.8.0 <0.9.0;

import {GPv2Order} from "cowprotocol/contracts/libraries/GPv2Order.sol";
import {IERC165} from "safe/interfaces/IERC165.sol";
import {IERC165} from "../vendor/Safe.sol";

/**
* @dev Canonical reason for `PollNeedsOffchainInput`: the handler cannot
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/ISwapGuard.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

import {IERC165} from "safe/interfaces/IERC165.sol";
import {IERC165} from "../vendor/Safe.sol";

import {IConditionalOrder, GPv2Order} from "./IConditionalOrder.sol";

Expand Down
55 changes: 55 additions & 0 deletions src/vendor/Safe.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.0 <0.9.0;

/**
* @dev The Safe surface this registry actually uses, vendored from
* `safe-contracts` rather than depended upon.
*
* The dependency was a compilation liability: `Safe.sol` uses inline
* assembly that is not annotated memory-safe, so the IR pipeline cannot
* allocate its stack and `via_ir` fails on the whole project. Nothing here
* needs the implementation. `Safe` is only ever a typed address, and the
* handler is only ever asked whether it supports an interface.
*
* Declarations match `safe-contracts` exactly, so a contract written
* against either compiles against this.
*/

/// @dev Standard ERC-165.
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

/// @dev ERC-1271, as `safe-contracts` declares it.
interface ERC1271 {
function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4 magicValue);
}

/**
* @dev A Safe, as far as this registry is concerned. Only its address is used:
* `isValidSafeSignature` takes one as a typed address and `_auth` reads
* the registry's own storage, so no Safe behaviour is invoked.
*/
interface Safe {}

/**
* @title Safe Signature Verifier Interface
* @notice Standard for external contracts verifying signatures for a Safe.
*/
interface ISafeSignatureVerifier {
function isValidSafeSignature(
Safe safe,
address sender,
bytes32 _hash,
bytes32 domainSeparator,
bytes32 typeHash,
bytes calldata encodeData,
bytes calldata payload
) external view returns (bytes4 magic);
}

interface ISignatureVerifierMuxer {
function domainVerifiers(Safe safe, bytes32 domainSeparator) external view returns (ISafeSignatureVerifier);

function setDomainVerifier(bytes32 domainSeparator, ISafeSignatureVerifier verifier) external;
}
4 changes: 3 additions & 1 deletion test/ComposableCow.base.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

import {Safe, IERC165, Enum} from "safe/Safe.sol";
import {Safe} from "safe/Safe.sol";
import {Enum} from "safe/libraries/Enum.sol";
import {IERC165} from "safe/interfaces/IERC165.sol";

// Testing Libraries
import {Base} from "./Base.t.sol";
Expand Down
11 changes: 1 addition & 10 deletions test/ComposableCow.descriptorDoc.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@ import "./ComposableCow.base.t.sol";
import "../src/types/TradeAboveThreshold.sol";
import {TWAPOrder} from "../src/types/twap/libraries/TWAPOrder.sol";

/**
* @dev `parseJsonKeys` is supported by the `forge` binary but absent from the
* vendored `forge-std` interface, so it is declared here rather than
* bumping the submodule for one cheatcode.
*/
interface VmJson {
function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory);
}

/**
* @dev Checks the generated descriptor documents against the contracts they
* describe. Solidity rather than a JS toolchain: the facts worth
Expand Down Expand Up @@ -45,7 +36,7 @@ contract ComposableCowDescriptorDocTest is BaseComposableCowTest {
}

function _errorKeys(string memory doc) private pure returns (string[] memory) {
return VmJson(address(vm)).parseJsonKeys(doc, "$.errors");
return vm.parseJsonKeys(doc, "$.errors");
}

function _hex4(bytes4 sel) private pure returns (string memory) {
Expand Down
9 changes: 5 additions & 4 deletions test/ComposableCow.t.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

import {Safe as CowSafe} from "../src/vendor/Safe.sol";
import {ERC1271} from "safe/handler/extensible/SignatureVerifierMuxer.sol";
import {ISafeSignaturePayload} from "../src/ComposableCow.sol";

Expand Down Expand Up @@ -262,7 +263,7 @@ contract ComposableCowTest is BaseComposableCowTest {
// should revert as the order hash mismatches
vm.expectRevert(abi.encodeWithSelector(IConditionalOrder.OrderNotValid.selector, InvalidHash.selector));
composableCow.isValidSafeSignature(
Safe(payable(address(alice.addr))),
CowSafe(payable(address(alice.addr))),
address(0),
GPv2Order.hash(order1, domainSeparator),
domainSeparator,
Expand Down Expand Up @@ -300,7 +301,7 @@ contract ComposableCowTest is BaseComposableCowTest {
// should revert as the proof is invalid
vm.expectRevert(ComposableCow.ProofNotAuthed.selector);
composableCow.isValidSafeSignature(
Safe(payable(owner)),
CowSafe(payable(owner)),
address(0), // sender isn't used
keccak256("some GPv2Order hash"),
keccak256("some domain separator"),
Expand Down Expand Up @@ -328,7 +329,7 @@ contract ComposableCowTest is BaseComposableCowTest {
// should revert as the order has not been created
vm.expectRevert(ComposableCow.SingleOrderNotAuthed.selector);
composableCow.isValidSafeSignature(
Safe(payable(owner)),
CowSafe(payable(owner)),
address(0), // sender isn't used
keccak256("some gpv2order hash"),
keccak256("some domain separator"),
Expand Down Expand Up @@ -359,7 +360,7 @@ contract ComposableCowTest is BaseComposableCowTest {
bytes memory cd = abi.encodeCall(
composableCow.isValidSafeSignature,
(
Safe(payable(address(owner))),
CowSafe(payable(address(owner))),
address(0), // sender isn't used
keccak256(abi.encode(order)),
domainSeparator,
Expand Down
5 changes: 3 additions & 2 deletions test/helpers/Safe.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
pragma solidity >=0.8.0 <0.9.0;

import {Safe} from "safe/Safe.sol";
import {Enum} from "safe/common/Enum.sol";
import {Enum} from "safe/libraries/Enum.sol";
import {SafeProxyFactory} from "safe/proxies/SafeProxyFactory.sol";
import {CompatibilityFallbackHandler} from "safe/handler/CompatibilityFallbackHandler.sol";
import {MultiSend} from "safe/libraries/MultiSend.sol";
import {SignMessageLib} from "safe/libraries/SignMessageLib.sol";
import {ExtensibleFallbackHandler, FallbackHandler, MarshalLib} from "safe/handler/ExtensibleFallbackHandler.sol";
import {ExtensibleFallbackHandler, FallbackHandler} from "safe/handler/ExtensibleFallbackHandler.sol";
import {MarshalLib} from "safe/handler/extensible/MarshalLib.sol";

import {SafeLib} from "../libraries/SafeLib.t.sol";
import {TestAccount, TestAccountLib} from "../libraries/TestAccountLib.t.sol";
Expand Down
2 changes: 1 addition & 1 deletion test/libraries/SafeLib.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

import {Enum} from "safe/common/Enum.sol";
import {Enum} from "safe/libraries/Enum.sol";
import {Safe} from "safe/Safe.sol";
import {SafeProxy} from "safe/proxies/SafeProxy.sol";
import {SafeProxyFactory} from "safe/proxies/SafeProxyFactory.sol";
Expand Down
Loading