Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f176400
test: helper base for e2e tests (#215)
meetmangukiya Oct 7, 2024
884319e
chore: migrate E2E nonStandardErc20 tests to Foundry (#213)
meetmangukiya Oct 7, 2024
efc8caa
chore: migrate E2E internalBalances test to Foundry (#216)
meetmangukiya Oct 7, 2024
59c3410
chore: migrate E2E 0xTrade test to Foundry (#219)
meetmangukiya Oct 7, 2024
8d8f77d
chore: merkle.io for ETH RPC (#227)
mfw78 Oct 7, 2024
9225dff
chore: migrate E2E wineOilMarket tests to Foundry (#214)
meetmangukiya Oct 7, 2024
75bf332
chore: migrate E2E upgradeAuthenticator test to Foundry (#217)
meetmangukiya Oct 7, 2024
89f9189
chore: set fork block number (#228)
mfw78 Oct 7, 2024
3d8a350
chore: migrate E2E burnFees to Foundry (#221)
meetmangukiya Oct 8, 2024
51f4a5b
chore: update test CI/CD for FORK_URL env (#230)
mfw78 Oct 8, 2024
078c5a6
chore: migrate E2E buyEth tests to Foundry (#229)
meetmangukiya Oct 8, 2024
e974119
chore: migrate E2E offchainAllowances test to Foundry (#218)
meetmangukiya Oct 8, 2024
fbfd19f
chore: migrate E2E smartOrder test to Foundry (#220)
meetmangukiya Oct 8, 2024
672c1ba
chore: migrate E2E uniswapTrade test to Foundry (#222)
meetmangukiya Oct 8, 2024
d3e1c19
chore: migrate E2E contractOrdersWithGnosisSafe test to Foundry (#223)
meetmangukiya Oct 8, 2024
b6871bc
chore: migrate E2E deployment test to Foundry (#225)
meetmangukiya Oct 8, 2024
1cbd0de
chore: remove env (#231)
mfw78 Oct 9, 2024
92ae3b5
chore: migrate E2E balancerSwap test to Foundry (#224)
meetmangukiya Oct 9, 2024
521c551
chore: clean dead code (#232)
mfw78 Oct 9, 2024
92e387a
improvements for the e2e test update branch
kaze-cow Dec 28, 2025
0fdf4c3
forge fmt
kaze-cow Dec 28, 2025
824e88d
fix linter warnings
kaze-cow Dec 28, 2025
6ccd902
fix all the warnings
kaze-cow Dec 28, 2025
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
4 changes: 4 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,9 @@ jobs:
- name: Run Forge tests
if: matrix.profile != 'solc-0.7.6'
run: |
if [ "${{ matrix.profile }}" == "default" ]; then
echo "Setting FORK_URL for default profile"
export FORK_URL="${{ secrets.MAINNET_ARCHIVE_RPC }}"
fi
FOUNDRY_PROFILE=ci forge test -vvv
id: test
4 changes: 2 additions & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ optimizer = true
optimizer_runs = 1000000
evm_version = "cancun"

deny_warnings = true
deny = "notes"

fs_permissions = [
{ access = "read", path = "./balancer"},
{ access = "read", path = "./networks.json"},
{ access = "read", path = "./out"}
{ access = "read", path = "./out"},
]

[fmt]
Expand Down
12 changes: 2 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,10 @@
"ethers": "^5.4.0"
},
"devDependencies": {
"@0x/contract-artifacts-v2": "npm:@0x/contract-artifacts@^2.2.2",
"@gnosis.pm/safe-contracts": "^1.3.0",
"@nomicfoundation/hardhat-verify": "^2.0.1",
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-waffle": "^2.0.5",
"@openzeppelin/contracts": "=3.4.0-solc-0.7",
"@safe-global/api-kit": "^1.3.0",
"@safe-global/protocol-kit": "^1.2.0",
"@safe-global/safe-core-sdk-types": "^2.2.0",
"@slack/web-api": "^6.9.0",
"@openzeppelin/contracts": "=5.5.0",
"@tenderly/hardhat-tenderly": "~1.1.6",
"@types/chai": "^4.3.4",
"@types/chai-as-promised": "^7.1.5",
Expand All @@ -58,7 +52,6 @@
"@typescript-eslint/parser": "^5.58.0",
"@uniswap/v2-core": "^1.0.1",
"@uniswap/v2-periphery": "^1.1.0-beta.0",
"axios": "^1.3.5",
"canonical-weth": "^1.4.0",
"chai": "^4.3.7",
"chai-as-promised": "^7.1.1",
Expand All @@ -72,8 +65,7 @@
"eslint-plugin-prettier": "^4.2.1",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.7.2",
"globby": "^11.0.4",
"hardhat": "^2.13.1",
"hardhat": "^2.28.0",
"hardhat-deploy": "^0.11.26",
"hardhat-gas-reporter": "^1.0.9",
"prettier": "^2.8.7",
Expand Down
19 changes: 9 additions & 10 deletions script/TransferOwnership.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,25 +95,24 @@ contract TransferOwnership is NetworksJson {
}
}

return ScriptParams({
newOwner: newOwner,
resetManager: resetManager,
authenticatorProxy: ERC173(authenticatorProxy)
});
return
ScriptParams({
newOwner: newOwner, resetManager: resetManager, authenticatorProxy: ERC173(authenticatorProxy)
});
}

function checkIsProxy(address candidate) internal view {
if (address(candidate).code.length == 0) {
revert(string.concat("No code at target authenticator proxy ", vm.toString(address(candidate)), "."));
}

bool isERC173;
try ERC165(candidate).supportsInterface(type(ERC173).interfaceId) returns (bool isERC173_) {
isERC173 = isERC173_;
bool isErc173;
try ERC165(candidate).supportsInterface(type(ERC173).interfaceId) returns (bool isErc173_) {
isErc173 = isErc173_;
} catch {
isERC173 = false;
isErc173 = false;
}
if (!isERC173) {
if (!isErc173) {
revert(
string.concat(
"Not a valid proxy contract: target address ",
Expand Down
6 changes: 3 additions & 3 deletions script/interfaces/ERC173.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ interface ERC173 {

interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @param interfaceId The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
/// `interfaceId` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
1 change: 1 addition & 0 deletions script/lib/NetworksJson.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ contract NetworksJson is Script {
}

function addressByChainId(string memory contractName, uint256 chainId) public view returns (address) {
/// forge-lint: disable-next-line(unsafe-cheatcode)
string memory networksJson = vm.readFile(PATH);
return
vm.parseJsonAddress(networksJson, string.concat(".", contractName, ".", vm.toString(chainId), ".address"));
Expand Down
20 changes: 14 additions & 6 deletions src/contracts/GPv2AllowListAuthentication.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;

import "./interfaces/GPv2Authentication.sol";
import "./libraries/GPv2EIP1967.sol";
import "./mixins/Initializable.sol";
import "./mixins/StorageAccessible.sol";
import {GPv2Authentication} from "./interfaces/GPv2Authentication.sol";
import {GPv2EIP1967} from "./libraries/GPv2EIP1967.sol";
import {Initializable} from "./mixins/Initializable.sol";
import {StorageAccessible} from "./mixins/StorageAccessible.sol";

/// @title Gnosis Protocol v2 Access Control Contract
/// @author Gnosis Developers
Expand Down Expand Up @@ -47,7 +47,7 @@ contract GPv2AllowListAuthentication is
/// @dev Modifier that ensures a method can only be called by the contract
/// manager. Reverts if called by other addresses.
modifier onlyManager() {
require(manager == msg.sender, "GPv2: caller not manager");
_onlyManager();
_;
}

Expand All @@ -57,11 +57,19 @@ contract GPv2AllowListAuthentication is
/// This modifier assumes that the proxy uses an EIP-1967 compliant storage
/// slot for the admin.
modifier onlyManagerOrOwner() {
_onlyManagerOrOwner();
_;
}

function _onlyManager() internal view {
require(manager == msg.sender, "GPv2: caller not manager");
}

function _onlyManagerOrOwner() internal view {
require(
manager == msg.sender || GPv2EIP1967.getAdmin() == msg.sender,
"GPv2: not authorized"
);
_;
}

/// @dev Set the manager for this contract.
Expand Down
50 changes: 31 additions & 19 deletions src/contracts/GPv2Settlement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@
pragma solidity >=0.7.6 <0.9.0;
pragma abicoder v2;

import "./GPv2VaultRelayer.sol";
import "./interfaces/GPv2Authentication.sol";
import "./interfaces/IERC20.sol";
import "./interfaces/IVault.sol";
import "./libraries/GPv2Interaction.sol";
import "./libraries/GPv2Order.sol";
import "./libraries/GPv2Trade.sol";
import "./libraries/GPv2Transfer.sol";
import "./libraries/SafeCast.sol";
import "./libraries/SafeMath.sol";
import "./mixins/GPv2Signing.sol";
import "./mixins/ReentrancyGuard.sol";
import "./mixins/StorageAccessible.sol";
import {GPv2VaultRelayer} from "./GPv2VaultRelayer.sol";
import {GPv2Authentication} from "./interfaces/GPv2Authentication.sol";
import {IGPv2Settlement} from "./interfaces/IGPv2Settlement.sol";
import {IERC20} from "./interfaces/IERC20.sol";
import {IVault} from "./interfaces/IVault.sol";
import {GPv2Interaction} from "./libraries/GPv2Interaction.sol";
import {GPv2Order} from "./libraries/GPv2Order.sol";
import {GPv2Trade} from "./libraries/GPv2Trade.sol";
import {GPv2Transfer} from "./libraries/GPv2Transfer.sol";
import {SafeCast} from "./libraries/SafeCast.sol";
import {SafeMath} from "./libraries/SafeMath.sol";
import {GPv2Signing} from "./mixins/GPv2Signing.sol";
import {ReentrancyGuard} from "./mixins/ReentrancyGuard.sol";
import {StorageAccessible} from "./mixins/StorageAccessible.sol";

/// @title Gnosis Protocol v2 Settlement Contract
/// @author Gnosis Developers
contract GPv2Settlement is GPv2Signing, ReentrancyGuard, StorageAccessible {
contract GPv2Settlement is IGPv2Settlement, GPv2Signing, ReentrancyGuard, StorageAccessible {
using GPv2Order for bytes;
using GPv2Transfer for IVault;
using SafeCast for int256;
Expand All @@ -29,14 +30,17 @@ contract GPv2Settlement is GPv2Signing, ReentrancyGuard, StorageAccessible {
/// That is, only authorized solvers have the ability to invoke settlements.
/// Any valid authenticator implements an isSolver method called by the onlySolver
/// modifier below.
GPv2Authentication public immutable authenticator;
/// forge-lint: disable-next-line(screaming-snake-case-immutable)
GPv2Authentication public immutable override authenticator;

/// @dev The Balancer Vault the protocol used for managing user funds.
IVault public immutable vault;
/// forge-lint: disable-next-line(screaming-snake-case-immutable)
IVault public immutable override vault;

/// @dev The Balancer Vault relayer which can interact on behalf of users.
/// This contract is created during deployment
GPv2VaultRelayer public immutable vaultRelayer;
/// forge-lint: disable-next-line(screaming-snake-case-immutable)
GPv2VaultRelayer public immutable override vaultRelayer;

/// @dev Map each user order by UID to the amount that has been filled so
/// far. If this amount is larger than or equal to the amount traded in the
Expand Down Expand Up @@ -85,17 +89,25 @@ contract GPv2Settlement is GPv2Signing, ReentrancyGuard, StorageAccessible {
/// @dev This modifier is called by settle function to block any non-listed
/// senders from settling batches.
modifier onlySolver() {
require(authenticator.isSolver(msg.sender), "GPv2: not a solver");
_onlySolver();
_;
}

function _onlySolver() internal view {
require(authenticator.isSolver(msg.sender), "GPv2: not a solver");
}

/// @dev Modifier to ensure that an external function is only callable as a
/// settlement interaction.
modifier onlyInteraction() {
require(address(this) == msg.sender, "GPv2: not an interaction");
_onlyInteraction();
_;
}

function _onlyInteraction() internal view {
require(address(this) == msg.sender, "GPv2: not an interaction");
}

/// @dev Settle the specified orders at a clearing price. Note that it is
/// the responsibility of the caller to ensure that all GPv2 invariants are
/// upheld for the input settlement, otherwise this call will revert.
Expand Down
26 changes: 15 additions & 11 deletions src/contracts/GPv2VaultRelayer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
pragma solidity >=0.7.6 <0.9.0;
pragma abicoder v2;

import "./interfaces/IERC20.sol";
import "./interfaces/IVault.sol";
import "./libraries/GPv2Transfer.sol";
import {IERC20} from "./interfaces/IERC20.sol";
import {IVault} from "./interfaces/IVault.sol";
import {GPv2Transfer} from "./libraries/GPv2Transfer.sol";

/// @title Gnosis Protocol v2 Vault Relayer Contract
/// @author Gnosis Developers
Expand All @@ -13,23 +13,27 @@ contract GPv2VaultRelayer {

/// @dev The creator of the contract which has special permissions. This
/// value is set at creation time and cannot change.
address private immutable creator;
address private immutable CREATOR;

/// @dev The vault this relayer is for.
IVault private immutable vault;
IVault private immutable VAULT;

constructor(IVault vault_) {
creator = msg.sender;
vault = vault_;
CREATOR = msg.sender;
VAULT = vault_;
}

/// @dev Modifier that ensures that a function can only be called by the
/// creator of this contract.
modifier onlyCreator() {
require(msg.sender == creator, "GPv2: not creator");
_onlyCreator();
_;
}

function _onlyCreator() internal view {
require(msg.sender == CREATOR, "GPv2: not creator");
}

/// @dev Transfers all sell amounts for the executed trades from their
/// owners to the caller.
///
Expand All @@ -41,7 +45,7 @@ contract GPv2VaultRelayer {
function transferFromAccounts(
GPv2Transfer.Data[] calldata transfers
) external onlyCreator {
vault.transferFromAccounts(transfers, msg.sender);
VAULT.transferFromAccounts(transfers, msg.sender);
}

/// @dev Performs a Balancer batched swap on behalf of a user and sends a
Expand Down Expand Up @@ -72,14 +76,14 @@ contract GPv2VaultRelayer {
uint256 deadline,
GPv2Transfer.Data calldata feeTransfer
) external onlyCreator returns (int256[] memory tokenDeltas) {
tokenDeltas = vault.batchSwap(
tokenDeltas = VAULT.batchSwap(
kind,
swaps,
tokens,
funds,
limits,
deadline
);
vault.fastTransferFromAccount(feeTransfer, msg.sender);
VAULT.fastTransferFromAccount(feeTransfer, msg.sender);
}
}
2 changes: 1 addition & 1 deletion src/contracts/interfaces/IVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
pragma solidity >=0.7.6 <0.9.0;
pragma abicoder v2;

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

/**
* @dev Minimal interface for the Vault core contract only containing methods
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/libraries/GPv2Order.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;

import "../interfaces/IERC20.sol";
import {IERC20} from "../interfaces/IERC20.sol";

/// @title Gnosis Protocol v2 Order Library
/// @author Gnosis Developers
Expand Down
2 changes: 1 addition & 1 deletion src/contracts/libraries/GPv2SafeERC20.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;

import "../interfaces/IERC20.sol";
import {IERC20} from "../interfaces/IERC20.sol";

/// @title Gnosis Protocol v2 Safe ERC20 Transfer Library
/// @author Gnosis Developers
Expand Down
6 changes: 3 additions & 3 deletions src/contracts/libraries/GPv2Trade.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;

import "../interfaces/IERC20.sol";
import "../mixins/GPv2Signing.sol";
import "./GPv2Order.sol";
import {IERC20} from "../interfaces/IERC20.sol";
import {GPv2Signing} from "../mixins/GPv2Signing.sol";
import {GPv2Order} from "./GPv2Order.sol";

/// @title Gnosis Protocol v2 Trade Library.
/// @author Gnosis Developers
Expand Down
8 changes: 4 additions & 4 deletions src/contracts/libraries/GPv2Transfer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
pragma solidity >=0.7.6 <0.9.0;
pragma abicoder v2;

import "../interfaces/IERC20.sol";
import "../interfaces/IVault.sol";
import "./GPv2Order.sol";
import "./GPv2SafeERC20.sol";
import {IERC20} from "../interfaces/IERC20.sol";
import {IVault} from "../interfaces/IVault.sol";
import {GPv2Order} from "./GPv2Order.sol";
import {GPv2SafeERC20} from "./GPv2SafeERC20.sol";

/// @title Gnosis Protocol v2 Transfers
/// @author Gnosis Developers
Expand Down
4 changes: 4 additions & 0 deletions src/contracts/libraries/SafeCast.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ library SafeCast {
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: not positive");
// casting to 'uint256' is safe because we've checked value >= 0
// forge-lint: disable-next-line(unsafe-typecast)
return uint256(value);
}

Expand All @@ -50,6 +52,8 @@ library SafeCast {
value <= uint256(type(int256).max),
"SafeCast: int256 overflow"
);
// casting to 'int256' is safe because we've checked value <= int256.max
// forge-lint: disable-next-line(unsafe-typecast)
return int256(value);
}
}
Loading