{"id":26162525,"url":"https://github.com/balancer/linear-pools","last_synced_at":"2026-02-02T18:37:49.362Z","repository":{"id":64269229,"uuid":"572235127","full_name":"balancer/linear-pools","owner":"balancer","description":null,"archived":false,"fork":false,"pushed_at":"2023-06-06T10:03:46.000Z","size":29221,"stargazers_count":6,"open_issues_count":0,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-28T02:38:57.041Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/balancer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-11-29T20:51:49.000Z","updated_at":"2023-11-02T05:30:18.000Z","dependencies_parsed_at":"2024-03-27T01:01:48.890Z","dependency_job_id":null,"html_url":"https://github.com/balancer/linear-pools","commit_stats":null,"previous_names":["balancer/linear-pools"],"tags_count":5,"template":false,"template_full_name":"balancer/balancer-examples","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Flinear-pools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Flinear-pools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Flinear-pools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/balancer%2Flinear-pools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/balancer","download_url":"https://codeload.github.com/balancer/linear-pools/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248888579,"owners_count":21178081,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-11T13:54:54.049Z","updated_at":"2026-02-02T18:37:44.335Z","avatar_url":"https://github.com/balancer.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Balancer V2 Linear Pool Integrations\n\n[![Docs](https://img.shields.io/badge/docs-%F0%9F%93%84-blue)](https://docs.balancer.fi/guides/boosted-pool-creators/new-protocol.html)\n[![License](https://img.shields.io/badge/License-GPLv3-green.svg)](https://www.gnu.org/licenses/gpl-3.0)\n\nThis repo contains smart contract implementations of all known Linear Pool factories on Balancer. Contributions are welcome!\n\n\u003e IMPORTANT: Before developing your own factory, ensure that your yield-bearing token is truly incompatible with existing solutions. In most cases, unique factories are not required to support forks of existing integrations (e.g., Aave v2). Furthermore, yield vaults implementing the [ERC-4626 standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626/) can leverage [that factory](./pkg/linear-pools/contracts/erc4626-linear-pool) and will not require bespoke solutions.\n\nFor more information about Boosted Pools and Linear Pools, please consult the [official documentation](https://docs.balancer.fi/concepts/pools/boosted.html).\n\n# Components of a Linear Pool Integration\n\nEach implementation should include the components below.\n\n## LinearPool\n\nThe Linear Pool contract defines how the exchange rate is calculated. This is the most critical component because it determines the price of each swap within the Pool.\n\n\u003e NOTE: All external calls within the `_getWrappedTokenRate` function should include try/catch blocks and utilize the [`ExternalCallLib`](https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/pool-utils/contracts/lib/ExternalCallLib.sol) to prevent manipulation by nefarious tokens.\n\n### Unit Tests\n\nAt a minimum, the unit tests for each Linear Pool should verify the following assumptions:\n\n1. There is strict relationship between a `mainToken` and `wrappedToken` is respected (e.g., cDAI is not paired with USDC).\n2. Asset Managers are set correctly.\n3. The token rate is calculated correctly and is normalized to 1e18 regardless of `mainToken` or `wrappedToken` decimals.\n4. Malicious queries (that manipulate the token rate) are reverted.\n\n## LinearPoolFactory\n\nThe Linear Pool Factory contract is responsible for creating new Linear Pools.\n\n### Unit Tests\n\nAt a minimum, the unit tests for each Linear Pool Factory should verify the following assumptions:\n\n1. A Pool can be created and its constituent tokens are registered in the Vault.\n2. The Factory version and Pool version are set correctly.\n3. An Asset Manager is created and configured for each Pool.\n\n## LinearPoolRebalancer\n\nThe Linear Pool Rebalancer contract is a helper to enable efficient, capital-free arbitrage and maintain the target balance of `mainToken` within the Pool.\n\nIt doesn't have unit tests. The logic of the Rebalancer is instead verified using fork tests, since it is very sensitive to the `wrappedToken` implementation.\n\n## Protocol Interface(s)\n\nIn order to implement a Linear Pool for a given yield protocol, we need to understand the following features of that protocol:\n\n* Can the exchange rate between the `mainToken` and `wrappedToken` be queried directly, and is the return value up to date?\n  * If not, how can we calculate the exchange rate?\n* How is `mainToken` deposited to the protocol?\n* How is `wrappedToken` redeemed, or `mainToken` withdrawn, from the protocol?\n* How many decimals does the `wrappedToken` have? Is it at all related to the `mainToken` decimals, or is it fixed?\n\nThese questions will define which interfaces need to be declared. Some protocols expose all of this via the token contract itself, whereas others perform some or all operations via a central protocol vault.\n\n### Mocked Contracts\n\nIn order to properly unit test Linear Pool contracts, mocked token contracts need to be implemented. These can be found inside the `__mocks__` directory.\n\n## Fork Tests\n\nFork tests are also essential because they act on real token contracts rather than mocks. The Rebalancer, especially, requires precision in order to function correctly, so it is safest to verify it on a real protocol token.\n\nFork tests can be found inside [`pkg/fork-tests`](./pkg/fork-tests), and their implementation is described in the next section.\n\n# How-To Guide\n\n1. Clone this repository to your machine. Ensure that you have `nodejs` installed and that your version is at least 14.x (preferably 16.x). Run `yarn \u0026\u0026 yarn build` to begin, and troubleshoot any errors you encounter before moving forward.\n2. Create a copy of [`pkg/linear-pools/contracts/erc4626-linear-pool`](./pkg/linear-pools/contracts/erc4626-linear-pool), and change the name to match your protocol's name (e.g., `pkg/linear-pools/contracts/\u003cYOUR_PROTOCOL\u003e-linear-pool`)\n3. Change the names of all files accordingly, e.g., `ERC4626LinearPool.sol`, `ERC4626LinearPoolFactory.sol`, `ERC4626LinearPoolRebalancer.sol`, and all corresponding test files.\n4. Within each file, change the names of variables and classes to suit your protocol's name.\n5. Inside `\u003cYOUR_PROTOCOL\u003eLinearPool.sol`, adapt the `_getWrappedTokenRate` function to your protocol. Make sure to wrap any external calls in try/catch blocks and utilize the `ExternalCallLib`.\n\n   1. NOTE: During this step, you'll probably need to define an interface for the token/vault of the protocol, especially the function pertaining to the exchange rate.\n   \n6. Inside `\u003cYOUR_PROTOCOL\u003eLinearPoolRebalancer.sol`, define the `_wrapTokens` (deposit), `_unwrapTokens` (redeem), and `_getRequiredTokensToWrap` (given an amount of `wrappedToken`, how many `mainToken` do I need?) functions.\n\n   1. IMPORTANT: `_getRequiredTokensToWrap` also uses the token rate, so make sure that `_getWrappedTokenRate` and `_getRequiredTokensToWrap` use the same source to fetch the token rate.\n   2. IMPORTANT: During this step, the interface created in Step 4 will need to be expanded to include withdraw/deposit functions.\n   \n7. Edit the `setup` section within your Linear Pool test file to make sure you're deploying and testing the correct Linear Pool. Do not delete any tests from the copied file, since many tests apply to all kinds of Linear Pools and protocols.\n\n   1. NOTE: `setup` deploys a mocked version of the token, so you'll also need to implement a mock. If your protocol uses a central vault contract as well, check the `AaveLinearPool` tests for examples.\n\n8. Run `yarn test` and make sure the Linear Pool tests pass.\n9. Edit the Linear Pool Factory test file (especially `beforeEach('deploy factory \u0026 tokens')`) to adapt to your protocol. You don't need to change the Protocol ID right now.\n10. Run `yarn test` and make sure the Linear Pool Rebalancer tests pass.\n11. To begin fork testing, navigate to `pkg/fork-tests/tests`, duplicate the ERC-4626 test folder, and change the name to your protocol. Make sure the number in the folder matches the YYYYMMDD pattern.\n12. Delete the `output` directory and the contents of `build-info`.\n13. Adapt `index.ts`, `input.ts`, and `readme.md` to your protocol name.\n14. Open `pkg/linear-pools` and run `yarn hardhat compile`. Once the contracts are compiled, open the `artifacts/build-info` directory and copy the json inside this file to `pkg/fork-tests/tests/YYYYMMDD-\u003cYOUR-PROTOCOL\u003e-linear-pool/build-info`.\n15. Inside your test folder, open `test.fork.ts` and adapt it to your protocol. Make sure that you're using a recent block number, token addresses are correctly defined, and your chosen token holder has a large balance at that block number.\n16. Go to `pkg/fork-tests` and run `yarn test`. Make sure your tests are passing.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalancer%2Flinear-pools","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbalancer%2Flinear-pools","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbalancer%2Flinear-pools/lists"}