Skip to content
Open
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
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ optimizer = true
optimizer_runs = 1000000
evm_version = "cancun"

deny_warnings = true
deny = "notes"

fs_permissions = [
{ access = "read", path = "./balancer"},
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@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",
"@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 @@ -65,7 +65,7 @@
"eslint-plugin-prettier": "^4.2.1",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.7.2",
"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
Loading