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
20 changes: 20 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## Description
Summarize what this PR does and why in a single, clear sentence.
A reader should understand the purpose and scope of the change just from this line.

## Context
Explain the motivation or problem this PR addresses.
Include links to any relevant documentation, tickets, or discussions.

Provide background that helps reviewers understand *why* the change is needed.
Highlight any important design decisions, dependencies, or related components.

## Out of Scope
Specify what is *not* covered in this PR.
This helps reviewers focus on the intended scope and prevents scope creep.

## Testing Instructions
Provide clear, step-by-step instructions for verifying this change locally.
Assume the reviewer has no prior context about your setup.

This section reinforces the scope of the PR by outlining what should be tested and what the expected outcomes are.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Template Addition

Good addition of a PR template to standardize pull request descriptions. The template includes all essential sections:

  • Description (what & why)
  • Context (background & motivation)
  • Out of Scope (prevents scope creep)
  • Testing Instructions (verification steps)

Verification Status:
✅ Template structure matches the source from cowprotocol/token-lz
✅ Content is well-organized and clear
✅ Encourages thorough PR descriptions

This will help maintain consistent PR quality across the repository.

2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ jobs:

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: v1.4.3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Foundry Version Pinning

Good practice pinning the Foundry version to v1.4.3. This ensures:

  • Reproducible builds: CI will use the same version consistently
  • Compatibility: Matches the optimizer config change in foundry.toml
  • Stability: Prevents unexpected breaks from new Foundry releases

Note: Remember to periodically update this version to benefit from bug fixes and new features. Consider adding a comment in the file noting why this specific version was chosen.


- name: Show Forge version
run: |
Expand Down
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
src = "src"
out = "out"
libs = ["lib"]
optimize = true
optimizer = true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configuration Update

Good catch updating optimize to optimizer. This is the correct configuration key for newer Foundry versions.

Verification Recommendation:
Consider verifying the optimizer is actually enabled by checking the compiled contract bytecode size or running:

forge build --sizes

This ensures the optimizer is working as expected after the configuration change.


# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
2 changes: 1 addition & 1 deletion src/CowEvcWrapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {IEVC} from "evc/EthereumVaultConnector.sol";
import {IGPv2Authentication} from "./vendor/interfaces/IGPv2Authentication.sol";

import {GPv2Signing, IERC20, GPv2Trade} from "cow/mixins/GPv2Signing.sol";
import {GPv2Wrapper,GPv2Interaction} from "cow/GPv2Wrapper.sol";
import {GPv2Wrapper, GPv2Interaction} from "cow/GPv2Wrapper.sol";

