Skip to content

Commit

Permalink
feat: adding deployment script with faucet erc20s (#114)
Browse files Browse the repository at this point in the history
* feat: adding deployment script with faucet erc20s

* fix: missing files

* feat: update appData to a valid one

* fix: natspec in IFaucet

* fix: final tweaks

* refactor: deployment script

* chore: testnet deployment (updated registry)

* fix: rm solhint 1-contract-per-file rule in script dir

* fix: update bDao address

* fix: gas snapshots

* fix: refresh snapshots

* fix: extra line

* chore: testnet redeployment

* chore: add grafiti to factory

* chore: deployment addresses

* chore: rm grafiti from factory

* refactor: reorganize deployment and scripting architecture

* fix: linter warnings

* fix: deprecate mainnet and testnet id constants

* fix: contract comments

* feat: adding explicit revert on unknown chains

* feat: adding BCoWHelper to deployment script and registry
  • Loading branch information
wei3erHase authored Jul 24, 2024
1 parent 5920cd1 commit c250754
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 58 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,11 @@ yarn test # run the tests
- The weight represents the intended distribution of value between the tokens in the pool
- Modify the pool's swap fee by calling `IBPool.setSwapFee(fee)`
- Finalize the pool by calling `IBPool.finalize()`

# Deployments
Ethereum Mainnet:
- BCoWFactory: (0x21Cd97D70f8475DF3d62917880aF9f41D9a9dCeF)[https://etherscan.io/address/0x21Cd97D70f8475DF3d62917880aF9f41D9a9dCeF#code]

Ethereum Sepolia:
- BCoWFactory: (0xe8587525430fFC9193831e1113a672f3133C1B8A)[https://sepolia.etherscan.io/address/0xe8587525430fFC9193831e1113a672f3133C1B8A#code]
- BCoWPool: (0xFe1ce255D68B3Bff95E71DDef1c8fc55459aaCd7)[https://sepolia.etherscan.io/address/0xFe1ce255D68B3Bff95E71DDef1c8fc55459aaCd7#code]
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,17 @@
"build": "forge build",
"build:optimized": "FOUNDRY_PROFILE=optimized forge build",
"coverage": "forge coverage --match-path 'test/unit/**'",
"deploy:bcowfactory:mainnet": "bash -c 'source .env && forge script DeployBCoWFactory -vvvvv --rpc-url $MAINNET_RPC --broadcast --chain mainnet --private-key $MAINNET_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:bcowfactory:testnet": "bash -c 'source .env && forge script DeployBCoWFactory -vvvvv --rpc-url $SEPOLIA_RPC --broadcast --chain sepolia --private-key $SEPOLIA_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:bfactory:mainnet": "bash -c 'source .env && forge script DeployBFactory -vvvvv --rpc-url $MAINNET_RPC --broadcast --chain mainnet --private-key $MAINNET_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:bfactory:testnet": "bash -c 'source .env && forge script DeployBFactory -vvvvv --rpc-url $SEPOLIA_RPC --broadcast --chain sepolia --private-key $SEPOLIA_DEPLOYER_PK --verify --etherscan-api-key $ETHERSCAN_API_KEY'",
"deploy:bcowfactory:mainnet": "forge script DeployBCoWFactory -vvvvv --rpc-url $MAINNET_RPC --broadcast --chain mainnet --private-key $MAINNET_DEPLOYER_PK --verify",
"deploy:bcowfactory:testnet": "forge script DeployBCoWFactory -vvvvv --rpc-url $SEPOLIA_RPC --broadcast --chain sepolia --private-key $SEPOLIA_DEPLOYER_PK --verify",
"deploy:bfactory:mainnet": "forge script DeployBFactory -vvvvv --rpc-url $MAINNET_RPC --broadcast --chain mainnet --private-key $MAINNET_DEPLOYER_PK --verify",
"deploy:bfactory:testnet": "forge script DeployBFactory -vvvvv --rpc-url $SEPOLIA_RPC --broadcast --chain sepolia --private-key $SEPOLIA_DEPLOYER_PK --verify",
"lint:bulloak": "find test/unit -name '*.tree' | xargs bulloak check",
"lint:check": "solhint 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol' && forge fmt --check",
"lint:fix": "solhint --fix 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol' && sort-package-json && forge fmt",
"lint:natspec": "npx @defi-wonderland/natspec-smells --config natspec-smells.config.js",
"prepare": "husky install",
"script:mainnet": "forge script MainnetScript -vvvvv --rpc-url $MAINNET_RPC --broadcast --chain mainnet --private-key $MAINNET_DEPLOYER_PK --verify",
"script:testnet": "forge script TestnetScript -vvvvv --rpc-url $SEPOLIA_RPC --broadcast --chain sepolia --private-key $SEPOLIA_DEPLOYER_PK --verify",
"smock": "smock-foundry --contracts src/contracts",
"test": "yarn test:integration && yarn test:unit",
"test:integration": "forge test --ffi --match-path 'test/integration/**' -vvv --isolate",
Expand Down
6 changes: 6 additions & 0 deletions script/.solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"rules": {
"one-contract-per-file": "off",
"custom-errors": "off"
}
}
43 changes: 43 additions & 0 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {BCoWFactory} from 'contracts/BCoWFactory.sol';
import {BCoWHelper} from 'contracts/BCoWHelper.sol';
import {BFactory} from 'contracts/BFactory.sol';
import {IBFactory} from 'interfaces/IBFactory.sol';

import {Script} from 'forge-std/Script.sol';
import {Params} from 'script/Params.s.sol';

/// @notice This base script is shared across `yarn script:{b|bcow}factory:{mainnet|testnet}`
abstract contract DeployBaseFactory is Script, Params {
constructor() Params(block.chainid) {}

function run() public {
vm.startBroadcast();
IBFactory bFactory = _deployFactory();
bFactory.setBDao(_bFactoryDeploymentParams.bDao);
vm.stopBroadcast();
}

function _deployFactory() internal virtual returns (IBFactory);
}

/// @notice This script will be executed by `yarn script:bfactory:{mainnet|testnet}`
contract DeployBFactory is DeployBaseFactory {
function _deployFactory() internal override returns (IBFactory bFactory) {
bFactory = new BFactory();
}
}

/// @notice This script will be executed by `yarn script:bcowfactory:{mainnet|testnet}`
contract DeployBCoWFactory is DeployBaseFactory {
function _deployFactory() internal override returns (IBFactory bFactory) {
bFactory = new BCoWFactory({
solutionSettler: _bCoWFactoryDeploymentParams.settlement,
appData: _bCoWFactoryDeploymentParams.appData
});

new BCoWHelper(address(bFactory));
}
}
17 changes: 0 additions & 17 deletions script/DeployBCoWFactory.s.sol

This file was deleted.

17 changes: 0 additions & 17 deletions script/DeployBFactory.s.sol

This file was deleted.

48 changes: 28 additions & 20 deletions script/Params.s.sol
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

contract Params {
/// @notice Deployment parameters
abstract contract Params {
struct BFactoryDeploymentParams {
address bDao;
}

struct BCoWFactoryDeploymentParams {
address bDao;
address settlement;
bytes32 appData;
}

/// @notice Settlement address
address internal constant _GPV2_SETTLEMENT = 0x9008D19f58AAbD9eD0D60971565AA8510560ab41;

/// @notice AppData identifier
bytes32 internal constant _APP_DATA = bytes32('appData');

/// @notice BFactory deployment parameters for each chain
mapping(uint256 _chainId => BFactoryDeploymentParams _params) internal _bFactoryDeploymentParams;

/// @notice BCoWFactory deployment parameters for each chain
mapping(uint256 _chainId => BCoWFactoryDeploymentParams _params) internal _bCoWFactoryDeploymentParams;

constructor() {
// Mainnet
_bFactoryDeploymentParams[1] = BFactoryDeploymentParams(address(this));
_bCoWFactoryDeploymentParams[1] = BCoWFactoryDeploymentParams(address(this), _GPV2_SETTLEMENT, _APP_DATA);

// Sepolia
_bFactoryDeploymentParams[11_155_111] = BFactoryDeploymentParams(address(this));
_bCoWFactoryDeploymentParams[11_155_111] = BCoWFactoryDeploymentParams(address(this), _GPV2_SETTLEMENT, _APP_DATA);
/// @notice Balancer DAO address (has controller permission to collect fees from BFactory pools)
address internal constant _B_DAO = 0xce88686553686DA562CE7Cea497CE749DA109f9F;

/**
* @notice AppData identifier
* @dev Value obtained from https://explorer.cow.fi/appdata?tab=encode
* - appCode: "CoW AMM Balancer"
* - metadata:hooks:version: 0.1.0
* - version: 1.1.0
*/
bytes32 internal constant _APP_DATA = 0x362e5182440b52aa8fffe70a251550fbbcbca424740fe5a14f59bf0c1b06fe1d;

/// @notice BFactory deployment parameters
BFactoryDeploymentParams internal _bFactoryDeploymentParams;

/// @notice BCoWFactory deployment parameters
BCoWFactoryDeploymentParams internal _bCoWFactoryDeploymentParams;

constructor(uint256 chainId) {
if (chainId == 1 || chainId == 11_155_111) {
// Ethereum Mainnet & Ethereum Sepolia [Testnet]
_bFactoryDeploymentParams = BFactoryDeploymentParams({bDao: _B_DAO});
_bCoWFactoryDeploymentParams = BCoWFactoryDeploymentParams({settlement: _GPV2_SETTLEMENT, appData: _APP_DATA});
} else {
revert('Params: unknown chain ID');
}
}
}
36 changes: 36 additions & 0 deletions script/Registry.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {BCoWFactory} from 'contracts/BCoWFactory.sol';
import {BCoWHelper} from 'contracts/BCoWHelper.sol';
import {BFactory} from 'contracts/BFactory.sol';

import {Params} from 'script/Params.s.sol';

/// @notice Registry of deployed contracts
abstract contract Registry is Params {
/// @notice Balancer Pool Factory
BFactory public bFactory;
/// @notice Balancer CoW Pool Factory
BCoWFactory public bCoWFactory;
/// @notice Balancer CoW Helper
BCoWHelper public bCoWHelper;

constructor(uint256 chainId) Params(chainId) {
// TODO: redeploy
if (chainId == 1) {
// Ethereum Mainnet
bFactory = BFactory(0xaD0447be7BDC80cf2e6DA20B13599E5dc859b667);
bCoWFactory = BCoWFactory(0x21Cd97D70f8475DF3d62917880aF9f41D9a9dCeF);
bCoWHelper = BCoWHelper(0xE50481D88f147B8b4aaCdf9a1B7b7bA44F87823f);
} else if (chainId == 11_155_111) {
// Ethereum Sepolia [Testnet]
bFactory = BFactory(0x2bfA24B26B85DD812b2C69E3B1cb4C85C886C8E2);
bCoWFactory = BCoWFactory(0xe8587525430fFC9193831e1113a672f3133C1B8A);
bCoWHelper = BCoWHelper(0x0fd365F9Ed185512536E7dbfc7a8DaE43cD3CA09);
} else {
// TODO: add Gnosis chain
revert('Registry: unknown chain ID');
}
}
}
59 changes: 59 additions & 0 deletions script/Script.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;

import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import {IBPool} from 'contracts/BPool.sol';
import {IFaucet} from 'interfaces/IFaucet.sol';

import {Script} from 'forge-std/Script.sol';
import {Registry} from 'script/Registry.s.sol';

/// @notice This base script is shared across `yarn script:{mainnet|testnet}`
abstract contract BaseScript is Registry, Script {
constructor() Registry(block.chainid) {}
}

/// @notice This script will be executed by `yarn script:mainnet`
contract MainnetScript is BaseScript {
function run() public {
assert(block.chainid == 1);
vm.startBroadcast();

// script logic here

vm.stopBroadcast();
}
}

/// @notice This script will be executed by `yarn script:testnet`
contract TestnetScript is BaseScript {
/// @notice ERC20 and Faucet addresses
address internal constant _SEPOLIA_FAUCET = 0x26bfAecAe4D5fa93eE1737ce1Ce7D53F2a0E9b2d;
address internal constant _SEPOLIA_BAL_TOKEN = 0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75;
address internal constant _SEPOLIA_DAI_TOKEN = 0xB77EB1A70A96fDAAeB31DB1b42F2b8b5846b2613;
address internal constant _SEPOLIA_USDC_TOKEN = 0x80D6d3946ed8A1Da4E226aa21CCdDc32bd127d1A;

/// @dev The following is an example of a script that deploys a Balancer CoW pool
function run() public {
assert(block.chainid == 11_155_111);
vm.startBroadcast();

// NOTE: dripping can be called by anyone but only once a day (per address)
IFaucet(_SEPOLIA_FAUCET).drip(_SEPOLIA_BAL_TOKEN);
IFaucet(_SEPOLIA_FAUCET).drip(_SEPOLIA_DAI_TOKEN);
IFaucet(_SEPOLIA_FAUCET).drip(_SEPOLIA_USDC_TOKEN);

IBPool bPool = bCoWFactory.newBPool();

IERC20(_SEPOLIA_BAL_TOKEN).approve(address(bPool), type(uint256).max);
IERC20(_SEPOLIA_DAI_TOKEN).approve(address(bPool), type(uint256).max);
IERC20(_SEPOLIA_USDC_TOKEN).approve(address(bPool), type(uint256).max);

bPool.bind(_SEPOLIA_BAL_TOKEN, 40e18, 1e18);
bPool.bind(_SEPOLIA_DAI_TOKEN, 10e18, 1e18);
bPool.bind(_SEPOLIA_USDC_TOKEN, 10e6, 1e18);

bPool.finalize();
vm.stopBroadcast();
}
}
14 changes: 14 additions & 0 deletions src/interfaces/IFaucet.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.25;

/**
* @title IFaucet
* @notice External interface of Sepolia's Faucet contract.
*/
interface IFaucet {
/**
* @notice Drips an amount of tokens to the caller.
* @param token The address of the token to drip.
*/
function drip(address token) external;
}

0 comments on commit c250754

Please sign in to comment.