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
268 changes: 137 additions & 131 deletions .gas-snapshot

Large diffs are not rendered by default.

9 changes: 3 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
branch = v1.5.3
[submodule "lib/murky"]
path = lib/murky
url = https://github.com/dmfxyz/murky
[submodule "lib/@openzeppelin"]
path = lib/@openzeppelin
url = https://github.com/openzeppelin/openzeppelin-contracts
[submodule "lib/cowprotocol"]
path = lib/cowprotocol
url = https://github.com/cowprotocol/contracts
Expand All @@ -16,3 +10,6 @@
path = lib/safe
url = https://github.com/cowdao-grants/extensible-fallback-handler
branch = main
[submodule "lib/solady"]
path = lib/solady
url = https://github.com/vectorized/solady
2 changes: 1 addition & 1 deletion docs/discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ 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))` (OpenZeppelin `MerkleProof` convention); an
`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`
Expand Down
14 changes: 7 additions & 7 deletions foundry.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
{
"lib/@openzeppelin": {
"rev": "fd81a96f01cc42ef1c9a5399364968d0e07e9e90"
},
"lib/cowprotocol": {
"branch": {
"name": "main",
Expand All @@ -14,13 +11,16 @@
"rev": "73a504d2cf6f37b7ce285b479f4c681f76e95f1b"
}
},
"lib/murky": {
"rev": "1d9566b908b9702c45d354a1caabe8ef5a69938d"
},
"lib/safe": {
"branch": {
"name": "main",
"rev": "11273c1f08eda18ed8ff49ec1d4abec5e451ff21"
}
},
"lib/solady": {
"tag": {
"name": "v0.1.26",
"rev": "acd959aa4bd04720d640bf4e6a5c71037510cc4b"
}
}
}
}
1 change: 0 additions & 1 deletion lib/@openzeppelin
Submodule @openzeppelin deleted from fd81a9
1 change: 0 additions & 1 deletion lib/murky
Submodule murky deleted from 1d9566
1 change: 1 addition & 0 deletions lib/solady
Submodule solady added at acd959
6 changes: 2 additions & 4 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
@openzeppelin/=lib/@openzeppelin/
cowprotocol/=lib/cowprotocol/src/
ds-test/=lib/forge-std/lib/ds-test/src/
erc4626-tests/=lib/@openzeppelin/lib/erc4626-tests/
forge-std/=lib/forge-std/src/
murky/=lib/murky/src/
openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/
safe/=lib/safe/contracts/
solady/=lib/solady/src/
4 changes: 2 additions & 2 deletions src/ComposableCow.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 {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import {MerkleProofLib} from "solady/utils/MerkleProofLib.sol";
import {
ExtensibleFallbackHandler,
ERC1271,
Expand Down Expand Up @@ -521,7 +521,7 @@ contract ComposableCow is ISafeSignatureVerifier {
if (proof.length != 0) {
// The order is part of a merkle tree
bytes32 leaf = keccak256(bytes.concat(hash(params)));
require(MerkleProof.verify(proof, roots[owner], leaf), ProofNotAuthed());
require(MerkleProofLib.verify(proof, roots[owner], leaf), ProofNotAuthed());
} else {
// The order is a single order
ctx = hash(params);
Expand Down
4 changes: 2 additions & 2 deletions src/types/GoodAfterTime.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 {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {SafeCastLib} from "solady/utils/SafeCastLib.sol";

import {IExpectedOutCalculator} from "../vendored/Milkman.sol";
import {
Expand Down Expand Up @@ -50,7 +50,7 @@ contract GoodAfterTime is OrderDescriptor {
OrderDescriptor(descriptorUris, descriptorDigest_, descriptorKind)
{}

using SafeCast for uint256;
using SafeCastLib for uint256;

// --- types

Expand Down
4 changes: 2 additions & 2 deletions src/types/twap/TWAP.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 {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {SafeCastLib} from "solady/utils/SafeCastLib.sol";

import {ComposableCow} from "../../ComposableCow.sol";

Expand Down Expand Up @@ -37,7 +37,7 @@ error OrderNotInitialized();
* @dev Designed to be used with the CoW Protocol Conditional Order Framework.
*/
contract TWAP is OrderDescriptor {
using SafeCast for uint256;
using SafeCastLib for uint256;

ComposableCow public immutable composableCow;

Expand Down
4 changes: 2 additions & 2 deletions src/types/twap/libraries/TWAPOrder.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 {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {SafeCastLib} from "solady/utils/SafeCastLib.sol";
import {IERC20, GPv2Order} from "cowprotocol/contracts/libraries/GPv2Order.sol";

import {IConditionalOrder} from "../../../interfaces/IConditionalOrder.sol";
Expand Down Expand Up @@ -48,7 +48,7 @@ error InvalidSpan();
* @dev Structs, errors, and functions for time-weighted average orders.
*/
library TWAPOrder {
using SafeCast for uint256;
using SafeCastLib for uint256;

// --- structs

Expand Down
4 changes: 1 addition & 3 deletions test/ComposableCow.base.t.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0 <0.9.0;

import {Merkle} from "murky/Merkle.sol";

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

// Testing Libraries
Expand Down Expand Up @@ -30,7 +28,7 @@ import {IValueFactory} from "../src/interfaces/IValueFactory.sol";
import {ISwapGuard, ComposableCow, GPv2Order} from "../src/ComposableCow.sol";
import {PackageKind} from "../src/interfaces/PackageKind.sol";

contract BaseComposableCowTest is Base, Merkle {
contract BaseComposableCowTest is Base {
using ComposableCowLib for IConditionalOrder.ConditionalOrderParams;
using SafeLib for Safe;

Expand Down
10 changes: 6 additions & 4 deletions test/ComposableCow.proof.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 {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import {MerkleProofLib} from "solady/utils/MerkleProofLib.sol";

import {IConditionalOrder, ComposableCow, BaseComposableCowTest} from "./ComposableCow.base.t.sol";
import {ComposableCowLib} from "./libraries/ComposableCowLib.t.sol";
Expand Down Expand Up @@ -163,7 +163,7 @@ contract ComposableCowProofTest is BaseComposableCowTest {

/**
* @dev The payload standard's tree construction, implemented
* independently of the Murky test helper: ascending-sorted leaf
* independently of solady's `MerkleTreeLib`: ascending-sorted leaf
* hashes, bottom-up sorted-pair keccak, odd trailing node promoted
* unchanged. Mutates `hashes` in place.
*/
Expand Down Expand Up @@ -245,7 +245,7 @@ contract ComposableCowProofTest is BaseComposableCowTest {

/**
* @dev The normative construction (`leafEncoding: "v1"`) is verifiable by
* exactly the check `_auth` performs (OZ `MerkleProof.verify`), for
* exactly the check `_auth` performs (`MerkleProofLib.verify`), for
* every leaf across minimal, even, and odd tree sizes - including
* the odd-promotion levels
*/
Expand All @@ -272,7 +272,9 @@ contract ComposableCowProofTest is BaseComposableCowTest {
}
bytes32[] memory proof = _normativeProof(forProof, leaf);
// the exact check _auth performs
assertTrue(MerkleProof.verify(proof, root, leaf), "normative proof rejected by OZ verify");
assertTrue(
MerkleProofLib.verify(proof, root, leaf), "normative proof rejected by MerkleProofLib.verify"
);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/ComposableCow.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ contract ComposableCowTest is BaseComposableCowTest {
function test_setRoot_e2e() public {
IConditionalOrder.ConditionalOrderParams[] memory _leaves = getBundle(safe1, 50);
(bytes32 root, bytes32[] memory proof, IConditionalOrder.ConditionalOrderParams memory params) =
_leaves.getRootAndProof(0, leaves, getRoot, getProof);
_leaves.getRootAndProof(0, leaves);

// should fail to validate the proof as root is still set bytes32(0)
vm.expectRevert(ComposableCow.ProofNotAuthed.selector);
Expand Down Expand Up @@ -95,7 +95,7 @@ contract ComposableCowTest is BaseComposableCowTest {
function test_setRootWithContext_e2e() public {
IConditionalOrder.ConditionalOrderParams[] memory _leaves = getBundle(safe1, 50);
(bytes32 root, bytes32[] memory proof, IConditionalOrder.ConditionalOrderParams memory params) =
_leaves.getRootAndProof(0, leaves, getRoot, getProof);
_leaves.getRootAndProof(0, leaves);

// should fail to validate the proof as root is still set bytes32(0)
vm.expectRevert(ComposableCow.ProofNotAuthed.selector);
Expand Down
4 changes: 2 additions & 2 deletions test/ComposableCow.twap.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 {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {SafeCastLib} from "solady/utils/SafeCastLib.sol";
import {ERC1271} from "safe/handler/extensible/SignatureVerifierMuxer.sol";

import {IConditionalOrderGenerator} from "../src/interfaces/IConditionalOrder.sol";
Expand Down Expand Up @@ -487,7 +487,7 @@ contract ComposableCowTwapTest is BaseComposableCowTest {

// 2. Do the merkle tree dance
(bytes32 root, bytes32[] memory proof, IConditionalOrder.ConditionalOrderParams memory leaf) =
_leaves.getRootAndProof(0, leaves, getRoot, getProof);
_leaves.getRootAndProof(0, leaves);

// 3. Set the root
_setRoot(
Expand Down
22 changes: 18 additions & 4 deletions test/helpers/Tokens.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,34 @@
pragma solidity >=0.8.0 <0.9.0;

import {IERC20} from "cowprotocol/contracts/interfaces/IERC20.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {ERC20} from "solady/tokens/ERC20.sol";

/**
* @title Mock ERC20 token for testing.
* @author mfw78 <mfw78@nxm.rs>
*/
contract MockERC20 is ERC20 {
string private _name;
string private _symbol;

/**
* @dev Initializes a new mock ERC20 token. No tokens are minted, makes use instead
* of `vm.deal` in tests.
* @param name The name of the token.
* @param symbol The symbol of the token.
* @param name_ The name of the token.
* @param symbol_ The symbol of the token.
*/
constructor(string memory name, string memory symbol) ERC20(name, symbol) {}
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}

function name() public view override returns (string memory) {
return _name;
}

function symbol() public view override returns (string memory) {
return _symbol;
}
}

/**
Expand Down
20 changes: 9 additions & 11 deletions test/libraries/ComposableCowLib.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 {Merkle} from "murky/Merkle.sol";
import {MerkleTreeLib} from "solady/utils/MerkleTreeLib.sol";
import {IConditionalOrder} from "../../src/interfaces/IConditionalOrder.sol";

library ComposableCowLib {
Expand All @@ -27,18 +27,14 @@ library ComposableCowLib {
* @param leaves to be inserted into the tree
* @param n th leaf to generate the proof for
* @param m a mapping of hashes to leaves to be populated (storage)
* @param getRoot a function that returns the root of the tree given an array of hashes
* @param getProof a function that returns the proof for a leaf given an array of hashes and the index of the leaf
* @return the root of the tree
* @return a proof for the n'th leaf
* @return the n'th leaf
*/
function getRootAndProof(
IConditionalOrder.ConditionalOrderParams[] memory leaves,
uint256 n,
mapping(bytes32 => IConditionalOrder.ConditionalOrderParams) storage m,
function(bytes32[] memory) internal pure returns (bytes32) getRoot,
function(bytes32[] memory, uint256) internal pure returns (bytes32[] memory) getProof
mapping(bytes32 => IConditionalOrder.ConditionalOrderParams) storage m
) internal returns (bytes32, bytes32[] memory, IConditionalOrder.ConditionalOrderParams memory) {
// 1. Create a mapping of hashes to leaves
for (uint256 i = 0; i < leaves.length; i++) {
Expand All @@ -54,11 +50,13 @@ library ComposableCowLib {
// 3. Sort the hashes
bytes32[] memory sortedHashes = sort(hashes);

// 4. Create the Merkle root
bytes32 root = getRoot(sortedHashes);

// 5. Create the Merkle proof for the n'th leaf
bytes32[] memory proof = getProof(sortedHashes, n);
// 4. Build the tree, then take the root and the n'th leaf's proof.
// `MerkleTreeLib` pairs with `MerkleProofLib`, which is what
// `ComposableCow` verifies with, so construction and verification
// come from the same family.
bytes32[] memory tree = MerkleTreeLib.build(sortedHashes);
bytes32 root = MerkleTreeLib.root(tree);
bytes32[] memory proof = MerkleTreeLib.leafProof(tree, n);

// 6. Get the leaf that was used to create the proof
IConditionalOrder.ConditionalOrderParams memory leaf = m[sortedHashes[n]];
Expand Down
2 changes: 1 addition & 1 deletion test/vendored/GPv2TradeEncoder.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 {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol";
import {IERC20} from "cowprotocol/contracts/interfaces/IERC20.sol";

import {GPv2Order} from "cowprotocol/contracts/libraries/GPv2Order.sol";
import {GPv2Signing} from "cowprotocol/contracts/mixins/GPv2Signing.sol";
Expand Down
Loading