Below, we will outline a high-level summary of everything that was worked on in Y1 (since 1st October 2022, 9 months) and describe the key challenges that were faced. This post is to provide context for the OpCo Y2 Funding Proposal. Future retrospectives/updates will be posted on a monthly basis.
For reference, here are the high-level goals set out in our Y1 funding proposal:
- Build, Improve and Optimize the canonical UI for interacting with Balancer.
- Maintain API and caching services to retrieve Balancer information.
- Integrate the front-end with other app stores and services.
- Provide tools that allow anyone to self-host the Balancer front-end.
- Provide documentation, resources and help to allow others to implement their own custom UIs for their project.
The most important initial goal was to improve the load time of the home page (pools list) and individual pool pages. Previously these pages took a long time to load due to fetching the raw pool data from the subgraph and then having to calculate important statistics on the client like total liquidity, volume/fee snapshots and APRs before being able to render the page.
To address these issues, the following optimizations have been introduced:
- Pools API implementation and usage (Time to render pools list went from ~10-20s to ~0.2-0.4s).
- Bundle size optimization (Max chunk size dropped from 3MB down to 800KB, a 73% reduction).
- Pre-fetching of page bundles on desktop. This means there is less to load when you land and usually no loading time to switch pages.
The result of this work is an app that overall feels much faster to the user than it was before.
Over the last 8 months, Boosted Pools have been a major development focus in the Balancer Ecosystem, helping position Balancer as the leader in liquidity for LSDs. As a result, significant fee flows have been generated for the DAO. Boosted and composable pools are quite different in their composition. Major and rapid refactoring was required and completed in order to enable the DAO to quickly innovate in this area that showed signs of traction.
In particular, the initial join/exit flows were never built to handle the variety of boosted pool compositions that emerged in 2022/23. The initial flows were only designed to handle weighted and stable pools without any anticipation of what was to come. Consequently, they were rigid and difficult to adapt for boosted pools. For that reason, a significant ongoing project over the past year has involved refactoring and adapting the flows to cope with boosted pools.
The work done to support boosted pools so far:
- Initial support for PoC bb-a-USD.
- Generalized Boosted pool join/exit support.
- A large refactor of the join/exit front-end architecture to be more flexible for future pool types and combinations.
- Support added for ‘whale’ exits from Boosted pools.
- Support for exits to internal balances (Euler fix) and a new page for withdrawing internal balances from the Vault.
The result of this work is that the front-end should now be capable of handling joins and exits for any combination of boosted pools up to a certain depth. Additionally, the work done enables the join and exit flows to easily adapt to unknown pool types that may arise in the future.
Many of the front-end’s initial optimization problems came from the vision of decentralizing front-ends and avoiding any dependence on centralized services. However, the UX started to suffer beyond what was acceptable and so an effort was made to set up caching layers using serverless technology.
Work done on the API / caching services:
- Pools API implementation and usage (mentioned in Optimization above).
- Full pool list sorting (made possible by using the pools API).
- SOR endpoint to speed up SOR requests.
- Cowswap solver-specific endpoint that supports join/exit swap paths.
- Moved price fetching into API, and removed direct dependency on Coingecko.
The result of working on our API and caching services has, primarily, been a drastic improvement in loading speeds for pool information. The SOR endpoint also enables other teams to more easily fetch swap information, without having to dive heavily into the SDK/SOR code.
The original implementation of the front-end for the Balancer V2 launch separated networks by subdomain. This was initially seen as a clean way to separate all dependencies for each network. In reality, it slowed down development and impacted UX. At the time it also wasn’t clear how many new networks we would support in the future due to limitations in the liquidity mining program, i.e. being spread too thin. With the implementation of veBAL deploying on new networks became more feasible and so some work on the front-end was required to make that process as quick and easy as possible.
Work done to support new networks:
- Consolidated all networks into one app (no subdomains and multiple deployments).
- Consolidation of network-specific config into one directory for each network.
- Added Gnosis Chain support.
- Added zkEVM support.
The result is an improved UX where users can more easily switch between networks, i.e. it’s quicker because a full app refetch is not required. However, the primary benefit has been that we can more easily add support for new networks.
A significant amount of technical debt was built up in the front-end codebase due to the time and resource constraints in building out the initial V2 app, and following that, a consistent stream of new protocol features or new pool types to support. In 2023 we have had the opportunity to clean up some of that technical debt and make the codebase easier to work with and add to in the future.
Notable refactors carried out:
- Join/exit architecture.
- Staking architecture.
- New network consolidation.
- Assets repo to tokenlists repo.
The benefits of this work are primarily in DX (developer experience). It makes it easier for our team to reason about what the code does and it also makes it easier for us to adapt and add to that code in the future. A secondary benefit is that it makes the code more stable and therefore the UX should feel less error-prone.
In the above sections, we have outlined the areas of work that addressed our biggest challenges and required the most time and resources. In addition, we worked on many smaller scopes of work, some of which are summarized below:
- Support for migrations, pool to pool and gauge to gauge.
- Vote resubmission.
- List filtering.
- List loading optimisation.
- Swap UI improvements:
- Added support for join/exit paths.
- Added trade amount URL params for direct trade linking.
- Error tracking improvements.
- Protocol risks page.
- Pool risks section on pool page.
- WalletConnectV2 support.
All previously mentioned challenges, and many other challenges not worth detailing here stem from a single problem, when we initially built the front-end app for the V2 launch back in Q2 2021, the vision at Balancer Labs was that decentralization of front-ends would also be important. That meant keeping the app as a static SPA (Single Page Application) and not relying heavily on any centralized services like APIs. This approach results in overly complex and heavy front-ends where the majority of business logic that would typically reside in APIs ends up in front-end code. We believe this approach is not optimal, as previously mentioned, it results in complex front-ends which slow down development and therefore the ability to adapt to a quickly evolving protocol. The industry (DeFi) also seems to be moving away from this ideal in favour of centralized supporting services to facilitate better UX, and we should too. Of course, decentralized UI tooling should still be provided to perform core protocol actions, but this should be separate from the canonical app. We will propose solutions to this problem in the OpCo’s Y2 Funding Proposal (coming soon).