Unlocking AMM Powers With Balancer V3 Hooks
Dappcon·Thu, Jun 19, 2025, 01:29 PM · 43:56
with Fabio Mendes & John Grant
Transcript
Okay, thank you everyone for joining us. Today, we're going to talk about balancer V3 hooks and how you can build on them and why you should build on them. Just a quick intro to the agenda. We'll do a very quick V3 introduction, talk about why it's good for you guys to build on balancer and some of the benefits that you maybe don't know about. A quick overview of the V3 architecture and how that relates to hooks.
We'll go through the Staple Search hook, which is a hook that is deployed live at the moment. That will showcase some of the hook code. And then I'll switch to Fabio, who will walk through another one of our hooks, which is the MAV capture walkthrough. And then we'll close out and you can ask any questions. So, Balancer V3 is a platform for AMMs.
Using our past experience from V1 and V2, it was really focused on making it easy to build and customize AMMs. It's been fully and very deeply audited, been audited by three of the best firms, which should give you confidence that you can use it as a Lego block to build on top of. Some of the other interesting innovations that we added is support for 100% boosted pools, which basically makes the pools super capital efficient by depositing idle liquidity into any of the lending protocols, such as Aave. And for this talk especially, we introduced support for hooks at various life cycle points. And these are basically modular plug-ins that allow you to extend any existing pool behavior.
Since launch at the end of last year, both partners and ourselves have been busy building things on Balancer V3. We've got a range of pools that have been built on top of it, such as wave pools, stable pools, gyroscope pools, which were built by the gyroscope team, quant AMM pools, reclam pools, which is our latest pool that Fabio introduced yesterday, and we also have three hooks in the wild as well, the StableSearch hook and the MEV Capture hook, which we'll go over today, and then Akron hook, which was built by a separate team without even really getting in touch with us, which kind of showcases how easy it is to do. Didn't Cow also make some hooks in the V3 pool for the Cow AMM? So the question was, did Cow AMMs also build on top? So they're actually built on V1 because they were developed while we were still developing V3, and they will be ported to V3 at some point soon.
They're doing that as we speak. Does the V3 contract repo have the Cow pool in it? The V3. That's possibly part of the development. They're really migrating over now, but yeah, it should be coming soon on V3 as well.
Yeah, so why should you guys build on Balancer V3? The main idea, the main reason is actually because you can take your idea to product super fast, and a shorter development cycle means faster time to market for you, and you can just focus on implementing your actual idea. You can build on top of all the Balancer audited code relating to like token balances, accounting, and you can just take care of your own stuff. We also have comprehensive documentation. We have a range of example hoops and reference implementations in the Monorepo.
We've got a bunch of helpful periphery contracts that you can leverage for testing and development. We have very active dev support in Discord and Telegram, and we also have grants available if you have any ideas. So basically, if you have anything or if you need help, you can reach out to us at any point, and we'll be there to help. And it's not just the development part. We also have a lot of support after launch or before the launch through our ecosystem.
We have the Balancer front end, which is modular and easy to update to include customer branding. We can also implement extra features, so both Kairoscope and QuantAMM are separate products, but we've managed to add them to our Balancer UI, which allows them to launch straight away with an interface that LPs can come and add and remove liquidity. And it also showcases their own kind of design, their own kind of graphs and things. Aggregators is super important. You can't just launch a pool and expect the aggregators to pick it up.
We have good relationships with all the core aggregators and solvers, and we also make contributions directly to their code base. So that's something that we can do so that you can launch and soon after be picked up, which drives volume to your pool, which gives your LPs more swap fees. Balancer also has the incentive slide wheel, and we have a very capable and supportive operations and marketing teams. They can help you from things like governance proposals, launching your first pools, anything like that, there's somebody there to kind of help you. So just to cover the architecture before we get into the code, it's a very high level view, but there's like four main components to look at.
The router, the vault, the pools and the hooks. The router is the user's entry point to Balancer, and this is where like somebody would go if they want to register a pool, add liquidity, remove liquidity or swap. The vault is a single pin contract that does scaling, fee accounting, limit, things like that, and it's been optimized for gas. Both these contracts or range of contracts are fully audited, deployed, and it's not something you really need to worry about. You just need to focus on the right hand side, which is your custom pools or custom hook logic.
And it's probably worth explaining at this point the difference between the pools and the hooks. So pools are where you can define your core maths. It's where you can build different math-based liquidity curves. So you can think of your wave pools, your stable pools, gyro pools, things like that, basically giving you custom pricing models. So it's like a new AMM.
Whereas hooks extend these pools. So a hook can be used with any pool type. It can be used with multiple pools, and it basically allows you to build extra behavior on top of that existing pool. And a hook is registered with a pool when the pool is created. And once it's registered, you can't unhook it, basically.
It's immutable. So that's something worth noting. And the hooks themselves can be hooked into a different range of lifecycle points. So we have basically registration, initialization, after and before add liquidity, the same with remove liquidity. And we've also got the dynamic swap fee hooks.
And you can use one or more of these within your hook. So the hook we're going to talk about first is the stable search hook. This was an innovative directional fee mechanism that was actually proposed by one of our maxes. And it's basically a dynamic swap fee hook that as the pool becomes imbalanced, the price of the swap fee goes up, which should protect stable coin pegs during periods of market volatility. And the things that we use in the code here is the stable pool and also the custom search logic which exists in the hook itself.
To start with, we'll talk about two of the periphery contracts that exist in Balancer v3 already that you can leverage. So the first one is the vault guard. It's a base contract that your hook can inherit and stores a reference to the Balancer vault and basically ensures that when you use the only vault modifier, it restricts access to only the vault. And it's important to use that because only the vault should trigger hook logic. And this prevents external or unauthorized contracts from calling any sensitive logic.
I can just flick over quickly. Just looking at the stable search hook itself. So you can see that it's added here on the on register. And it's easy to just import this. And you just inherit it as a vault guard.
And these hooks are all available in the Monorepo and serve as like super useful references if you're going to start hacking yourself. The next one is the base hook. It's another one that can be inherited and basically implement a minimal default hook that your hook should follow. You can basically override any of the functions that you want to implement and then be sure that anything that you have not implemented will be covered correctly. That's basically done by each hook returning false, which means that no logic will be applied for that hook.
And you should use that for a number of reasons. It basically saves you time because you only need to override what you want to do. And it does ensure that your hook is going to be compatible with the interface. And it basically improves your safety. I'll just quickly show that one.
So it's basics here. And you can see that every hook here is just defined and returns false, which basically shows the vault that that hook is not going to be used. And then in the stable surge, wherever we want to use any logic, we've just overridden it here and implemented our own logic in the contract itself. So the first thing that you have to override if you use the basics is the getHookFlags function. This is called by the vault whenever a pool is registered.
And it basically tells the vault what the config of that hook is and what hooks it's going to use. Once the pool is registered with that hook, that config is saved in the vault and the vault will use those configs to make sure that the hooks that you've configured are going to be used. We can see in the stable surge hook that we use three separate hooks. We've got the dynamic swap fee, the after add liquidity, and the after remove liquidity. Every hook must implement this.
And if it doesn't, yeah, your test won't pass basically. On hook registration, we also have the onRegister function. And this can be used for a bunch of different things. One of the common use cases is restricting usage. So basically if this function returns false, the actual throw in the pool can't be created with that hook.
So you can use it for whitelisting. You can restrict it to certain pool types or certain pool factors. And it can also be used to initialize with default configuration. For your pool to successfully register with a hook, that function must return true. And we can see in the stable surge hook, there's no kind of whitelisting going on, but it's being used here to set the max surge fee to the default and set the surge threshold to the default.
It also omits an event, which is super useful for the off-chain infrastructure. And then it just returns true, which allows the registration to continue. The other hooks that this particular stable surge hook uses is the add and remove hooks. So these are triggered after an LP adds or removes liquidity. And it's important to note that this function gets called with the updated balances from the vault for that pool.
So it can be used to validate the pool state. You can emit custom logs or analytics. It can also be used at that point in time to interact with external contracts. And in this particular case, it's used to detect if the pool is surging at that point after the liquidity has been added or removed. And if it is surging, then it will throw false and the action will be blocked.
And this ensures that the liquidity isn't added during unstable conditions. It's a pretty hard one to see. If we just look at a bit of the code here, we can see the first thing it does is it's checking what kind of add action it is. Any proportional add is fine because it's always going to be adding it proportionally, which won't unbalance the pool. So it immediately returns true, which allows the vault just to continue with the action.
If it's not a proportional add, then we're doing some math to basically detect if the pool is going to surge after the action. And if it is surging, then it returns false, which will block the action. And if it's not, it will just return true. So it's a nice way to make sure that your LPs aren't going to get shafted, basically. And then the last one, which is where the meat of this innovation is happening, is the dynamic swap fee, which is the on-compute dynamic swap fee percentage hook.
This is called every time that a swap is happening. And the hook responds to the vault with the current swap fee, which is then used in the swap calculations. And this allows your hook to dynamically change the swap fee based on the pool state, the direction, or external data. So there's a lot of room for innovation within this. The dynamic swap fee itself, the math is here.
It's pretty detailed. If you do want to look at it, you can check out the whole Monorepo implementation. But the basic kind of principle is if the pool drifts from the balance, the fee starts surging. It increases the fee as the imbalance becomes further. And if it's not surging at all, it will just return the default swap fee.
So you can see this. So here's the on-compute dynamic swap fee. It has to return true again. If it turns false at any point, then the action will be blocked. And then it's getting the get surge fee percentage.
So the first thing it's doing is updating the balances with the amounts. And then it goes into the get surge fee percentage. This is where the math is happening. And then it's basically checking if it is surging. It returns this calculated swap fee, which is based on the math.
And if it's not, it just uses the static swap fee that the pool was configured with at the time. And the reason we wanted to kind of highlight stable surge is this is a hook that was implemented in probably about a month, including audit time. And it's a hook that's in the wild already. It's deployed in mainnet and L2s. And it's powering a lot of our partners' stable pools.
It's already got over 30 million TVL and 100 million swap volume. There's also a couple of links to the full contract code and also a blog post that kind of shows the whole deep dive into the concept and how we went from design to the full product. And yeah, and that's us. Pass you over to Fabio. Any questions so far?
We have the microphone there. Yeah, a question. One, one, okay. Yeah, so thank you for the explanations. The question is, the hooks are there just smart contract functions, so to say, or is there anything, any tech stack on top of that, such as, I don't know, oracles, maybe some cross chain stuff, or maybe some monitoring nodes monitoring something that trigger some of the hooks?
No, they are just standalone smart contracts that the vault is aware of. So the vault calls those smart contracts at those specific points of time in the pool lifecycle. So if you think the LP is going to add liquidity, when that action is triggered in the vault, the vault knows that that pool has an associated hook and calls out to that contract, does the logic, and then returns back into the vault, which will then continue. But you could, from your hook, you could reach out to other contracts as well. So it's like an opportunity for you to do that.
And when you say the vault triggers the action, does it happen when a user does something, or does it happen at some time intervals, or maybe the protocol itself triggers the vault? Probably best to show you, so it's these specific points here, which are all related to a pool lifecycle point. So we have the registration point, so when a pool is first registered with the vault, you can do an action before and after that. When a pool is first initialized, which is when somebody first adds liquidity to it, the same again, you can do before and after. And then also before and after add liquidity, and then the dynamic swap percentage is whenever there's a swap.
So it's those kind of core actions that you can inject your logic into, I guess. Okay, I will continue. We have a second hook to present today, which is the MZCapture hook. This one is a quite simple one, but powerful at the same time. So the objective of this one is to internalize the value leaked from the pool to the liquidity providers, and then redistribute that value loss in between the liquidity providers who have been providing liquidity for a long time in the pool.
Methodology is actually based on a paper from Paradigm called Priority is All You Need, if you have read it. And we use priority fees to identify which transactions are from MZBots. So with that information, that's the signal we use, we apply a dynamic fee mechanism, which aims to internalize the most value possible from the arbitrageur. So this is more or less how it works. So here on my, your left side, we have how it works today.
And I did not mention actually, but this only works on off stack chains, where you have priority fee, a centralized sequencer, which sorts the transactions by this priority fee. And in the first image, you have the arbitrageur, and on the right side, you have the validator, how it works today is the validator receives this fee and sorts the transactions by the priority. And if the arbitrageur manages to perform this arbitrage, it receives the profits from the liquidity providers from the validator. On the other hand, what we are trying to do is adjust the sub-fee of the pool based on this signal, based on the priority fee. So you can try to keep the most value possible within the pool and not send that over to the validator, to the base sequencer, for instance, or on any off stack chain sequencer.
And that value will be redistributed automatically for the liquidity providers, because this can be applied to any fungible position or any balancer pool action. So you might be wondering how you get the priority fee from the block or for the transaction metadata. That's actually not directly available, but you can calculate it. So we have this object transaction and this other object block, and in each one of those, in the transaction, you have the guest fee, and the block, you have the base fee. And actually, that's combined, that's the fee that's being paid by the user, but if you subtract one from the other, then you have only the priority fee price paid by the user.
user. And that's what we are going to use as a signal for the dynamic C calculation. We have a few hook params. That's how we are modeling the problem, and that's how we are going to apply the dynamic C. So, first of all, you have a threshold, or we decided to have a threshold.
And that's the threshold that determines when you start triggering, when you start charging priority Cs. We don't want to charge priority Cs from solvers, aggregators, and retail users, so we have this threshold in order to distinguish between retail flow and arbitrage flow. We have the multiplier, which means how aggressively we are increasing the fee based on the priority guess. We have a max sub-fee percentage, that's a global maximum dynamic sub-fee. That's mostly for safety reasons, but yes, you can just go over and over.
And then you have the exempted senders. Again, speaking of the same idea as for the threshold, we have contracts that we trust that the only flow that's coming from there is retail flow. So, we could, for instance, trust the CalSwap settlement contract and just apply the static fee for them, because we acknowledge that the flow coming from, the order flow coming from their contracts, it's just retail flow. It's good flow for the pool, actually, and it's what makes the LP providers make money. This is what the hook setup looks like.
So we have unregister, on before add and remove liquidity, and you have uncompute dynamic sub-fee. As John showed us, we have the get hook flags, which defines exactly what it said, so setting true for the three hooks default should call. And then upon registration, this is the simplest one. We just have this default multiplier and the default threshold for all the pools, but that's actually also configurable upon registration. The pool owner, the sub-fee manager, can actually change that.
You might be wondering why we need the before add and remove hook, and that's actually needed because that transaction or that operation can behave like a swap, because at balance you add balance every three, you can do unbalanced operation. So I can single-side join a pool and single-side exit that same pool. That's pretty much a swap, and we have to protect against that case. So that's the reason we have this before add and remove. If the kind of the operation is proportional, that's completely fine.
That's just someone joining the pool, but otherwise we'll check if the priority gas price is below the threshold. If it's above the threshold, that transaction will just revert. We will not allow the liquidity provider, likely being in this case an MEPBot trying to arbitrage that pool, we will not allow that. And then the most interesting logic is really the dynamic fee. One thing that I already mentioned, and the first thing that happens on this transaction, on this function, is we check the sender to see if it's exempt of the MEP tax or not.
And in order to do that, we have to use this trusted router function, because anyone can call the vault, and anyone can tell the vault that someone is performing the swap, even though it might not be that person. So we need that sort of routers that we trust that are going to pass us the original sender. They're really the user, the retailer user, behind that transaction. So that's why we use this concept of trusted router. That's the second thing we check on this function.
If it's a trusted router, we get the sender, and then we check if the sender is one of the exempted MEP tax addresses. If that's the case, we just apply the... Go ahead, can you pick up the microphone? So I understood that maybe something like these aggregators would be exempt. You're using the whitelist for that.
Do you set this at the pool creation, or how do you leave it open enough to adapt? Yeah, that's controlled by the DAO. So we have this contract called Bouncer Registry, and then we can whitelist addresses there. So far, we have only whitelisted the CAO settlement contract, because that's the one that is for sure retail flow. There are some aggregators that anyone can call.
You don't have this enforcement, the batch auction that happens at CAO swap. So we did not allow listed any other aggregators, but we did it for CAO, and that's on the DAO's permissions. The Bouncer DAO data, yeah. Actually, the max is on behalf of the DAO, which is a service provider. Can the pool deployer configure their pool in a way to be the controller of this allow list, or is this...
I don't think so. The way it is set up right now, I don't think so. That's for DAO. So how much freedom do the pool deployers have to govern the mutability of their pool after the fact, and how much of it is on Bouncer's side? It really depends.
It's case by case. I would say the pool owner here do have the ability to set multiplier, set threshold, and some of the params, but they do not have ability to set it all. That's the pool type developed by Bouncer. That's what we thought was the best when we were designing, but it could be even changed. Sounds good?
I'm not complaining. No, no, no. No worries. Cool. Yeah, that's it.
That's the beginning of the Dynamics C calculation, and then we go to the function itself, the function that's called by the hooks. That's the calculate swap fee percentage function. The first thing it does is get the priority fee gas price, as I showed you guys. If it's below the threshold, we just return the static swap fee. There's nothing to be done.
But if it's above the threshold, then we take the difference from the priority fee gas price paid by the user minus the threshold, and we multiply that by the multiplier. So that's how we do, and that's how we get the fee increment. So this multiplication will give us the fee increment that we have to sum with the static fee, and that's the fee that will be ultimately charged by the pool for the arbitrageur, We do have a cap, as I mentioned before. So we have this max swap fee percentage. That's why the return of this function is actually the minimum, either the max or the new swap fee percentage calculated by summing the static swap fee and the fee increment.
Just wrapping up, we have deployed this pool, I guess, one or two months ago. It was the first-of-its-kind image internalization product on base, and it also expands balancer image protection to kits. We had PowerAMMs built on Balancer V1 and live on Mainnet and Gnosis, but now we also have this other product live on base, and could be live on other OpStack chains, as I said, but we're focusing on base right now. So pools available on Balancer V3. You can find them on the UI.
There's a filter there. You can find image capture, and you have the contract code, the solid implementation is in GitHub under the Balancer V3 monorepo. That's it. Speaking of the image capture hook, you got a question for the image capture? Yeah, if it's question time, I can wait.
No, no, go ahead. So maybe this is a long-winded question, but we're seeing a lot of launchpads, I don't know, Pump.fun and all this stuff out there now, and a lot of them tend to use Uni-V2 pools because it's super easy, and we see people maybe launching, I don't know, Uni-V3 pools, and it's obvious, at least to me, that Balancer would be the way to go when deploying liquidity because you have some additional configurability or something. But I guess my question was, what configurability does Balancer V3 offer? I mean, we see the hooks on top of all of these commonly used alternatives that give incentive to, say, the pool deployer to use it instead of something super trivial like Uni-V2.
Mm-hmm. But you mean the pool deployer as a developer, a viewer, or someone who wants to launch a token? Yeah, somebody's got a launchpad to launch a token, and at some point, once this ICO phase is over, the liquidity that's been added to the launchpad gets added, it gets deployed to a pool that's, say, technically owned by the launching, whatever address is associated with the ownership of this company, this entity, and it's maybe, say, locked for years, but maybe the DAO wants to have additional, like the actual token holders of the pool that's been created maybe want to have some control over changing these parameters over time. Okay, yeah, I guess we are right now working on LBPs, so I guess I'll start from that. So we are taking LBPs, the liquidity bootstrapping pool, from V2 and porting to V3.
That's a pool designed for launchpads, actually, launching tokens. And what we're trying to do better this time, I would say, is having post-hooks for LBPs such that you have some guarantees that after the LBP runs and the sale of the token happens, migration can easily happen for a new balancer pool. You have some insurance that maybe liquidity will be deposited, locked, tokens burned, like you have on FunPlus Fund, for instance. So we are really into this post-hook LBPs research. Balancer V3 does offer a lot of flexibility for projects to do whatever they want, I would say.
We do have our own pool types, which, like, you have defined parents, like you have a weighted pool which has weights and a sub-fee. You have a stable sub-pool which has tokens and a factor. That can be configured by the pool owner, by the way, if he chooses to do. But he can also, after deployment, the pool owner can do that, for sure, if he chooses to be the pool owner, kind of. Because that's one of the parents of the construction of the pool.
You can delegate that power to the balancer DAO, for instance, even to any contract, really. Or you can keep it for yourself. Or you can even burn it, maybe, set to a random address, like the bad address. And that's it. Nobody will be able to change it anymore.
It will be immutable. It's probably worth saying as well that we also have quite a comprehensive operations site as well that makes it easy for people to manage the pools, create payloads and things like that. And the maxi is always like support people through that as well. Yeah, just a quick one on your question. One other thing that happens is balancer has always been, I want to say, shy on shutting out our benefits compared to other competitors.
And that we can see every time that we talk to a partner and then we show them how good our pools work and how easy it is to create a new pool and how they can tweak the parameters when they're starting it and how different pools we have for each type of strategy. So one of the things that I would mention here is that besides only being easier to use, we're focusing also on shutting out a little bit more on these capabilities. And I think when we launch LBPs, that will be kind of like a no-brainer or easy sell to show how good and how easy you can just switch to a pool. And then even like after that, let's say you go with a reclaim that he presented yesterday. If you're not happy with the parameters, you don't need to migrate to a new pool.
You can just change the parameters. So those are like a few tweaks and things that we can show that. Yeah. I was under the impression that these bootstrapping pools already existed even in v2. Is that not a thing?
That's yeah. It's live on v2. We're taking and porting to v3. Yeah. Okay.
And relaunching and bringing to the balance your UI actually because before we had this external UI running LBPs and we were bringing LBPs home. Okay. So I mean, people who are doing launchpads shouldn't be rolling their own contracts anymore. Like at all. Yep.
Yeah, exactly. They won't even need to do UI because the UI on Balancer will support as well. Yeah. Wow. Balancer is great.
It's also a great opportunity for launchpads because we're providing the infrastructure. You have access to what's happening on our UI, but we'll not be promoting the token launch UI as Pump the Fund does. So we're actually just going to promote our infrastructure that you can use. People can use the contract by themselves, by their own product. But if someone wants to create a UI and create a launchpad and use our protocol, that is fine as well.
And they can use all the structure that Balancer offers on their own UI. They could potentially make money off that as well. I think that's something we forgot to mention maybe. But in Balancer v3, we do have a pool creator fee. So upon registration, you can set a pool creator and take your cut of the top fees generated by that pool.
So there's an easy module for builders and developers to just make money building Balancer. Thank you for the question. Yeah. Moving forward. Last slide, I guess.
We have a few grants up for grabs. This is all hooks. Yes. This is all hooks. So we have been revamping, actually, the grants program.
I'm leading it right now with Mike B. He's not here, but he's my partner. And we had three ideas that we would like to see built in Balancer v3. First one is size-based fees. So charge different fees based on the volume that trade is producing that potentially involves some integration with oracles or something like that.
Because you do have to have a notion of price in that case. We have permission pool. Some kind of projects have already reached out to us asking for a solution to have permission swappers or liquidity providers. There are many ways to build this, actually. You can use attestations.
You can just hard code a bunch of addresses in your contract. But yeah, you have to come up with a good and scalable solution for this problem. We're just throwing a few ideas out. And then the last one is directional fees. So that's the idea of liquidity providers being able to adjust their spread based on the price of the token and the volatility of the market.
So that's the third venue for exploration. This all can be done via hooks. Specifically, dynamic fees, two of them. The permission pool would be on before swap, on before add, remove liquidity. As you have to check the sender, you probably have to use the Terasys router, as I was showing you guys.
And yeah, those are our two ideas. That's my telegram. Feel free to reach out to us. It's the first time, I guess, we were talking about these ideas. But we'll probably do a push on Twitter.
You might see that there as well. But yeah, feel free to get the alpha and reach out to me if you're a builder and want to do that. So what's the process to participate in these grants? Do we put up proposals in a forum first? Or do we just start forking the three contracts?
No, talk to me first. Reach out to me. We need a proposal for sure. That proposal does not have to go to the forum. We have a grants committee, and you can submit a proposal to us.
We don't have a clear format, I would say. It's more about getting to know your background, what your proposal in terms of deadlines and ask, in terms of budget looks like. And then we'll set up a group and chat and figure it out. Do it. Yeah, so in terms of this grant program, how are we supposed to build purely on your stack?
Because the ideas I'm getting is applying our Infratech stack to your hooks to possibly enhance the functionality. I did not get it. Yeah, so the question is, are we supposed to build purely on your tech stack, or can we add something else on top of that? You can, for sure. Like I said, the size-based fees can be probably built on top of chaining or codes.
For the directional fees, you might need some sort of pricing data as well. For the permission pool, it could be built on top of the stations. You might have heard of it, but yeah, it's built by the EIS team. But for sure, if your tech contributes to any of those problems, right, like those are problems we have, we want to find solutions to them. If you can help us figure out, I guess that's great.
Is the full list of the problems, are there some open? These are the three we're putting out there. I actually managed to just have this short list of six yesterday, but I prioritized those three, just a smaller one, easier to scope. We don't want to create huge projects at the same time, so we are starting slowly and then potentially growing. And yeah, getting the community to get these ideas done and do some outsourcing.
Yeah, thank you. Is that the last one? Yep, any other questions?
Automatic transcript — names and jargon may be misspelled.