New Ethereum talks, every Monday. The week's conference uploads by event, in your inbox.

Loading player…

Default: A Design Pattern for Better Protocol Development | OlympusDAO | ETHTaipei 2023

ETHTaipeiMon, Oct 9, 2023, 12:00 AM

Transcript

[Music] hi everybody [Music] uh my name's fully um I'm Indigo and we're smart contract developers at Olympus style uh and we're here to talk about a framework that we've been working with called default and it's for how to design smart contracts um okay so uh why use a framework and like what is a framework so if you start writing code most of the times you're not really thinking about the longevity of your code base or how you're organizing the different components of your logic and when you're beginning you know your your project it's not a big deal because the scope is very small you don't really have a lot of features you don't have a lot of external dependencies so it doesn't really matter how you know you organize your code but as the code base grows as you add more developers as you have more Integrations things can get very messy very quickly and you know if you're building in more features eventually you end up with a very messy architectures and sometimes you don't know like where you can find your logic and things can get very ugly so we use a framework to increase like readability of code to make it easier to access for developers and over the long term it should make development uh you know faster cleaner make the code more readable and things like that so um if you look at these two diagrams don't get too intimidated but this is a lot of what you know architecture can actually look like so if you're a smart contract developer you're working with different protocols um and you're trying to do an integration a lot of times you actually end up you know looking at systems like this and you're doing it from scratch um these are diagrams of architectures of protocols that we probably all have used or at least know the one on the left is maker Dao and the one on the right is Ave or like versions of them and so you know if you've ever done like a yield Farm or you know some kind of like lending integration as a developer and you're looking at these systems it's very hard to understand like where you have to call the contracts what happens if you know you hit this one it goes here it goes there it's very easy to get lost so the idea behind our framework is to create a very clean and organized pattern for the system so that if you you know call this contract you know exactly where it's going you know exactly what it's doing and it's very easy to find for both you for your internal developers if you're working with a team for external Partnerships if they have to integrate with your system it just makes it a lot cleaner and a lot easier for everybody uh so this that's the goal and and actually maybe I should go a little bit over how this happens is like um it's a very natural thing so I I want everyone to know I'm not criticizing this architecture you know when you're when you're not using a like a um a framework to design your code it's very easy to use just processes uh you know one by one and you kind of like add them together and you chain your logic right so maybe you have like a lending system and you have a lending pool and then the lending pool has like a manager a lending manager and the lending manager has like an asset controller and the asset controller has something else and so your your brain naturally thinks like this uh it's very process driven and the problem is you know you want to add a new feature then you have this new manager this new controller this new thing and you just stick it in you know to the next part behind the chain and next thing you know you just have this whole web so what we want to do is we want to take a top-down approach kind of a more holistic idea of what are the different parts of a protocol that are important for us to develop and then how can we categorize them into you know an organizational like structure for our logic and this is default yeah so you can kind of see the goal is to condense the architecture turn it from a web where you have all these different you know unconnected nodes that all connect to each other to kind of a stack and with the stack you know at the top you have these policies in the middle you have this kind of Kernel this controller and then at the bottom you have modules uh and then yeah I'll let Indigo talk a little bit more about what each of these do and kind of how we how we use them at Olympus yeah so uh the first implementation that we made of like this this framework is Olympus V3 we did this uh I think a year and a half ago and um we've been working on it slowly so um so this is actually the Olympus V3 initial version so the first part of the default is the kernel which acts like a central registry for all the contracts uh policies and modules all register with the with the kernel that we have modules which are um like uh State Stores of any any state for the protocol is stored in the in the module and anything that's shared across uh the protocol so you can imagine like a treasury a mentor contract anything like that is uh primarily a module and then lastly we have policies which act like user interface for the protocol so like a vault contract anything like that is is a policy so the kernel is uh primarily restricted down to six actions and this is what allows us to to um to stop the uh the growth and of complexity that we see in like the maker and the Ave contracts so as you can see there's an install and upgrade module there's activated deactivate policy there's change executor and migrate kernel so the first two are just for installing and upgrading modules uh this is very simple as you guys know changing out contracts is always necessary activating deactivating policies so policies are kind of act like uh you can think of them like scripts almost or things that are uh they're like completely immutable if we need to change a policy we just deactivate it and change it to something else and the reason why we could do this is because the state is inside the module so we don't have to do any kind of like migration or anything and then lastly we have the change executor so the executor is primarily the governance contract or the multi-sig that's uh has control over the protocol and uh this just allows us to change out who's who's in control essentially so for now we have a multi-sig that's our executor but when we deploy our governance contract we will change the executor to from the multi-sig to the governance and then lastly we have the migrate kernel is just so in case we need to change the uh the kernel or if there's a bug or something we can change it out okay so this is the module contracts and I apologize for non-devs uh this is like this is a presentation for devs but I'll try to explain it like in an in a non-technical way so the modules act as like internal State stores for uh for the protocol so and we denote these modules by key codes which are like just five five letter uh five letters to just you know just so we know exactly what we're looking at right when we see the module and when we upgrade the module we keep the key code so you can almost think of it like how uh proxies are done for upgradable proxies you have a proxy that points to an implementation it's very similar conceptually to that so the module is um it's just shared State um it's generally very simple so like an example of a module that we have is the treasury so the treasury holds assets and uh it literally just holds assets so any kind of logic for the asset of like allocating it to a different protocol uh farming it or like trading it whatever that would be implemented in a policy above but the state of the asset stays inside the module so a module is pretty simple policies are where we encapsulate a lot of the complexity of the protocol so we try to do any kind of uh as I said like swapping allocation of assets um this this policy is this is the most complex one we have in Olympus it's the operator policy if you guys know what uh what we do we have a apologies I got it um uh we have a we have a bunch of Assets in our Treasury and what the ask what we do is we use the assets to defend the price uh of of of ohm so when the price is above a level we we sell ohm and when the price is above below a level we buy ohm using our treasury assets so um as you can see here I don't know if you guys can see in the back but uh we have four we have four modules that we're pulling in so um one defining feature of default is that uh and one of the biggest things that we wanted to emphasize was that when a policy gets installed you know exactly what you're looking at and what you're getting right when you look at it when right when you install it in so um right up front this is the main two functions you see that we have four modules that we need and then we know exactly what functions the modules are calling right when we right from the start so this is very different from like integrating a different protocol where you don't know exactly one call is calling what like how many levels deep it goes how many different protocols it's calling uh nothing like that we know exactly what we're what we're looking at and what we're getting right when we look at the policy so yeah we uh pull in the four modules and then we have the functions that we're calling right below so just uh to go over some examples of the Olympus V3 code base is obviously very simple to look at the core of the the core of the protocol is just the the treasury and the mentor module below so the treasury as I explained before is just a asset store for the protocol and then the mentor is how we actually mint the token if we need to and then we have a treasury custodian that's like a policy that just manages the treasury contract in case of like whatever issues that we need sometimes we have to do a swap or something like that so that's what we use the treasury custodian for um so the range Mount stability is what I was uh what you were looking at earlier on the policy Slide the range Mount stability is the contract that actually does the price controls for the token and um as you can see here it's like very easy to understand like okay it's four different modules on the bottom and there's two up here there's a bond callback and the operator these are the policies and these are the entire entire system is this like uh the system is like fairly complex but it's very encapsulated into just those two policies up there you don't actually have to worry too much about like what's happening on the modules you just look at the operator you know the functions are very um very clear so you look at the operator you know exactly what it's doing this is very different from like other code bases I've seen where I don't exactly know like how deep the call stack goes or anything like that it gets really complex really fast so um and then yeah fully over governance can you guys hear me cool yeah on the governance side um also very simple so we have our entire on-chain governance system encapsulated with these three contracts uh for the modules we have votes and instructions uh votes just keep a track of how many votes an address has so it's just a voting balance um you like erc20 token that's non-transferable instructions are just the actual like executable code for the proposals in case they get passed so what is actually going to get called and they're all kernel instructions right so it's like the proposal could be install uh or upgrade the treasury install a new policy and do something else and that will be a proposal that gets stored as an instruction and then the actual business logic around like the governance the voting um the consensus mechanism when does a proposal pass how does it pass what's the Quorum that all goes into the governor and so if you want to change your governance logic business logic like okay you know we want to change the way we count votes maybe we want to uh you know have a super majority instead of just a simple majority maybe we want to use like a Delta you know voting system instead of just like a majority voting system those are all things where like you don't have to touch the vote the erc20 votes all you have to do is say okay disable the old Governor policy activate a new governor policy put it in and all of the dependencies will automatically link so it just makes upgrading the system a lot more clean a lot manageable and uh and also in my mind a more transparent yeah so um we we experience this a lot right where like we want to change how our systems perform uh you know functionally speaking but when we do it it's very hard to like move things in and out you have to unplug and plug a lot of your dependencies and so we kind of developed this way for us to be able to you know upgrade our business logic uh you know without having to manage a lot of the um I guess it's like devops side but yeah web3 devops I don't know but yeah all right so uh we didn't we did we gave this talk in November uh when we had just first launched Olympus V3 and it's been like months since and so I just wanted to share some of the things that we've learned and uh like what actually we're working for towards and why so um one of the biggest things that happened was that uh because the because the system is like so modular we actually were able to do like almost six different uh development efforts in parallel which is um I if you go from like web 2 or like a different uh field of software engineering this is very common but like it's not something we generally get in contracts development because everything is like so tightly coupled because we were able to uh separate all the logic and everything we actually had like all these different things going on at the same time and there's very little like like oh what uh you know are you using this contract are you changing this it's not like that it's very easy actually to work as a as a larger team but we didn't even realize like how nice it is we at Olympus we have like maybe one weekly stand up where we just go over what we're working on and each dev has like a completely different like feature uh on their own you know some guys doing like an accounting system some guys doing governance some guys doing like uh aggregations or you know liquidity vaults and all we have to do is say like yeah this is what I'm working on the cost of coordination is very low because of the way that yeah we like have this structure I don't know so um the other thing is that we have like the code base is extremely easy to understand uh we've heard this from like multiple people from Auditors from other people who've just looked through our code and uh that's like as a Dev is a very nice thing to hear um but actually the biggest goal that uh fully and I the reason why we wanted to implement this architecture was because our vision for con for protocols is actually to be like truly truly decentralized not to have a dow that's like an org like a pseudo Corporation organization that's like managing contracts with multi-cigs and stuff we actually want the whole system to be completely decentralized where anyone can just come in plug into the system and all you have to do is like convince voters you don't have to convince like the BD team or the Partnerships team and then tell the devs to integrate your contracts like no we want you to be able to write a contract you propose it as a proposal and then it goes to the governance system everyone sees it everyone's able to understand exactly what it's touching what it's doing the Auditors are able to audit what it's doing and then it just gets voted on and then it gets added into the system I don't think we have anything like this right now and this is one of the reasons why we build this system and we know it's not perfect there's a few things where there are some challenges with it but I think the system is like it's the first iteration and something that actually leads to like a true doubt all right I think we can open it up for questions uh thank you a wonderful talk and then uh well since you mentioned the challenges I want to like if you can elaborate on those like what kind of challenges that you already see right now and perhaps what what are you thinking of how to address them okay he asked what challenges we're facing so the challenges we face right now is like uh sometimes there's a little complexity um because the structure is like you know one one stack deep sometimes you want like more complexity in like the modules or and you don't really know where to put it um so we uh we've been thinking about like uh adding a third layer to the system at some point um that's for like data aggregation or things like that we're trying to really solidify exactly the use case before we go to towards that um do you have any yeah sure so like I can give a little more detail uh it came in with the on-chain accounting system but uh there was something where we needed to use data across different modules but we didn't want to abstract it into the policy because of a way that we were doing a callback and so we were thinking like okay do we allow something because modules normally cannot talk to each other they all have to go through policies but this is just purely for like data aggregation so we're like do we make an exception do we not and we went back and forth and so the solution that we're exploring is actually uh what Indigo said like a third layer and the third layer is a query layer a query contract that basically just uh gives you a read value with business logic and then it might have its own kernel actions and that way you can just upgrade that without having to worry about anything else and the benefit I see with this is actually very similar to how we think about upgradable proxies where like we can keep our policy contract addresses the same and then you know if you want to change the calculations for your bonding curves you want to change like you know your slopes or anything like that you can just change the query contracts and you don't have to touch the policy logic or the data models and yeah it should work so this is currently in development so I'll just add um the other thing is that the system obviously since you're splitting the logic across different contracts you'll have like more gas costs trying to call if you're calling like tons of different things but I will say that like when you're calling a module you know that it's not calling anything else so it's just one single external call right um and uh what's up okay uh so yeah it's just uh it's just it's not actually as bad as like people think and also uh one thing that fully and I decided was like we don't want to design for the current constraints we want to design for a true system that can work with like future constraints which I think gas will be a much lower in the future and like I don't think it'll be as much of a problem uh so I I really like the idea of uh anyone coming out with a proposal to just um stitch together these modules to to basically implement the proposal are you guys uh have you guys thought about like a tooling at a meta level to for non-coders to just like uh stitched together modules and then you know that turned into that generates code and you know that that turn that implements the the proposal and that way it's also uh easier for the community to know that a proposal is implemented correctly yeah I actually got this so um two things I want to say actually one is uh yeah basically like uh you know we hope that if anyone wants to use like the Olympus liquidity or treasury for their own project uh you don't have to go through anyone you don't have to go through the Partnerships team and know someone and say hey can the dev set this up can you get this so um we're actually going to Pilot an on-chain uh governance uh uh demo and we're going to deploy a copy of the protocol and we're going to inject it with you know uh some incentives I don't know exactly how much but it should be like decent size and the idea is anyone can come in and buy votes and use it to submit whatever they want and we'll just kind of see what happens but the idea in the future is uh we can actually create like policy factories so maybe someone from an Olympus team or someone else can say like uh this is a template for you know pulling liquidity out and using it to allocate it into a farm and the uh that might just be like a vault structure or it might be like uh you know some kind of template and then you all you have to do is like initialize the Constructor with like this is the target address this is the allowance that you can get from the treasury and so then we just have to look at like okay based on the you know parameters that you put into the contract um this is what we know it's it's doing and then if you even if you don't know code and you say well I have an idea I want to do like an allocation system for the treasury uh then you just have to deploy a copy with you know what your target variables are and it should all go so that's something that we're thinking about I I think it's going to be a little bit ways out because we have to make sure that the governance system and everything is more mature but yeah in terms of safety and accessibility like the whole reason um as Indigo was saying the philosophy behind this is so that everyone can participate in protocol governance and feel like you know as a stakeholder of this system they actually can make a decision about where the money goes and what it's doing um and I I don't feel like you know we have a lot of protocols that give us that feeling today all right next question from this fell yeah just one question regarding the interaction between the different contracts are they are they each like deployed separately and have their own storage and just have like normal calls in between or is it like delegate courts or some kind of shared storage it's just regular calls for example yeah no delegate calls in the entire system not yet yeah so everything is explicit flows yeah it's just called it's just regular calls um so uh the way that it works is that the red uh the kernel is the registry so like anything that needs that dependency it just requests that dependency from the kernel so we know exactly um so the kernel knows exactly what it's sending to the policy that's requesting it but yeah it's just a regular call yeah so each one of these is actually deployed separately so when we like deployed our system or if we're trying to like you know test it um yeah you just deploy the operator policy deploy the button callback policy and then you go through each kernel action and you say like install this install this install this approve this approve this approve this and then like then you get the system in completion it's actually uh it's funny because like we didn't actually use like any fancy anything there's no delegate calls there's like uh we didn't actually use like much assembly there's like uh all these other Frameworks use like Dynamic routers and all kinds of craziness like we actually the system is like dead simple if a new Dev looked at it they would know exactly what's going on very very fast all right I think we can take final question if there's any we're gonna have another five seconds all right nice talk it's my blowing for me I enjoyed it so thanks indigo [Music] [Applause] [Music]

Automatic transcript — names and jargon may be misspelled.