Skip to content

Commit

Permalink
Fix linter & better organize foundry dependencies (#53)
Browse files Browse the repository at this point in the history
* Fix the linter CI and foundry dependencies for better DX
  • Loading branch information
MattPereira authored Jul 8, 2024
1 parent 89cdc6a commit ce353d4
Show file tree
Hide file tree
Showing 19 changed files with 819 additions and 2,370 deletions.
53 changes: 53 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Lint

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
ci:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest]
node: [lts/*]

steps:
- name: Checkout
uses: actions/checkout@master

- name: Setup node env
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
cache: yarn

- name: Install foundry-toolchain
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install dependencies
run: yarn install --immutable

# - name: Run foundry anvil fork
# run: yarn fork
# env:
# SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}

# - name: Deploy contracts to anvil fork
# run: yarn deploy:factory
# env:
# DEPLOYER_PRIVATE_KEY: ${{ secrets.DEPLOYER_PRIVATE_KEY }}
# SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}

- name: Run nextjs lint
run: yarn next:lint --max-warnings=0

- name: Check typings on nextjs
run: yarn next:check-types
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "packages/foundry/lib/forge-std"]
path = packages/foundry/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "packages/foundry/lib/permit2"]
path = packages/foundry/lib/permit2
url = https://github.com/uniswap/permit2
11 changes: 2 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,14 @@
"next:format": "yarn workspace @se-2/nextjs format",
"next:check-types": "yarn workspace @se-2/nextjs check-types",
"next:build": "yarn workspace @se-2/nextjs build",
"postinstall": "husky install",
"postinstall": "husky install && forge install --root packages/foundry",
"precommit": "lint-staged",
"vercel": "vercel",
"vercel:yolo": "vercel --build-env NEXT_PUBLIC_IGNORE_BUILD_ERROR=true"
},
"packageManager": "[email protected]",
"devDependencies": {
"forge-gas-snapshot": "https://github.com/ylv-io/forge-gas-snapshot",
"husky": "^8.0.1",
"lint-staged": "^13.0.3",
"next": "^14.0.4",
"permit2": "https://github.com/Uniswap/permit2.git#cc56ad0f3439c502c246fc5cfcc3db92bb8b7219",
"vercel": "^32.4.1"
},
"dependencies": {
"@balancer-labs/v3-monorepo": "https://github.com/balancer/balancer-v3-monorepo#head=scaffold-package-setup-deploy5"
"lint-staged": "^13.0.3"
}
}
1 change: 0 additions & 1 deletion packages/foundry/.env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
DEPLOYER_PRIVATE_KEY=
ETHERSCAN_API_KEY=
SEPOLIA_RPC_URL=
6 changes: 3 additions & 3 deletions packages/foundry/contracts/ConstantSumFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ import { ConstantSumPool } from "./ConstantSumPool.sol";
*/
contract ConstantSumFactory is BasePoolFactory {
/**
* @notice BasePoolFactory requires the pool contract's creationCode which will be used for CREATE3
* @dev The pool's creationCode is used to deploy pools via CREATE3
* @notice The pool creationCode cannot be changed after the factory has been deployed
* @param vault address of Balancer v3 Vault
* @param pauseWindowDuration for pools based on the factory deployment time
* @param vault The contract instance of the Vault
* @param pauseWindowDuration The period ( starting from deployment of this factory ) during which pools can be paused and unpaused
*/
constructor(
IVault vault,
Expand Down
1 change: 0 additions & 1 deletion packages/foundry/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ out = 'out'
libs = ['node_modules', 'lib']
test = 'test'
ffi = true
allow_paths = ['../../node_modules/']
solc_version = '0.8.24'
auto_detect_solc = false
evm_version = 'cancun'
Expand Down
1 change: 1 addition & 0 deletions packages/foundry/lib/permit2
Submodule permit2 added at cc56ad
2 changes: 2 additions & 0 deletions packages/foundry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/VerifyAll.s.sol --ffi --rpc-url ${1:-default_network}"
},
"dependencies": {
"@balancer-labs/v3-monorepo": "https://github.com/balancer/balancer-v3-monorepo#head=scaffold-package-setup-deploy5",
"dotenv": "~16.3.1",
"envfile": "~6.18.0",
"ethers": "~5.7.1",
Expand All @@ -27,6 +28,7 @@
"devDependencies": {
"@types/prettier": "2",
"@types/qrcode": "1",
"forge-gas-snapshot": "https://github.com/ylv-io/forge-gas-snapshot",
"prettier": "~2.8.8",
"prettier-plugin-solidity": "^1.3.1"
}
Expand Down
12 changes: 6 additions & 6 deletions packages/foundry/remappings.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@test/=../../node_modules/@balancer-labs/v3-monorepo/pkg/
@balancer-labs/v3-solidity-utils/=../../node_modules/@balancer-labs/v3-monorepo/pkg/solidity-utils/
@balancer-labs/v3-interfaces/=../../node_modules/@balancer-labs/v3-monorepo/pkg/interfaces/
@balancer-labs/v3-vault/=../../node_modules/@balancer-labs/v3-monorepo/pkg/vault/
permit2/=../../node_modules/permit2/
forge-gas-snapshot/=../../node_modules/forge-gas-snapshot/src/
@test/=node_modules/@balancer-labs/v3-monorepo/pkg/
@balancer-labs/v3-solidity-utils/=node_modules/@balancer-labs/v3-monorepo/pkg/solidity-utils/
@balancer-labs/v3-interfaces/=node_modules/@balancer-labs/v3-monorepo/pkg/interfaces/
@balancer-labs/v3-vault/=node_modules/@balancer-labs/v3-monorepo/pkg/vault/
permit2/=lib/permit2/
forge-gas-snapshot/=node_modules/forge-gas-snapshot/src/
17 changes: 5 additions & 12 deletions packages/foundry/script/01_DeployConstantSumFactory.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.24;
import { ScaffoldETHDeploy, console } from "./ScaffoldETHDeploy.s.sol";
import { ConstantSumFactory } from "../contracts/ConstantSumFactory.sol";
import { VeBALFeeDiscountHook } from "../contracts/VeBALFeeDiscountHook.sol";
import { HelperConfig } from "../utils/HelperConfig.sol";
import { HelperConfig } from "./HelperConfig.sol";
import { MockToken1 } from "../contracts/mocks/MockToken1.sol";
import { MockToken2 } from "../contracts/mocks/MockToken2.sol";
import { MockVeBAL } from "../contracts/mocks/MockVeBAL.sol";
Expand All @@ -28,27 +28,20 @@ contract DeployConstantSumFactory is HelperConfig, ScaffoldETHDeploy {

vm.startBroadcast(deployerPrivateKey);

/**
* @notice Deploys the factory contract
*/
// Deploy factory contract
ConstantSumFactory factory = new ConstantSumFactory(vault, pauseWindowDuration);
console.log("Deployed Factory Address: %s", address(factory));

/**
* @notice Deploys mock tokens used for pool initialization and hooks contract
* @dev Remove this if you plan to work with already deployed tokens
*/
// Deploy mock tokens
MockToken1 token1 = new MockToken1("Mock Token 1", "MT1", 1000e18);
MockToken2 token2 = new MockToken2("Mock Token 2", "MT2", 1000e18);
MockVeBAL veBAL = new MockVeBAL("Vote-escrow BAL", "veBAL", 1000e18);
console.log("Deployed MockToken1 Address: %s", address(token1));
console.log("Deployed MockToken2 Address: %s", address(token2));
console.log("Deployed Vote-escrow BAL Address: %s", address(veBAL));

/**
* @notice Deploys the hook contract
*/
VeBALFeeDiscountHook hook = new VeBALFeeDiscountHook(vault, address(factory), address(veBAL), address(router));
// Deploy hooks contract
new VeBALFeeDiscountHook(vault, address(factory), address(veBAL), address(router));

vm.stopBroadcast();

Expand Down
5 changes: 2 additions & 3 deletions packages/foundry/script/02_DeployConstantSumPool1.s.sol
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import { HelperFunctions } from "../utils/HelperFunctions.sol";
import { HelperConfig } from "./HelperConfig.sol";
import { ConstantSumFactory } from "../contracts/ConstantSumFactory.sol";
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { DevOpsTools } from "lib/foundry-devops/src/DevOpsTools.sol";
import { Script, console } from "forge-std/Script.sol";
import { RegistrationConfig, InitializationConfig } from "../utils/PoolTypes.sol";

/**
* @title Deploy Constant Sum Pool #1
* @notice This script deploys a new pool using the most recently deployed pool factory and mock tokens
* @dev Set the pool registration and initialization configurations in `HelperConfig.sol`
* @dev Run this script with `yarn deploy:pool1`
*/
contract DeployConstantSumPool1 is HelperFunctions, Script {
contract DeployConstantSumPool1 is HelperConfig, Script {
error InvalidPrivateKey(string);

function run() external virtual {
Expand Down
5 changes: 2 additions & 3 deletions packages/foundry/script/03_DeployConstantSumPool2.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ pragma solidity ^0.8.24;

import { LiquidityManagement, PoolRoleAccounts } from "@balancer-labs/v3-interfaces/contracts/vault/VaultTypes.sol";

import { HelperFunctions } from "../utils/HelperFunctions.sol";
import { HelperConfig } from "./HelperConfig.sol";
import { ConstantSumFactory } from "../contracts/ConstantSumFactory.sol";
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { DevOpsTools } from "lib/foundry-devops/src/DevOpsTools.sol";
import { Script, console } from "forge-std/Script.sol";
import { RegistrationConfig, InitializationConfig } from "../utils/PoolTypes.sol";

/**
* @title Deploy Constant Sum Pool #2
Expand All @@ -17,7 +16,7 @@ import { RegistrationConfig, InitializationConfig } from "../utils/PoolTypes.sol
* @notice Some config is set directly in this script including the pool hooks contract
* @dev Run this script with `yarn deploy:pool2`
*/
contract DeployConstantSumPool2 is HelperFunctions, Script {
contract DeployConstantSumPool2 is HelperConfig, Script {
error InvalidPrivateKey(string);

function run() external virtual {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import { IVault } from "@balancer-labs/v3-interfaces/contracts/vault/IVault.sol"
import { IRouter } from "@balancer-labs/v3-interfaces/contracts/vault/IRouter.sol";
import { IRateProvider } from "@balancer-labs/v3-interfaces/contracts/vault/IRateProvider.sol";
import { InputHelpers } from "@balancer-labs/v3-solidity-utils/contracts/helpers/InputHelpers.sol";
import { IPermit2 } from "permit2/src/interfaces/IPermit2.sol";

import { RegistrationConfig, InitializationConfig } from "./PoolTypes.sol";
import { IPermit2 } from "permit2/src/interfaces/IPermit2.sol";
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { DevOpsTools } from "lib/foundry-devops/src/DevOpsTools.sol";

Expand All @@ -29,6 +28,26 @@ contract HelperConfig {
// Canonical permit2 Sepolia address
IPermit2 internal permit2 = IPermit2(0x000000000022D473030F116dDEE9F6B43aC78BA3);

struct RegistrationConfig {
string name;
string symbol;
bytes32 salt;
TokenConfig[] tokenConfig;
uint256 swapFeePercentage;
bool protocolFeeExempt;
PoolRoleAccounts roleAccounts;
address poolHooksContract;
LiquidityManagement liquidityManagement;
}

struct InitializationConfig {
IERC20[] tokens;
uint256[] exactAmountsIn;
uint256 minBptAmountOut;
bool wethIsEth;
bytes userData;
}

/**
* @dev Set the pool factory configurations here
*/
Expand Down Expand Up @@ -121,6 +140,10 @@ contract HelperConfig {
});
}

///////////////////
// Helper Functions
//////////////////

/**
* Helper function to sort the tokenConfig array
*/
Expand All @@ -135,4 +158,48 @@ contract HelperConfig {
}
return tokenConfig;
}

/**
* @notice Approves the vault to spend tokens and then initializes the pool
*/
function initializePool(
address pool,
IERC20[] memory tokens,
uint256[] memory exactAmountsIn,
uint256 minBptAmountOut,
bool wethIsEth,
bytes memory userData
) internal {
// Approve Permit2 to spend account tokens
approveSpenderOnToken(address(permit2), tokens);
// Approve Router to spend account tokens using Permit2
approveSpenderOnPermit2(address(router), tokens);
// Initialize pool with the tokens that have been permitted
router.initialize(pool, tokens, exactAmountsIn, minBptAmountOut, wethIsEth, userData);
}

/**
* @notice Max approving to speed up UX on frontend
* @param tokens Array of tokens to approve
* @param spender Address of the spender
*/
function approveSpenderOnToken(address spender, IERC20[] memory tokens) internal {
uint256 maxAmount = type(uint256).max;
for (uint256 i = 0; i < tokens.length; ++i) {
tokens[i].approve(spender, maxAmount);
}
}

/**
* @notice Max approving to speed up UX on frontend
* @param tokens Array of tokens to approve
* @param spender Address of the spender
*/
function approveSpenderOnPermit2(address spender, IERC20[] memory tokens) internal {
uint160 maxAmount = type(uint160).max;
uint48 maxExpiration = type(uint48).max;
for (uint256 i = 0; i < tokens.length; ++i) {
permit2.approve(address(tokens[i]), spender, maxAmount, maxExpiration);
}
}
}
3 changes: 1 addition & 2 deletions packages/foundry/test/ConstantSumFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ contract ConstantSumFactoryTest is Test {
TokenConfig[] memory tokenConfigs = new TokenConfig[](2);
tokenConfigs[0].token = token1;
tokenConfigs[1].token = token2;
uint256 swapFeePercentage = 0;
bool protocolFeeExempt = false;
PoolRoleAccounts memory roleAccounts;
address poolHooksContract = address(0);
Expand All @@ -66,7 +65,7 @@ contract ConstantSumFactoryTest is Test {
);
}

function testFactoryPausedState() public {
function testFactoryPausedState() public view {
uint256 pauseWindowDuration = factory.getPauseWindowDuration();
assertEq(pauseWindowDuration, 365 days);
}
Expand Down
11 changes: 5 additions & 6 deletions packages/foundry/test/ConstantSumPool.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ contract ConstantSumPoolTest is BaseVaultTest {

function _createPool(address[] memory tokens, string memory label) internal override returns (address) {
factory = new ConstantSumFactory(IVault(address(vault)), 365 days);
uint256 swapFeePercentage = 0;
bool protocolFeeExempt = false;
PoolRoleAccounts memory roleAccounts;
address poolHooksContract = address(0);
Expand Down Expand Up @@ -80,12 +79,12 @@ contract ConstantSumPoolTest is BaseVaultTest {
vm.stopPrank();
}

function testPoolAddress() public {
function testPoolAddress() public view {
address calculatedPoolAddress = factory.getDeploymentAddress(ZERO_BYTES32);
assertEq(address(constantSumPool), calculatedPoolAddress);
}

function testPoolPausedState() public {
function testPoolPausedState() public view {
(bool paused, uint256 pauseWindow, uint256 bufferPeriod, address pauseManager) = vault.getPoolPausedState(
address(pool)
);
Expand All @@ -96,7 +95,7 @@ contract ConstantSumPoolTest is BaseVaultTest {
assertEq(pauseManager, address(0), "Pause manager should be 0");
}

function testInitialize() public {
function testInitialize() public view {
// Tokens are transferred from lp
assertEq(defaultBalance - usdc.balanceOf(lp), USDC_AMOUNT, "LP: Wrong USDC balance");
assertEq(defaultBalance - dai.balanceOf(lp), DAI_AMOUNT, "LP: Wrong DAI balance");
Expand Down Expand Up @@ -229,11 +228,11 @@ contract ConstantSumPoolTest is BaseVaultTest {
router.addLiquidityUnbalanced(address(pool), amountsIn, 0, false, bytes(""));
}

function testMinimumSwapFee() public {
function testMinimumSwapFee() public view {
assertEq(constantSumPool.getMinimumSwapFeePercentage(), MIN_SWAP_FEE, "Minimum swap fee mismatch");
}

function testMaximumSwapFee() public {
function testMaximumSwapFee() public view {
assertEq(constantSumPool.getMaximumSwapFeePercentage(), MAX_SWAP_FEE, "Maximum swap fee mismatch");
}

Expand Down
Loading

0 comments on commit ce353d4

Please sign in to comment.