balancer / scaffold-balancer-v3

Starter kit for creating custom pools and hooks contracts on Balancer v3
https://scaffold-balancerv3.vercel.app
MIT License
19 stars 17 forks source link

๐Ÿ—๏ธŽ Scaffold Balancer v3

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

๐Ÿ” 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

๐Ÿชง Table Of Contents

๐Ÿง‘โ€๐Ÿ’ป Environment Setup

1. Requirements ๐Ÿ“œ

2. Quickstart ๐Ÿƒ

  1. Ensure you have the latest version of foundry installed

    foundryup
  2. Clone this repo & install dependencies

git clone https://github.com/balancer/scaffold-balancer-v3.git
cd scaffold-balancer-v3
yarn install
  1. 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
DEPLOYER_PRIVATE_KEY=0x...
SEPOLIA_RPC_URL=...
  1. Start a local anvil fork of the Sepolia testnet
yarn fork
  1. 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
yarn deploy
  1. Start the nextjs frontend
yarn start
  1. Explore the frontend
  1. Run the Foundry tests
yarn test

3. Scaffold ETH 2 Tips ๐Ÿ—๏ธ

SE-2 offers a variety of configuration options for connecting an account, choosing networks, and deploying contracts

๐Ÿ”ฅ Burner Wallet If you do not have an active wallet extension connected to your web browser, then scaffold eth will automatically connect to a "burner wallet" that is randomly generated on the frontend and saved to the browser's local storage. When using the burner wallet, transactions will be instantly signed, which is convenient for quick iterative development. To force the use of burner wallet, disable your browsers wallet extensions and refresh the page. Note that the burner wallet comes with 0 ETH to pay for gas so you will need to click the faucet button in top right corner. Also the mock tokens for the pool are minted to your deployer account set in `.env` so you will want to navigate to the "Debug Contracts" page to mint your burner wallet some mock tokens to use with the pool. ![Burner Wallet](https://github.com/Dev-Rel-as-a-Service/scaffold-balancer-v3/assets/73561520/0a1f3456-f22a-46b5-9e05-0ef5cd17cce7) ![Debug Tab Mint](https://github.com/Dev-Rel-as-a-Service/scaffold-balancer-v3/assets/73561520/fbb53772-8f6d-454d-a153-0e7a2925ef9f)
๐Ÿ‘› Browser Extension Wallet - To use your preferred browser extension wallet, ensure that the account you are using matches the PK you previously provided in the `foundry/.env` file - You may need to add a local development network with rpc url `http://127.0.0.1:8545/` and chain id `31337`. Also, you may need to reset the nonce data for your wallet exension if it gets out of sync.
๐Ÿ› Debug Contracts Page The [Debug Contracts Page](http://localhost:3000/debug) can be useful for viewing and interacting with all of the externally avaiable read and write functions of a contract. The page will automatically hot reload with contracts that are deployed via the `01_DeployConstantSumFactory.s.sol` script. We use this handy setup to mint `mockERC20` tokens to any connected wallet
๐ŸŒ Changing The Frontend Network Connection - The network the frontend points at is set via `targetNetworks` in the `scaffold.config.ts` file using `chains` from viem. - By default, the frontend runs on a local node at `http://127.0.0.1:8545` ```typescript const scaffoldConfig = { targetNetworks: [chains.foundry], ```
๐Ÿด Changing The Forked Network - By default, the `yarn fork` command points at sepolia, but any of the network aliases from the `[rpc_endpoints]` of `foundry.toml` can be used to modify the `"fork"` alias in the `packages/foundry/package.json` file ```json "fork": "anvil --fork-url ${0:-sepolia} --chain-id 31337 --config-out localhost.json", ``` - To point the frontend at a different forked network, change the `targetFork` in `scaffold.config.ts` ```typescript const scaffoldConfig = { // The networks the frontend can connect to targetNetworks: [chains.foundry], // If using chains.foundry as your targetNetwork, you must specify a network to fork targetFork: chains.sepolia, ```

๐Ÿ‘ฉโ€๐Ÿซ Learn Core Concepts

v3-components

๐Ÿ•ต๏ธ Explore the Examples

Each of the following examples have turn key deploy scripts that can be found in the 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

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

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

๐ŸŒŠ Create a Custom Pool

custom-amm-video

1. Review the Docs ๐Ÿ“–

2. Recall the Key Requirements ๐Ÿ”‘

3. Write a Custom Pool Contract ๐Ÿ“

๐Ÿญ Create a Pool Factory

After designing a pool contract, the next step is to prepare a factory contract because Balancer's off-chain infrastructure uses the factory address as a means to identify the type of pool, which is important for integration into the UI, SDK, and external aggregators

1. Review the Docs ๐Ÿ“–

2. Recall the Key Requirements ๐Ÿ”‘

3. Write a Factory Contract ๐Ÿ“

๐Ÿช Create a Pool Hook

hook-video

1. Review the Docs ๐Ÿ“–

2. Recall the Key Requirements ๐Ÿ”‘

3. Write a Hook Contract ๐Ÿ“

๐Ÿšข Deploy the Contracts

The deploy scripts are located in the foundry/script/ directory. To better understand the lifecycle of deploying a pool that uses a hooks contract, see the diagram below

pool-deploy-scripts

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

2. Broadcast the Transactions ๐Ÿ“ก

To run all the deploy scripts

yarn deploy

๐Ÿ›ˆ To deploy to the live sepolia testnet, add the --network sepolia flag

๐Ÿงช Test the Contracts

The balancer-v3-monorepo provides testing utility contracts like BasePoolTest and BaseVaultTest. Therefore, the best way to begin writing tests for custom factories, pools, and hooks contracts is to leverage the examples established by the source code.

1. Testing Factories ๐Ÿ‘จโ€๐Ÿ”ฌ

The ConstantSumFactoryTest roughly mirrors the WeightedPool8020FactoryTest

yarn test --match-contract ConstantSumFactoryTest

2. Testing Pools ๐ŸŠ

The ConstantSumPoolTest roughly mirrors the WeightedPoolTest

yarn test --match-contract ConstantSumPoolTest

3. Testing Hooks ๐ŸŽฃ

The VeBALFeeDiscountHookExampleTest mirrors the VeBALFeeDiscountHookExampleTest

yarn test --match-contract VeBALFeeDiscountHookExampleTest