/// @title CowEvcWrapper
/// @notice A wrapper around the EVC that allows for settlement operations
Expand Down
22 changes: 4 additions & 18 deletions src/vendor/interfaces/IERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ interface IERC20 {
*
* Emits a {Transfer} event.
*/
function transfer(
address recipient,
uint256 amount
) external returns (bool);
function transfer(address recipient, uint256 amount) external returns (bool);

/**
* @dev Returns the remaining number of tokens that `spender` will be
Expand All @@ -56,10 +53,7 @@ interface IERC20 {
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(
address owner,
address spender
) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);

/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
Expand All @@ -86,11 +80,7 @@ interface IERC20 {
*
* Emits a {Transfer} event.
*/
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
Expand All @@ -104,9 +94,5 @@ interface IERC20 {
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
20 changes: 8 additions & 12 deletions src/vendor/interfaces/IEthereumVaultConnector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,10 @@ interface IEVC {
/// balance of the EVC contract will be forwarded.
/// @param data The encoded data which is called on the target contract.
/// @return result The result of the call.
function call(
address targetContract,
address onBehalfOfAccount,
uint256 value,
bytes calldata data
) external payable returns (bytes memory result);
function call(address targetContract, address onBehalfOfAccount, uint256 value, bytes calldata data)
external
payable
returns (bytes memory result);

/// @notice For a given account, calls into one of the enabled collateral vaults from the currently enabled
/// controller vault as per data encoded.
Expand All @@ -345,12 +343,10 @@ interface IEVC {
/// balance of the EVC contract will be forwarded.
/// @param data The encoded data which is called on the target collateral.
/// @return result The result of the call.
function controlCollateral(
address targetCollateral,
address onBehalfOfAccount,
uint256 value,
bytes calldata data
) external payable returns (bytes memory result);
function controlCollateral(address targetCollateral, address onBehalfOfAccount, uint256 value, bytes calldata data)
external
payable
returns (bytes memory result);

/// @notice Executes multiple calls into the target contracts while checks deferred as per batch items provided.
/// @dev This function defers the account and vault status checks (it's a checks-deferrable call). If the outermost
Expand Down
112 changes: 63 additions & 49 deletions src/vendor/interfaces/IGPv2Settlement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,81 @@ pragma solidity ^0.8;
pragma experimental ABIEncoderV2;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: this file is actually removed in subsequent PRs, so dont dig too deep in this


interface IGPv2Settlement {
receive() external payable;
function authenticator() external view returns (address);
function domainSeparator() external view returns (bytes32);
function filledAmount(bytes memory) external view returns (uint256);
function freeFilledAmountStorage(bytes[] memory orderUids) external;
function freePreSignatureStorage(bytes[] memory orderUids) external;
function getStorageAt(uint256 offset, uint256 length) external view returns (bytes memory);
function invalidateOrder(bytes memory orderUid) external;
function preSignature(bytes memory) external view returns (uint256);
function setPreSignature(bytes memory orderUid, bool signed) external;
function settle(
address[] memory tokens,
uint256[] memory clearingPrices,
GPv2Trade.Data[] memory trades,
GPv2Interaction.Data[][3] memory interactions
) external;
function simulateDelegatecall(address targetContract, bytes memory calldataPayload)
external
returns (bytes memory response);
function simulateDelegatecallInternal(address targetContract, bytes memory calldataPayload)
external
returns (bytes memory response);
function swap(IVault.BatchSwapStep[] memory swaps, address[] memory tokens, GPv2Trade.Data memory trade) external;
function vault() external view returns (address);
function vaultRelayer() external view returns (address);



receive () external payable;
function authenticator( ) external view returns (address ) ;
function domainSeparator( ) external view returns (bytes32 ) ;
function filledAmount( bytes memory ) external view returns (uint256 ) ;
function freeFilledAmountStorage( bytes[] memory orderUids ) external ;
function freePreSignatureStorage( bytes[] memory orderUids ) external ;
function getStorageAt( uint256 offset,uint256 length ) external view returns (bytes memory ) ;
function invalidateOrder( bytes memory orderUid ) external ;
function preSignature( bytes memory ) external view returns (uint256 ) ;
function setPreSignature( bytes memory orderUid,bool signed ) external ;
function settle( address[] memory tokens,uint256[] memory clearingPrices,GPv2Trade.Data[] memory trades,GPv2Interaction.Data[][3] memory interactions ) external ;
function simulateDelegatecall( address targetContract,bytes memory calldataPayload ) external returns (bytes memory response) ;
function simulateDelegatecallInternal( address targetContract,bytes memory calldataPayload ) external returns (bytes memory response) ;
function swap( IVault.BatchSwapStep[] memory swaps,address[] memory tokens,GPv2Trade.Data memory trade ) external ;
function vault( ) external view returns (address ) ;
function vaultRelayer( ) external view returns (address ) ;
event Interaction( address indexed target,uint256 value,bytes4 selector ) ;
event OrderInvalidated( address indexed owner,bytes orderUid ) ;
event PreSignature( address indexed owner,bytes orderUid,bool signed ) ;
event Settlement( address indexed solver ) ;
event Trade( address indexed owner,address sellToken,address buyToken,uint256 sellAmount,uint256 buyAmount,uint256 feeAmount,bytes orderUid ) ;
event Interaction(address indexed target, uint256 value, bytes4 selector);
event OrderInvalidated(address indexed owner, bytes orderUid);
event PreSignature(address indexed owner, bytes orderUid, bool signed);
event Settlement(address indexed solver);
event Trade(
address indexed owner,
address sellToken,
address buyToken,
uint256 sellAmount,
uint256 buyAmount,
uint256 feeAmount,
bytes orderUid
);
}

interface GPv2Trade {
struct Data {
uint256 sellTokenIndex;
uint256 buyTokenIndex;
address receiver;
uint256 sellAmount;
uint256 buyAmount;
uint32 validTo;
bytes32 appData;
uint256 feeAmount;
uint256 flags;
uint256 executedAmount;
bytes signature;
}
struct Data {
uint256 sellTokenIndex;
uint256 buyTokenIndex;
address receiver;
uint256 sellAmount;
uint256 buyAmount;
uint32 validTo;
bytes32 appData;
uint256 feeAmount;
uint256 flags;
uint256 executedAmount;
bytes signature;
}
}

interface GPv2Interaction {
struct Data {
address target;
uint256 value;
bytes callData;
}
struct Data {
address target;
uint256 value;
bytes callData;
}
}

interface IVault {
struct BatchSwapStep {
bytes32 poolId;
uint256 assetInIndex;
uint256 assetOutIndex;
uint256 amount;
bytes userData;
}
struct BatchSwapStep {
bytes32 poolId;
uint256 assetInIndex;
uint256 assetOutIndex;
uint256 amount;
bytes userData;
}
}


// THIS FILE WAS AUTOGENERATED FROM THE FOLLOWING ABI JSON:
/*
[{"type":"constructor","inputs":[{"name":"authenticator_","type":"address","internalType":"contract GPv2Authentication"},{"name":"vault_","type":"address","internalType":"contract IVault"}],"stateMutability":"nonpayable"},{"type":"receive","stateMutability":"payable"},{"type":"function","name":"authenticator","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract GPv2Authentication"}],"stateMutability":"view"},{"type":"function","name":"domainSeparator","inputs":[],"outputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"stateMutability":"view"},{"type":"function","name":"filledAmount","inputs":[{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"freeFilledAmountStorage","inputs":[{"name":"orderUids","type":"bytes[]","internalType":"bytes[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"freePreSignatureStorage","inputs":[{"name":"orderUids","type":"bytes[]","internalType":"bytes[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"getStorageAt","inputs":[{"name":"offset","type":"uint256","internalType":"uint256"},{"name":"length","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bytes","internalType":"bytes"}],"stateMutability":"view"},{"type":"function","name":"invalidateOrder","inputs":[{"name":"orderUid","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"preSignature","inputs":[{"name":"","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"setPreSignature","inputs":[{"name":"orderUid","type":"bytes","internalType":"bytes"},{"name":"signed","type":"bool","internalType":"bool"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"settle","inputs":[{"name":"tokens","type":"address[]","internalType":"contract IERC20[]"},{"name":"clearingPrices","type":"uint256[]","internalType":"uint256[]"},{"name":"trades","type":"tuple[]","internalType":"struct GPv2Trade.Data[]","components":[{"name":"sellTokenIndex","type":"uint256","internalType":"uint256"},{"name":"buyTokenIndex","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"},{"name":"sellAmount","type":"uint256","internalType":"uint256"},{"name":"buyAmount","type":"uint256","internalType":"uint256"},{"name":"validTo","type":"uint32","internalType":"uint32"},{"name":"appData","type":"bytes32","internalType":"bytes32"},{"name":"feeAmount","type":"uint256","internalType":"uint256"},{"name":"flags","type":"uint256","internalType":"uint256"},{"name":"executedAmount","type":"uint256","internalType":"uint256"},{"name":"signature","type":"bytes","internalType":"bytes"}]},{"name":"interactions","type":"tuple[][3]","internalType":"struct GPv2Interaction.Data[][3]","components":[{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"callData","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"simulateDelegatecall","inputs":[{"name":"targetContract","type":"address","internalType":"address"},{"name":"calldataPayload","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"response","type":"bytes","internalType":"bytes"}],"stateMutability":"nonpayable"},{"type":"function","name":"simulateDelegatecallInternal","inputs":[{"name":"targetContract","type":"address","internalType":"address"},{"name":"calldataPayload","type":"bytes","internalType":"bytes"}],"outputs":[{"name":"response","type":"bytes","internalType":"bytes"}],"stateMutability":"nonpayable"},{"type":"function","name":"swap","inputs":[{"name":"swaps","type":"tuple[]","internalType":"struct IVault.BatchSwapStep[]","components":[{"name":"poolId","type":"bytes32","internalType":"bytes32"},{"name":"assetInIndex","type":"uint256","internalType":"uint256"},{"name":"assetOutIndex","type":"uint256","internalType":"uint256"},{"name":"amount","type":"uint256","internalType":"uint256"},{"name":"userData","type":"bytes","internalType":"bytes"}]},{"name":"tokens","type":"address[]","internalType":"contract IERC20[]"},{"name":"trade","type":"tuple","internalType":"struct GPv2Trade.Data","components":[{"name":"sellTokenIndex","type":"uint256","internalType":"uint256"},{"name":"buyTokenIndex","type":"uint256","internalType":"uint256"},{"name":"receiver","type":"address","internalType":"address"},{"name":"sellAmount","type":"uint256","internalType":"uint256"},{"name":"buyAmount","type":"uint256","internalType":"uint256"},{"name":"validTo","type":"uint32","internalType":"uint32"},{"name":"appData","type":"bytes32","internalType":"bytes32"},{"name":"feeAmount","type":"uint256","internalType":"uint256"},{"name":"flags","type":"uint256","internalType":"uint256"},{"name":"executedAmount","type":"uint256","internalType":"uint256"},{"name":"signature","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"vault","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract IVault"}],"stateMutability":"view"},{"type":"function","name":"vaultRelayer","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract GPv2VaultRelayer"}],"stateMutability":"view"},{"type":"event","name":"Interaction","inputs":[{"name":"target","type":"address","indexed":true,"internalType":"address"},{"name":"value","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"selector","type":"bytes4","indexed":false,"internalType":"bytes4"}],"anonymous":false},{"type":"event","name":"OrderInvalidated","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"orderUid","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"PreSignature","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"orderUid","type":"bytes","indexed":false,"internalType":"bytes"},{"name":"signed","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"Settlement","inputs":[{"name":"solver","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"event","name":"Trade","inputs":[{"name":"owner","type":"address","indexed":true,"internalType":"address"},{"name":"sellToken","type":"address","indexed":false,"internalType":"contract IERC20"},{"name":"buyToken","type":"address","indexed":false,"internalType":"contract IERC20"},{"name":"sellAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"buyAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"feeAmount","type":"uint256","indexed":false,"internalType":"uint256"},{"name":"orderUid","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false}]
Expand Down
Loading