Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use default anvil account if no pk provided #81

Merged
merged 2 commits into from
Sep 30, 2024
Merged
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
16 changes: 0 additions & 16 deletions .github/pull_request_template.md

This file was deleted.

47 changes: 31 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@

A starter kit for building on top of Balancer v3. Accelerate the process of creating custom pools and hooks contracts. Concentrate on mastering the core concepts within a swift and responsive environment augmented by a local fork and a frontend pool operations playground.


[![intro-to-scaffold-balancer](https://github.com/user-attachments/assets/f862091d-2fe9-4b4b-8d70-cb2fdc667384)](https://www.youtube.com/watch?v=m6q5M34ZdXw)

### 🔁 Development Life Cycle

1. Learn the core concepts for building on top of Balancer v3
2. Configure and deploy factories, pools, and hooks contracts to a local anvil fork of Sepolia
3. Interact with pools via a frontend that runs at [localhost:3000](http://localhost:3000/)


### 🪧 Table Of Contents

- [🧑‍💻 Environment Setup](#-environment-setup)
Expand All @@ -34,6 +33,7 @@ A starter kit for building on top of Balancer v3. Accelerate the process of crea
### 2. Quickstart 🏃

1. Ensure you have the latest version of foundry installed

```
foundryup
```
Expand All @@ -46,11 +46,9 @@ cd scaffold-balancer-v3
yarn install
```

3. Set the necessary environment variables in a `packages/foundry/.env` file [^1]
[^1]: The `DEPLOYER_PRIVATE_KEY` must start with `0x` and must possess enough Sepolia ETH to deploy the contracts. The `SEPOLIA_RPC_URL` facilitates running a local fork and sending transactions to sepolia testnet
3. Set a `SEPOLIA_RPC_URL` in the `packages/foundry/.env` file

```
DEPLOYER_PRIVATE_KEY=0x...
SEPOLIA_RPC_URL=...
```

Expand All @@ -60,8 +58,8 @@ SEPOLIA_RPC_URL=...
yarn fork
```

5. Deploy the mock tokens, pool factories, pool hooks, and custom pools contracts [^2]
[^2]: The `DEPLOYER_PRIVATE_KEY` wallet receives the mock tokens and resulting BPT from pool initialization
5. 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
yarn deploy
Expand Down Expand Up @@ -158,31 +156,32 @@ const scaffoldConfig = {

![v3-components](https://github.com/user-attachments/assets/ccda9323-790f-4276-b092-c867fd80bf9e)


## 🕵️ Explore the Examples

Each of the following examples have turn key deploy scripts that can be found in the [foundry/script/](https://github.com/balancer/scaffold-balancer-v3/tree/main/packages/foundry/script) directory

### 1. Constant Sum Pool with Dynamic Swap Fee Hook

The swap fee percentage is altered by the hook contract before the pool calculates the amount for the swap

![dynamic-fee-hook](https://github.com/user-attachments/assets/5ba69ea3-6894-4eeb-befa-ed87cfeb6b13)

### 2. Constant Product Pool with Lottery Hook

An after swap hook makes a request to an oracle contract for a random number

![after-swap-hook](https://github.com/user-attachments/assets/594ce1ac-2edc-4d16-9631-14feb2d085f8)

### 3. Weighted Pool with Exit Fee Hook
An after remove liquidity hook adjusts the amounts before the vault transfers tokens to the user

![after-remove-liquidity-hook](https://github.com/user-attachments/assets/2e8f4a5c-f168-4021-b316-28a79472c8d1)
An after remove liquidity hook adjusts the amounts before the vault transfers tokens to the user

![after-remove-liquidity-hook](https://github.com/user-attachments/assets/2e8f4a5c-f168-4021-b316-28a79472c8d1)

## 🌊 Create a Custom Pool

[![custom-amm-video](https://github.com/user-attachments/assets/e6069a51-f1b5-4f98-a2a9-3a2098696f96)](https://www.youtube.com/watch?v=kXynS3jAu0M)


### 1. Review the Docs 📖

- [Create a custom AMM with a novel invariant](https://docs-v3.balancer.fi/build-a-custom-amm/build-an-amm/create-custom-amm-with-novel-invariant.html)
Expand Down Expand Up @@ -229,7 +228,7 @@ After designing a pool contract, the next step is to prepare a factory contract
- A hooks contract should also inherit from [VaultGuard.sol](https://github.com/balancer/balancer-v3-monorepo/blob/main/pkg/vault/contracts/VaultGuard.sol)
- Must implement `onRegister` to determine if a pool is allowed to use the hook contract
- Must implement `getHookFlags` to define which hooks are supported
- The `onlyVault` modifier should be applied to all hooks functions (i.e. `onRegister`, `onBeforeSwap`, `onAfterSwap` ect.)
- The `onlyVault` modifier should be applied to all hooks functions (i.e. `onRegister`, `onBeforeSwap`, `onAfterSwap` ect.)

### 3. Write a Hook Contract 📝

Expand All @@ -241,20 +240,36 @@ The deploy scripts are located in the [foundry/script/](https://github.com/balan

![pool-deploy-scripts](https://github.com/user-attachments/assets/bb906080-8f42-46c0-af90-ba01ba1754fc)


### 1. Modifying the Deploy Scripts 🛠️

For all the scaffold integrations to work properly, each deploy script must be imported into `Deploy.s.sol` and inherited by the `DeployScript` contract in `Deploy.s.sol`
For all the scaffold integrations to work properly, each deploy script must be imported into `Deploy.s.sol` and inherited by the `DeployScript` contract in `Deploy.s.sol`

### 2. Broadcast the Transactions 📡

To run all the deploy scripts
#### Deploy to local fork

1. Run the following command

```bash
yarn deploy
```

🛈 To deploy to the live sepolia testnet, add the `--network sepolia` flag
#### Deploy to a live network

1. Add a `DEPLOYER_PRIVATE_KEY` to the `packages/foundry/.env` file

```
DEPLOYER_PRIVATE_KEY=0x...
SEPOLIA_RPC_URL=...
```

> The `DEPLOYER_PRIVATE_KEY` must start with `0x` and must hold enough Sepolia ETH to deploy the contracts. This account will receive the BPT from pool initialization

2. Run the following command

```
yarn deploy --network sepolia
```

## 🧪 Test the Contracts

Expand Down
2 changes: 1 addition & 1 deletion packages/foundry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"account": "node script/ListAccount.js",
"chain": "anvil --config-out localhost.json",
"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 && node scripts-js/generateTsAbis.js",
"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",
"format": "npx prettier --write --plugin=prettier-plugin-solidity 'contracts/**/*.sol' 'test/**/*.sol' 'script/*.sol' 'utils/*.sol'",
Expand Down
25 changes: 15 additions & 10 deletions packages/foundry/script/ScaffoldHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,30 @@ contract ScaffoldHelpers is Script {
string path;
Deployment[] public deployments;

function getDeployerPrivateKey() internal view returns (uint256 deployerPrivateKey) {
deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
if (deployerPrivateKey == 0) {
revert InvalidPrivateKey(
"You don't have a deployer account. Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new random account"
);
/**
* Use the pk defined by dev if they added one to a .env file,
* otherwise use the default anvil #0 account
*/
function getDeployerPrivateKey() internal returns (uint256 deployerPrivateKey) {
try vm.envUint("DEPLOYER_PRIVATE_KEY") returns (uint256 key) {
deployerPrivateKey = key;
} catch {
deployerPrivateKey = 0;
}
}

function setupLocalhostEnv() internal returns (uint256 localhostPrivateKey) {
if (block.chainid == 31337) {
if (block.chainid == 31337 && deployerPrivateKey == 0) {
root = vm.projectRoot();
path = string.concat(root, "/localhost.json");
string memory json = vm.readFile(path);
bytes memory mnemonicBytes = vm.parseJson(json, ".wallet.mnemonic");
string memory mnemonic = abi.decode(mnemonicBytes, (string));
return vm.deriveKey(mnemonic, 0);
} else {
return vm.envUint("DEPLOYER_PRIVATE_KEY");
if (deployerPrivateKey == 0) {
revert InvalidPrivateKey(
"You don't have a deployer account. Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new random account"
);
}
}
}

Expand Down
18 changes: 9 additions & 9 deletions packages/nextjs/contracts/deployedContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";
const deployedContracts = {
31337: {
MockToken1: {
address: "0x37efddf706dcbd55ad4e8b5d4ddacf970d4c2e93",
address: "0xfdc90fb27105f322b384af5c3a39183047dec080",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -365,7 +365,7 @@ const deployedContracts = {
},
},
MockToken2: {
address: "0x0e8ebbd5590e4ad7fa19297eceaa238aa0361898",
address: "0xd2ed70a2ddc08f9e302b5298ef2e656959e79dd5",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -723,7 +723,7 @@ const deployedContracts = {
},
},
MockVeBAL: {
address: "0x46289c4f227af06e10d23ee09d4ad1bba9f177d8",
address: "0x8e18528aa76be18c51653a3f61fe79cea130620f",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -1081,7 +1081,7 @@ const deployedContracts = {
},
},
ConstantSumFactory: {
address: "0x543119c86f3d3fe063dd648df238b24b18c284c8",
address: "0x1f16730c011b43dc6a62259b30e5721265883dde",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -1465,7 +1465,7 @@ const deployedContracts = {
},
},
VeBALFeeDiscountHookExample: {
address: "0x25658ff6251ce2647a4834ab47b63420ef5ba1da",
address: "0x0d5e217f22a9f92f1dd2d5d5ede64ffc913a626d",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -2175,7 +2175,7 @@ const deployedContracts = {
},
},
ConstantProductFactory: {
address: "0x2c6e466169ffac0dca70bc170ea18f1aaa8e42a3",
address: "0x35b2e11b8c2b27fd74bd28da018eee10a67c95a8",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -2559,7 +2559,7 @@ const deployedContracts = {
},
},
LotteryHookExample: {
address: "0x3d993ff56201116c0ac8ee196a1f55a6a56a0f53",
address: "0xf92fb772445695d6d5a5a4dbbfd2d886b1500a52",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -3513,7 +3513,7 @@ const deployedContracts = {
},
},
WeightedPoolFactory: {
address: "0x69bf7d0745856db65fbfc1d2baa9a0cd702b0541",
address: "0x6def85e32294b59ad5084a12304d1284737b4389",
abi: [
{
type: "constructor",
Expand Down Expand Up @@ -3918,7 +3918,7 @@ const deployedContracts = {
},
},
ExitFeeHookExample: {
address: "0x0dca8c80fe1dc49b0f54305c04c8c2842e16d9d0",
address: "0x8a5450ce448a84ac5e6aea0ca03fb16d590d6227",
abi: [
{
type: "constructor",
Expand Down
Loading