Skip to content

Commit

Permalink
Update to deploy 12 (#118)
Browse files Browse the repository at this point in the history
* compile contracts for deploy-12 commit hash

* update hook examples and tests

* update to deploy12 and change fork to mainnet

* update gha to fork mainnet for linting / ci/cd purposes
  • Loading branch information
MattPereira authored Dec 12, 2024
1 parent 196b113 commit daa7e41
Show file tree
Hide file tree
Showing 24 changed files with 6,919 additions and 263 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,17 @@ jobs:
run: yarn install --immutable

- name: Run foundry anvil fork
run: yarn fork &
run: yarn fork --network mainnet &
env:
SEPOLIA_RPC_URL: ${{ secrets.SEPOLIA_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}

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

MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
- name: Run nextjs lint
run: yarn next:lint --max-warnings=0

Expand Down
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,26 @@ cd scaffold-balancer-v3
yarn install
```

3. Set a `SEPOLIA_RPC_URL` in the `packages/foundry/.env` file
3. Set the follwing RPC URLs in the `packages/foundry/.env` file

```
SEPOLIA_RPC_URL=...
SEPOLIA_RPC_URL=
MAINNET_RPC_URL=
GNOSIS_RPC_URL=
```

4. Start a local anvil fork of the Sepolia testnet
4. Start a local anvil fork of Ethereum mainnet
> To fork gnosis:
>
> 1. Change `targetFork` in `scaffold.config.ts` to `chains.gnosis`
> 2. Make sure the right addresses are un-commented in `PoolHelpers.sol`
> 3. Run `yarn fork --network gnosis`
```bash
yarn fork
yarn fork --network mainnet
```

5. Deploy the mock tokens, pool factories, pool hooks, and custom pools contracts
1. Deploy the mock tokens, pool factories, pool hooks, and custom pools contracts
> By default, the anvil account #0 will be the deployer and recieve the mock tokens and BPT from pool initialization
```bash
Expand Down
4 changes: 3 additions & 1 deletion packages/foundry/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
DEPLOYER_PRIVATE_KEY=
SEPOLIA_RPC_URL=
SEPOLIA_RPC_URL=
MAINNET_RPC_URL=
GNOSIS_RPC_URL=
648 changes: 648 additions & 0 deletions packages/foundry/broadcast/Deploy.s.sol/11155111/run-1734043568.json

Large diffs are not rendered by default.

648 changes: 648 additions & 0 deletions packages/foundry/broadcast/Deploy.s.sol/11155111/run-latest.json

Large diffs are not rendered by default.

13 changes: 6 additions & 7 deletions packages/foundry/contracts/hooks/LotteryHookExample.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

pragma solidity ^0.8.24;

import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

import { IHooks } from "@balancer-labs/v3-interfaces/contracts/vault/IHooks.sol";
import { IRouterCommon } from "@balancer-labs/v3-interfaces/contracts/vault/IRouterCommon.sol";
import { IHooks } from "@balancer-labs/v3-interfaces/contracts/vault/IHooks.sol";
import { IVault } from "@balancer-labs/v3-interfaces/contracts/vault/IVault.sol";
import {
AfterSwapParams,
Expand Down Expand Up @@ -35,7 +35,6 @@ contract LotteryHookExample is BaseHooks, VaultGuard, Ownable {

// Trusted router is needed since we rely on `getSender` to know which user should receive the prize.
address private immutable _trustedRouter;
address private immutable _allowedFactory;

// When calling `onAfterSwap`, a random number is generated. If the number is equal to LUCKY_NUMBER, the user will
// win the accrued fees. It must be a number between 1 and MAX_NUMBER, or else nobody will win.
Expand Down Expand Up @@ -128,7 +127,7 @@ contract LotteryHookExample is BaseHooks, VaultGuard, Ownable {
) public override onlyVault returns (bool success, uint256 hookAdjustedAmountCalculatedRaw) {
uint8 drawnNumber;
if (params.router == _trustedRouter) {
// If the router is trusted, draw a number as a lottery entry. (If router is not trusted, the user can
// If the Router is trusted, draw a number as a lottery entry. (If router is not trusted, the user can
// perform swaps and contribute to the pot, but is not eligible to win.)
drawnNumber = _getRandomNumber();
}
Expand All @@ -146,7 +145,7 @@ contract LotteryHookExample is BaseHooks, VaultGuard, Ownable {
// The preceding swap operation has already credited the original `amountCalculated`. Since we're
// returning `amountCalculated - feeToPay` here, it will only register debt for that reduced amount
// on settlement. This call to `sendTo` pulls `feeToPay` tokens of `tokenOut` from the Vault to this
// contract, and registers the additional debt, so that the total debts match the credits and
// contract, and registers the additional debt, so that the total debits match the credits and
// settlement succeeds.
uint256 feeToPay = _chargeFeeOrPayWinner(params.router, drawnNumber, params.tokenOut, hookFee);
if (feeToPay > 0) {
Expand All @@ -159,7 +158,7 @@ contract LotteryHookExample is BaseHooks, VaultGuard, Ownable {
// The preceding swap operation has already registered debt for the original `amountCalculated`.
// Since we're returning `amountCalculated + feeToPay` here, it will supply credit for that increased
// amount on settlement. This call to `sendTo` pulls `feeToPay` tokens of `tokenIn` from the Vault to
// this contract, and registers the additional debt, so that the total debts match the credits and
// this contract, and registers the additional debt, so that the total debits match the credits and
// settlement succeeds.

uint256 feeToPay = _chargeFeeOrPayWinner(params.router, drawnNumber, params.tokenIn, hookFee);
Expand Down Expand Up @@ -234,7 +233,7 @@ contract LotteryHookExample is BaseHooks, VaultGuard, Ownable {
_tokensWithAccruedFees.set(token, 1);

if (hookFee > 0) {
// Collect fees from the Vault; the user will pay them when the router settles the swap.
// Collect fees from the Vault; the user will pay them when the Router settles the swap.
_vault.sendTo(token, address(this), hookFee);

emit LotteryFeeCollected(address(this), token, hookFee);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ pragma solidity ^0.8.24;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import { IBasePoolFactory } from "@balancer-labs/v3-interfaces/contracts/vault/IBasePoolFactory.sol";
import { IHooks } from "@balancer-labs/v3-interfaces/contracts/vault/IHooks.sol";
import { IRouterCommon } from "@balancer-labs/v3-interfaces/contracts/vault/IRouterCommon.sol";
import { IHooks } from "@balancer-labs/v3-interfaces/contracts/vault/IHooks.sol";
import { IVault } from "@balancer-labs/v3-interfaces/contracts/vault/IVault.sol";
import {
LiquidityManagement,
Expand Down Expand Up @@ -78,7 +78,7 @@ contract VeBALFeeDiscountHookExample is BaseHooks, VaultGuard {
address,
uint256 staticSwapFeePercentage
) public view override onlyVault returns (bool, uint256) {
// If the router is not trusted, do not apply the veBAL discount. `getSender` may be manipulated by a
// If the Router is not trusted, do not apply the veBAL discount. `getSender` may be manipulated by a
// malicious router.
if (params.router != _trustedRouter) {
return (true, staticSwapFeePercentage);
Expand Down
2 changes: 0 additions & 2 deletions packages/foundry/deployments/.npmignore

This file was deleted.

2 changes: 2 additions & 0 deletions packages/foundry/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ fs_permissions = [{ access = "read-write", path = "./"}] # SE-2 default to allow
default_network = "http://127.0.0.1:8545"
localhost = "http://127.0.0.1:8545"
sepolia = "${SEPOLIA_RPC_URL}"
mainnet = "${MAINNET_RPC_URL}"
gnosis = "${GNOSIS_RPC_URL}"


# [etherscan]
Expand Down
2 changes: 1 addition & 1 deletion packages/foundry/lib/balancer-v3-monorepo
2 changes: 1 addition & 1 deletion packages/foundry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"compile": "forge compile",
"deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --slow && node scripts-js/generateTsAbis.js",
"flatten": "forge flatten",
"fork": "anvil --fork-url ${0:-sepolia} --chain-id 31337 --config-out localhost.json",
"fork": "anvil --fork-url ${1:-default_network} --chain-id 31337 --config-out localhost.json",
"format": "npx prettier --write --plugin=prettier-plugin-solidity 'contracts/**/*.sol' 'test/**/*.sol' 'script/*.sol' 'utils/*.sol'",
"generate": "node script/generateAccount.js",
"lint": "npx prettier --check --plugin=prettier-plugin-solidity 'contracts/**/*.sol' 'test/**/*.sol' && prettier --check ./script/**/*.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/foundry/script/00_DeployMockTokens.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ contract DeployMockTokens is ScaffoldHelpers {
vm.startBroadcast(deployerPrivateKey);

// Used to register & initialize pool contracts
mockToken1 = address(new MockToken1("Mock Token 1", "MT1", 1000e18));
mockToken2 = address(new MockToken2("Mock Token 2", "MT2", 1000e18));
mockToken1 = address(new MockToken1("Pepe the Frog", "PEPE", 1000e18));
mockToken2 = address(new MockToken2("Department of Government Efficiency", "DOGE", 1000e18));
console.log("MockToken1 deployed at: %s", mockToken1);
console.log("MockToken2 deployed at: %s", mockToken2);

Expand Down
24 changes: 18 additions & 6 deletions packages/foundry/script/PoolHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,29 @@ import { IPermit2 } from "permit2/src/interfaces/IPermit2.sol";
import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
import { IVault } from "@balancer-labs/v3-interfaces/contracts/vault/IVault.sol";
import { IRouter } from "@balancer-labs/v3-interfaces/contracts/vault/IRouter.sol";
import { console } from "forge-std/Script.sol";

/**
* @title Pool Helpers
* @notice Helpful types, interface instances, and functions for deploying pools on Balancer v3
* @notice Helpful addresses,functions, and types for deploying pools on Balancer v3
* @dev the block.chainid will always be 31337 when deploying to local anvil fork
*/
contract PoolHelpers {
// Balancer v3 Sepolia addresses (8th testnet release)
IVault internal vault = IVault(0x0EF1c156a7986F394d90eD1bEeA6483Cc435F542);
IRouter internal router = IRouter(0xB12FcB422aAe6720f882E22C340964a7723f2387);
IBatchRouter internal batchRouter = IBatchRouter(0x0418001D0d68C71d0E391fE46dC7aFCe045f34A0);
IPermit2 internal permit2 = IPermit2(0x000000000022D473030F116dDEE9F6B43aC78BA3);
// Same on all chains
IPermit2 internal permit2 = IPermit2(0x000000000022D473030F116dDEE9F6B43aC78BA3); // same on all chains
IVault internal vault = IVault(0xbA1333333333a1BA1108E8412f11850A5C319bA9);

// Mainnet
IRouter internal router = IRouter(0x5C6fb490BDFD3246EB0bB062c168DeCAF4bD9FDd);
IBatchRouter internal batchRouter = IBatchRouter(0x136f1EFcC3f8f88516B9E94110D56FDBfB1778d1);

// Gnosis
// IRouter internal router = IRouter(0x84813aA3e079A665C0B80F944427eE83cBA63617);
// IBatchRouter internal batchRouter = IBatchRouter(0xe2fa4e1d17725e72dcdAfe943Ecf45dF4B9E285b);

// Sepolia
// IRouter internal router = IRouter(0x0BF61f706105EA44694f2e92986bD01C39930280);
// IBatchRouter internal batchRouter IBatchRouter(0xC85b652685567C1B074e8c0D4389f83a2E458b1C);

/**
* Sorts the tokenConfig array into alphanumeric order
Expand Down
2 changes: 1 addition & 1 deletion packages/foundry/script/ScaffoldHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ contract ScaffoldHelpers is Script {
deployerPrivateKey = 0;
}

if (block.chainid == 31337 && deployerPrivateKey == 0) {
if (deployerPrivateKey == 0) {
root = vm.projectRoot();
path = string.concat(root, "/localhost.json");
string memory json = vm.readFile(path);
Expand Down
Loading

0 comments on commit daa7e41

Please sign in to comment.