Yearn V2 Code Review - Solidity Code Review

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right awesome what's up i'm alex entrepreneur setting up a new live in which we're going to go over um wiring version 2 if you have any question on the technology on solidity react hard at subgraph etc let me know uh and i'll also give you some context as to why i'm doing the code review on wiring today and i have you in the chat here on the right so the reason why i'm doing this is i uh share my screen the reason why i'm doing this is i'm building a little uh tool that uh uh basically uh yield farms and so i'm basically teaching myself uh this so that's my goal it's education purposes with the goal of building something uh for myself that i'll uh eventually share that said um why uh would you want to learn from wire is very simple when you start writing your own script such as something that i wrote you have perhaps a deposit function a withdrawal function and then maybe you have something to invest what's going to happen is you're quickly realized that you basically built a monolith which is what my case i built a monolith and all of this code uh is tied to a specific way of uh yield farming in this case this is tied to ave on polygon so i know you guys are out there uh out competing to ship this uh yield farming product we i'm uh i'm checking on you guys in between the way in which you do a deposit and uh the way in which you do the actual uh balancing the harvesting the farming etc and uh that means that this uh this is great uh you know as a solo investor if i invest my own funds this is great it's going to automate all the process it's going to give me all the stats it's going to rebalance it's going to do all this nice stuff so it's great however if i want to build this into a product that other people can use or i want to maintain this in a way where i can have different strategies because in a couple of months ave and polygon are no longer going to subsidize uh with wmatic so i basically need to build this with some extensibility in mind and that's how the wiring v2 was built which is i'm going to start zooming way deeper i checked the previous video and i realized that it's really hard to see so i'm going to actually zoom way more in this uh version and um if you remember in the wire v1 uh we basically had three keywords we had the vaults controllers and strategies and in ymv2 we basically get rid of controllers and we only have uh vaults and strategies so i'm in the yearn vault repo which is the ripper for uh wire and v2 or you're in vitro i'm gonna go in the contracts folder and you'll see that we fundamentally have just a few set of uh viper uh scripts and then we have a couple of solidity uh scripts these are highly documented so uh they're actually really well written and uh so we're i'm going to be learning a lot as i go along and you're going to be learning as well uh let's start by looking at the vault viper uh code for the vault and uh blah blah blah vault open source there's also an emergency shutdown let's actually read this over one token vault holds an underlying token and allow users to interact with the wire and ecosystem for strategies connected to the vault this basically gives you all the the context the architecture etc for what's going to happen we expect to see strategies which are going to be all the smart contracts that uh manage funds while uh we're not going to be uh uh and this the vault is just a way to deposit that next up we have uh let's see vaults are now limited to a single strategy yeah they can have up to 20. the positive funds are moved into the most impactful strategy that has not already reached its limit for us it's under management regardless of which strategy user funds end up in to receive the personal yields generated across all strategies okay so that's great and that means that there's going to be a generalization or a way to uh let's say more strategies of a portion of funds there's gonna there has to be a way to calculate uh which amount each strategy has and uh how that's going when a user withdraws if there are no funds sitting undeployed in the vault the vault withdraw funds from strategies in the order of list impact which means that funds are taken from the strategy that will disturb everyone's gains the least then the next list etc so again here i'm expecting that there's going to be a way to estimate uh the yield that each strategy is gonna um uh give and that's probably gonna be weighted in with the amount of funds that are available in each strategy so there has to be some sort of sorting way that makes withdrawal easy and that's something uh that uh is actually really uh helpful because in a naive way when you're building your own strategy you're probably gonna just unwrap and withdraw everything because to actually do the math to uh you know not impact other people funds uh is actually uh uh is actually very sophisticated in order to achieve this the withdrawal skewed order must be probably set and managed by the community through governance okay so that uh that actually uh defeats uh the you know i guess we're gonna use the i've mind of the uh the the governance instead of writing a a scripts that does it and um so we'll see what actually happens but um yeah this is actually a real uh challenge is that uh you want withdrawals and deposits to be cheap you want them to be easy to do but you also want to be able to rebalance this uh vault uh and strategies automatically so you have to find a compromise and i'm guessing the compromise here is using governance because how will the strategy and the vault know which uh how much yield each strategy is projected to do uh which i believe could be done i just it's probably an ingenuistic challenge and maybe this is going to be part of uh an improvement on wiring or urine let's continue both strategies are parameterized to pursue the highest risk adjusted yield so that means that there's going to be some sort parameter that has to quantify risk and then we're gonna have to compare that with yield because expected yield is something that you can always uh get let me give you the most basic example would be ave and maybe there's like a few bucks on this developer wallet but fundamentally if you go on avi you'll see that uh you you know exactly how much you can gain from each uh deposit on withdrawal and borrow like it's uh it's uh there like there's no so this is all in in the smart contract and you can calculate it however the risk the part the risk part is probably something that uh has to be done by a human being it has to be done either served by our oracles or by a trusted third party or again it may be served for governance so that's also something that we'll explore as we continue let's continue there's also an emergency shutdown mode this is probably a great idea to have even though you never want this to happen but uh especially when a code uh has been uh you know it's just a very uh young uh you probably want to have a way to just reimburse everyone um manually uh because the idea of locking everybody's funds and burning them is probably worse so uh you know you have to basically balance that out with the risk of being rank pulled when the vault is put into emergency shutdown assets will be recalled from strategies as quickly as is practical given on chain conditions minimizing loss deposits are halted new strategies may not be added and each strategy exits with the minimum possible damage to position while opening up deposits to be withdrawn by users there are no restrictions on withdrawals above what is expected under normal operations okay so basically we're gonna have this emergency shutdown um lens and i'll try to separate that from the ordinary code because to also deal with an emergency shutdown contingency it's just going to make our life so much more complicated and uh in terms of the difference between solidity and uh viper uh and there are many and uh uh you know but fundamentally we can just uh say audio code uh read it up say the code so even if even myself i'm not a viper coder at all so but i think we can live with that so here we have a version set to a string constant which is 0.3.5 we're importing here c20 we're and we're also extending that interface which means that it would be the uh is keyword and solidity we have an interface that specify what a detailed erc20 is and it's just name symbol and decimals and since we're in the vault we expect hey arom are you doing so we basically expect this uh to be the uh just the specification of the token representing your ownership of the pool so um and something interesting about this let me show you uh what i wrote in my own code but when you're dealing with withdrawals something you want to keep in mind is how do you reimburse a person based on what they earned and basically what they what you owe to them and so uh you probably will have to do either a uh percentage you're gonna have to calculate a percentage in this case i get the total value that is locked in the contract i multiply by the amount of tokens that the person wants to withdraw and i divide that by the total supply of tokens which means that i get the percentage and i base that on the total value that i have in my contract and that may be one way of doing it although uh another implementation which is as valid and uh you can see that in ave is that the tokens you own represents the exact corresponding collateral so you always have a one-to-one conversion because your token increase with time they literally if i go back on ave and i go here even if i have like a dollar you can see that the number goes up it goes up every two seconds because every time a new block is issued there's some sort of parameter in avid that goes up and that uh means that uh the uh my balance goes up it literally goes up uh uh it's it's actually beautiful to watch and if i um redeem that balance i will get back the exact amount of collateral so there is no percentage being calculated uh they're uh it's done in a different way however a more naive and faster way will be to use a percentage so we'll have to keep our eyes on that next up we have the interface for a strategy this is a uh we're gonna go into strategies and that's how you separate your code between vault depositing managing funds and strategies actually actively using the funds to get yield so we'll have to figure it out but basically we have one which is going to return the address of the uh token that the strategy wants to accrue more of it's gonna then have a parameter vault which is going to be the address of the vault that the strategy is assigned to it's probably a good idea to have each strategy be attached to a single vault which is going to again in the case of withdrawing it's going to make your life so much easier instead of having a strategy that could be used by multiple vaults uh which means that uh some strategy may not have enough funds next up we have is active it just checks if that's working delegated assets uh it's probably no this is a number delegated number delegated assets is a number we'll have to uh see what that is but uh i'm guessing it's probably the amount of funds that have been given so the amount of want or the amount of uh tokens that have been sent but i'm not sure we'll have to figure it out next we have estimated total assets i'm guessing again the amount of uh balance that the they own then we have the act of withdrawing it's going to be a function that receives the amount and he returns a number basically just withdrawing and migrate which migrates the funds from one strategy to the other the act of migrating you can interpret that and i go back to my personal script the act of migrating you can uh see it as the act of taking all of your money in my case i'm taking all of my money from ave and i'm repaying all of my debt so if you see here i have literally a loop which will cost you millions of gas so it's definitely not uh cheap but on polygon will be cheap uh but basically you can loop over until you withdraw everything and then you can do whatever you want you could you can migrate your funds so uh i'm assuming the migrate function is going to play a core role in uh getting funds out and putting them uh there and i'm not seeing an amount which uh uh is interesting but again we'll see but this leads me to believe that migrate will literally take all the money and put them in a new strategy next we have guest list interface that defines authorized guest address amount we'll see what this is we have the transfer event approval event these are erc standard events name public yeah erc you're see this is all of very familiar if you uh ever work with a near c20 contract and then we have the uh and i love how they separated it this shows like a nuance on the software engineering level it literally shows like a step up from trying to just code something to actually building it uh in a way that is maintainable they grouped up the the the basic erc stuff the uh the number stuff related to uh numbers and then the governance stuff or the uh management and admin stuff so i just like that just i think it's cool it's a nice touch then we have the strategy params and this is defined as a struct we have the performance fee defining basis points and i never remember what basis points is bps uh as percentage i think it's one uh hundredth of a percentage one basis points is zero point zero one percent one hundredth of a percent yeah so it would be one basis point is this number right here zero zero zero one and this may actually explain why we see ten thousand when we're dealing with uh uh is it gonna be ten thousand yeah i think ten thousand so that that explains why you see ten thousand because we're dealing in basis points uh and every time you deal with finance that's the the scale uh but you know engineer as an engineer you have to get used to that just like as a normal person you have to get used to arrays starting with zero instead of one because you know computer science anyway you have activation this shows a block timestamp so i'm guessing it's a way to block or you know prepare this strategy before actually publishing the debt ratio this is really interesting the maximum borrower amount so the debt ratio basically anytime you're doing yield farming you always have a uh you will most of the time have that to deal with that because nobody will just give you money for free like uh that's not what's happening so you you need to have a very um practical understanding of how uh you would uh farm manually in order to uh start understanding what uh why iron is actually doing but fundamentally uh you you always have to take a loan in order to be able to uh to to make money it's just like uh buying a house so that you can rent it you're buying the house you're doing the mortgage so you can rent the house and the debt ratio will represent how much you can uh how big of a house you can afford or how big of a house you're willing to afford uh before uh you're just gonna be like okay that's that's enough that's too much then we have mean debt per harvest lower limit of the increase of debt since lard last harvest so this brings a key word harvest which is a key word that in the yield farming space is a very uh widespread and i also have a harvest dot finance which uh literally takes that name and uh the rs function i i i genuinely i'm not sure exactly of what it's supposed to do but the harvest function is a function that you always find in all of these contracts and it typically either reinvests or it takes the profits and then it does something with them so i'm not exactly sure of what exactly we'll do but as you can see we have parameters that uh basically deal with increasing or reducing debt which basically you can see that as leverage where that is a way to either make more money or uh reduce your risk then we have last report last time a report occurred i think this is due to automation we'll see that later then we have the total debt total standing that's the strategy has yeah that's good total gain total returns that the strategy just realized for the vault and then the total losses which are the uh everything that was lost for the vault and we have these as totals which means that they're not relative these are going to be uh absolute numbers so we'll see what happens there next we have the strategy added and that's just the event for saying that it was added strategy reported it uh takes a um it actually indexes the address of the strategy and then it shows the gain the loss the debt and then you have the totals so the events actually will show you the uh relative gain and relative loss while the rest of these parameters will not then we have uh governance update governance with this address yeah just just the governance update management guest list rewards yeah these are just two events for changing management fee guardian shutdown withdrawal queue so we'll see what this withdrawal queue is but i'm assuming this leads back to uh the fact that the governance is able to change the uh withdrawal queue ordering which means that uh each strategy will pay out first when uh you need to withdraw next we have the strategy update that ratio uh this is the act of the event that triggers when you change the debt ratio strategy update min that per harvest this is just changing the minimum data this is changing the maximum debt the update of a performance fee and this is the act of migrating to a new strategy so this brings back that keyword migrate and at this point it's leaving me to believe that migrating a strategy is not just moving your funds from one to the next but it's actually moving the funds from a version of the strategy to the next version of the strategy and we'll we'll see if that's the case as we continue then we have strategy revoked i'm assuming this just blocks the strategy removed from q this removes it from the list of withdrawals and add it to the queue which adds it now we have a note track the total for overhead targeting purposes then we have a list of strategies which is gonna map between the address of the strategy and then the parameters okay so this gives us we means we're gonna uh use the address of a strategy to get back to strategy params which show us all of the configuration the debt the um the loan the totals etc then we have the maximum number of strategy which is 20 and this is a constant so it's a social contract and uh you know it's actually hard coded in the contract so this is what it is degradation coefficient not sure what this is but uh 10 to 18 is basically uh one if let me see then we have withdrawal q which is gonna be a um list of addresses that contains the number of maximum strategies so this is a list of 20 addresses and uh let's see the comment ordering that withdrawal uses to determine which strategies to pull funds from it does not have to match the ordering of all the current strategies that exist but it is recommended that it does or else withdrawal depth is limited to only those inside the queue ordering is determined by governance and should be balanced according to risk slippage and volatility can also be ordered to increase the withdrawal speed of a particular strategy and then the first time zero address is encountered it stops withdrawing so again this is this means that um and this may be a great pattern for uh saudi developers is that anytime there's an operation that is too complex and but you still need it you may as well just have it done by governance so somebody else has to has to do it and it also is flexible so this may be a better way than having an upgradeable contract that nobody's gonna trust uh so that's pretty good that we have the emergency shutdown deposit limit which is the maximum amount of volt can help the debt ratio we just uh saw it bps less than equal to 10k because 10k means uh uh a hundred percent that and uh you know you can't go over that although if you look at uh something like you'll see that the actual loan to values where loan to value is the amount of money you have to put in for the amount of money you can get out most of the times the loan to value is going to be something like 50 or 70 percent which means that for every dollar you put in you can actually only borrow 50 cents on the dollar so uh you would expect that this number right here will uh reflect uh the uh strategy and the actual uh protocol that is actually to be interfacing with we have total debt the amount of tokens our strategy are borrowed last report blocked the timestamp activation block to timestamp locked profit how much profit is locked and cannot be withdrawn we'll see what this uh has to do but we'll see again locked profit degradation rate per block of degradation degradation coefficient is 100 per block then we have rewards which is the rewards contract where governance fees are sent to governance fees are sent to the rewards contract that's okay and that's actually an emerging pattern that i'm seeing basically you're gonna call rewards is the uh contract that uh the token holders will receive rewards from either by staking or just by passively holding or stuff like that and uh i'm sorry to see that a lot governance fee for management of vault given to rewards again the management fee and then you have the performance fee apparently given two rewards as well so you have these two fees and uh if i'm not mistaken in the uh previous version of iron they were uh they were zero there were 50 basis points so 0.005 for uh management fee and then the performance fee was something like five percent on the extra profit and uh this was done the performance fee was available only for uh active uh strategies such as flash loans or uh uh arbitrage strategies we have max bps again uh the basis points we it's ten thousand this number you'll see a lot every time you deal with finance it's ten thousand then we have the seconds per year and this probably has to do with the uh we'll we'll have to see actually but yeah this is just seconds per year as uh again as a number with an actual explanation and this actually makes me think of a video by tom scott if you want to check that out is tom scott loses his sanity you should he shall definitely check this video out this video talks about dealing with uh time zones and uh uh the time so this video is awesome i highly recommend you check that out tom scott i actually had the same reaction when uh when i started working with time times so uh yeah uh then we have nonsense i'm assuming i subtract the permits then we have domain separator it's just gonna be a pearly string to just uh for for the name domain type hash we'll have to see what this is used for but this is cacao 256 of eip712 domain let's check quickly what vip 712 is ethereum type data structure for dashing and signing yeah so basically the eip712 allows uh the uh software wallet server wallets to actually show the structured data and uh it also makes your life easier when you're dealing with signatures so uh perhaps uh once i start doing some nft stuff and if you're interested in the nft stuff let me know in the chat or in the comments but once the permit type hash and this is basically the hash of the permit function that is allowing given the owner it uh allows us a reward parameter and management parameter then the name of a ride the symbol of a ride and that's uh uh just to our code an actual number and that we have the guardian set to an address that is equal to message.sender so guardian will have to see what it is but most likely guardian is somebody that can um can probably do a lot of interesting stuff let's see initialize is the vault this is called only once when the contract is deployed the performance fee is set to 10 of yield per strategy the management fee is set to 2 per year okay per year that brings back that um seconds per year because now you can actually calculate uh what what each block is worth in terms of uh that then we have the initial deposit limit is set to zero the positive disable it must be updated after initialization if you name override the name will be yearn combined with the name of token if symbol override otherwise you get the y which is normal we have a parameter called the token governance rewards management token the token that may be deposited governs the address of the authorized uh that is authorized for governance interactions rewards is the others to distribute rewards to management is the others of the vault manager we haven't seen this manager keyword pop up too much we'll see it probably with a um modifier later and then we have name override symbol override and guardian the guardian is the others authorized for guardian interactions which the false factor is one okay and uh normally you never go above 18 uh decimals uh although i've seen projects that did and i think they got mocked on twitter it was actually uh funny but you know it's just this mugginess of twitter where you get mocked for having uh more than 18 decimals so we have the governance we're just setting all these variables up nothing uh particularly complex here and then we also have these uh domain separator variable set to the uh catch 256 of the domain apache wiring vault and again this is for uh we look into more uh gasless stuff api version returns the api version set name changes the name of it requires to be done by the governance and it's changed the name set the symbol it allows you to change project change symbol uh after they launched but uh yeah i guess next up we have two-phase commit for changing governance set governance uh we receive an address it has to be done by the governance and it will set the governance to pending and then all right so this is actually uh cool so in a way in order to change governance where governance is uh the uh address or the multisig or uh the contract that can actually manage a bunch of stuff they chose to have a two-phase commit which means that the first time you're gonna call set governance and you will set this pro this uh uh property called pending governance to the uh governance that he was received so he will set it as pending and then the pending governance has to make a request because that's what this says and he will then set the governance to the message.sender so uh the governance has to be accepted by the other uh side as well which may be um um yeah i mean it's just the way to do it i guess it probably avoids mistakes or something like that next up we have set management changes the management address management is able to make some investment decisions adjust parameters and um yeah so that's what the management does that we have the guest list let's see a guest list is another contract that dictates who is allowed to participate in a vault okay so the guest list is basically a way to uh allow people to use it and this actually makes me think of uh other protocols and one of them that you will probably learn about later today the bankness is uh alchemics and alchemics uses yearn to repay for that they basically issue a token that will pay for itself and i'm assuming that uh some of those vaults especially when they're very experimental uh cannot be accessed by everyone and they uh you have to be put in the list you basically have to ask to be explicitly put in the list set rewards will set the rewards address set locked profit degradation which changes profit degradation with the rate of whatever we'll see what this is in a second set deposit limit the maximum amount that can be deposited in a vault and a performance fee which uh we said uh you know it's based on uh what happens we have the management fee same thing the guardian again the guardian can do a few things we'll see it later that we have a way to set the emergency shutdown and i love that the documentation is very far here so it says activates or deactivates vault mode where all strategies go into full withdrawal during emergency shutdown no users may deposit in the vault but may withdraw as usual the governance may not add new strategies each strategy must pay back their debt as quickly as reasonable to minimally affect their position and we'll have to see what this means we'll see it in this strategy and then only governance may undo emergency shutdown see a contract level note for further details if true the vault goes into blah blah okay basically sets that then it sets the withdrawal queue we already spoke about it it's just a way to uh prioritize which uh uh one of these um which strategy should be used for withdrawing first and which strategy should be used for withdrawing last i'm not seeing a deposit queue for strategy so i'm assuming there has to be a different mechanism for doing that we'll have to see we have the erc20 safe transfer that's fine uh as you know the safe transit will revert instead of just giving you a false result when it fails it's way better to have something revert when it fails because uh otherwise uh people will be upset when they lose their funds next you have transfer which is uh defined as internal and i like that i'm seeing this convention the underscore transfer internal so anytime you see an underscore function you want to think okay this function is used internally in the in the code it's not necessarily um accessible anywhere else so it's a c note on transfer and by the way the this idea of the internal function this idea is great because typically you will write a simple function that receives all of the parameters and does a bunch of stuff and that allows you when you're developing to set this to public and perhaps you can set it to only owner and you can use this pattern to write unit tests debug your contracts and write them real quick and then you can set them to internal so that um they're uh they're the unit tested functions and they work um i was checking the uh uni swap v3 source code and maybe i'll check that um another day but uh the um i think what they did with test is really interesting so we can learn a lot by checking that out so i highly recommend you go and check the unisop v3 core because it's just a uh example of engineering uh uh you know the test took like 10 minutes just to run the test so it was cool next up okay we have the transfer basically just send stuff nothing uh particular here again transfer function transfer from install you're here receive 20 function increase allowance so decrease allowance permit allows you to spend on your behalf free ip2612 let's just quickly check this eip just to be sure we're on the same page and anytime you can literally google this stuff and you'll see it this uh eip2612 is the permit everyone should sign approvals and it basically means that you can uh approve uh other uh uh another contract to use your funds by signing the git okay so that's cool and it basically does its thing to set itself up and i'm pretty sure you can literally copy all of this code from uh opensappling uh and uh you know thank you opens up button for existing i guess so we have the total assets total assets uh issue shares for amount okay so this is actually where we start getting into uh the more interesting uh stuff we see true address amount you win two five six so we receive it's an internal function that receives an address and an amount issues amount vault shares too it's gonna issue this amount of shares to this user shares must be issued prior to talk taking on new collateral or calculations will be wrong this means that only trusted tokens with no capability for exploitative behavior can be used so this this is actually something that um uh you know even ave may may uh even the ave even the ave uh tokens may cause issues with this because uh the fact that uh the number changes may throw off your your math so uh in this case they they probably will have a list of tokens they will accept and i think this is just because they wanted to save exactly they want to save uh gas basically they want to save so much gas that they wrote it using assembly anytime you see uh where is the asm there actually there is no assembly here so anyway they're declaring shares as they you end with zero total supply you integral self.total supply saves 2s loads i'm really not sure what this uh means but i'll trust it so anyway if total supply is greater than 0 we're going to set this precision factor to the percent factor variable and then shares is going to be equal to precision factor times amount times total supply divided by self.total assets divided by the precision factor so the shares that are going to be issued otherwise the shareholder amount is going to mint one to one normally otherwise it will actually and it's gonna mean shares right yeah total supply those wordpress shares balance of two shares so given the amount of uh issues amount vault shares too but technically this is not what this is doing this is calculating what amount is given this input amount and it will issue this shares amount so i would i guess i would say it i would phrase it differently this would issue issue shares vault shares 2 2 given the input amount and amount is used here as a way to we have total supply divided by total assets divided by precision factor and a multiplier by precision factor i'm assuming this is just for to avoid rounding they do it they do a multiplication division here you always do multiplications first next up we have amount times total supply and uh hey anime here good to see you how you doing so we have the amount times the total supply and then we're going to divide it by the total assets which i'm assuming is everything that they have in control so we'll see and again we're just issuing shares here next we have the withdrawal function with a known re-entrant modifier that means that you can't have this being called uh multiple times on a single uh block and we have the withdrawal function which has a parameter amount which starts by default to be set to the maximum we have the recipient set to message.sender it will deposit amount token issuing shares to recipient if the vault is in emergency shutdown deposit will not be accepted and this call will fail measuring quantity of shares measuring quantity of shares to issue is based on the total outstanding debt that this contract has the expected value instead of the total balance sheet it has the estimated value has important security consideration and is done intentionally if this value were measured against external systems it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim by redeeming their shares so this is this is actually there may be a big lesson here but we're seeing that they're using the uh told is basically a total outstanding debt that contrasts expected value instead of the estimated value i'm not sure what expected versus estimated value difference is going to be but and we'll see it as we continue reading but the uh thing i'm getting here is that uh you the contract has to um basically have a uh reference that avoids it being exploited from the external and uh that may be something that i haven't considered in my uh newbie solution so i'm definitely going to pay more attention on this next up we see on deposit this means that shares are issued against the total amount that the deposited capital can be given in service of the debt that strategies assume if the number were to be lower than the expected value at some future point the positive shares via this medal could entitle the depositor to less than the positive value once the realized value is updated from further reports by strategies to the vault so the realized value the expected value the estimated value this is the policy that shares the ratio against the total amount the deposit can be given a service to the debt the surgery assumed if the number were to be lower than the expected values in future the positivity is nothing could entitle deposit to less basically there is a potential exploit that is based on using the the current debt versus the expected amount of uh money or value that will be uh uh extracted by strategy and uh this basically the difference between the expected value the fact that you're taking in that and the fact that you're gonna have a different realized value means that there is a potential exploit here and so for the sake of consistency they're going to use the expected value instead of the total balance sheet okay care should be taken by integrators to account for this discrepancy by using these view only methods of this contract both off chain and unchained to deport determining if depositing to vault is a good idea no reintro withdraw okay and this is the function deposit okay so function deposit so we're saying that it can't be done during emergency shutdown you recipient not in self and zero address so the uh yeah you can't how to deposit your own funds and you can't be the zero address amount is gonna be set to uh the amount you receive if amount is not specified transfer the full token balance this is a shortcut to allow you to have uh the maximum amount by by having a no parameter otherwise it's going to ensure that the limit uh for total assets is respected self-deposit okay because we have a deposit limit for every vault so this is just ensuring that the vault doesn't accept more funds than uh it's program two then we're gonna assert that the amount is greater than zero and then we're going gonna check that the address is not uh zero and then we're gonna check that the um guest list is returning authorized on this uh account so you have to be authorized for this and this can be done all if the guesses is zero so you you now know that if you remove the gas list uh everybody is allowed to interact with the vault then we do a safe transfer and we return shares just in case someone wants them okay next we have share value it returns price one to one if the vault is empty and i'm guessing it calculates what the share is actually worth uh if it's not one to one so let's see how they do that i'm gonna give you my example to uh withdraw and my example is based on uh just withdrawing from uh let me see so in my case the way i i do it is i get total value which is equal to the balance of the token that i want and then i add what i deposited on of it and then i subtract the amount and i owe because i know that the amount that i o is not mine and the amount that i deposit is and it's always one to one that's because i'm using oven and then i'm just adding the balance that is currently floating in the contract and then given that i can just do a percentage given the amount of shares and the total supply so let's see instead how a more sophisticated system such as yearn will do it uh okay receives the share you wind value it then defines the locked funds ratio which is equal to block.timestamp minus self.last report times self-deluck profit degradation so basically there is a amount of pro funds that are going to be locked and it does that by uh calculating this profit degradation times which is a variable we saw basically one two uh one with 18 zeros or something that the governor set and then that will be multiplied by the time stamp the current one minus the last time that a report happened we have to see what last report means but uh that's basically what this does then we have free funds is equal to the total assets from this uh contract the precision factor was that variable we used to multiply and divide just to avoid um to avoid rounding errors now we see if locked funds ratio is less than the degradation coefficient or the gradation coefficient is a uh constant then free funds is minus equals to the self the locked profit the amount that is locked minus the precision factor uh which we remove yeah so uh it's going to be equal to locked funds ratio times locked profit the locked funds ratio the ratio of funds that are going to be locked multiplied by the locked profit the amounts of funds that are going to be remaining here divided by the degradation pro coefficient so if the locked fund ratio is less than the gradation coefficient the luck fund ratio times locked profit divided by the degradation coefficient so the degradation coefficient and then we have the ratio of funds we uh locked multiplied by the amount that is locked and that we this will uh change our free funds to be equal to that so basically the locked fundration the declaration coefficient are expressing a way or a number they used to figure out a number of funds that are uh gonna be uh unlocked so this is the unlocked part and this is the locked part and the the free funds is gonna be equal to the subtraction of the locked profits minus the part that has been uh unlocked so this basically is dealing with the locked stuff which i'm not sure why it's locked but we'll figure that out we have the locked stuff and then we have the free funds and we're just removing all the stuff that is locked by using this math right here and then given this we're going to return again precision factor we're going to ignore shares times free funds shares amount of shares multiplied by three funds divided by total supply and that gives us the share value yeah that makes a lot of sense uh beside uh i'm not sure why there's the locking but uh ignoring the locking we're simply having amount of free funds which is the total assets minus the locked so it's basically everything that this contract is holding and then you multiply that by the shares then you divided by the total supply of shares so uh since uh the entirety of the vault is the dominating one token then this makes perfect sense and there's no need for any uh further uh uh correction while um and since my example that i written also is denominating in one token then this makes a lot of sense otherwise you may need to also add these ideas of get rate where you basically use an oracle to calculate your uh uh um the value from a different currency in this case from if to uh matic that said uh again simply the value of a share is equal to the amount of shares divided by the total supply multiplied by the funds that are free and then we have this precision factor which is added and removed to avoid rounding i think i will take this advice of having a precision factor because i've had situations where uh my numbers were off by one and uh so this is how you avoid rounding errors i guess sounds uh cool then we have shares for amount i'm guessing it's literally the same thing but uh instead of using share the single share it's going to use the amount that we gave so that's basically that then we have the max available shares which determines the maximum quantity of shares this vault can facilitate withdrawal for factoring in assets currently residing in the vault as well as those deployed strategies on the volts balance sheet facilitate that withdrawal for factoring asset currently residing in the vault as well as those deposits on the volts balance sheet okay so this uh is this where we start uh getting into multi-strategy multi uh basic having assets in multiple places and i will simply return the uh all the shares that this vault can allow you to withdraw basically so let's see regarding our shares are calculated see death note on deposit which we saw uh up and if you want to calculate the maximum user code withdraw up to you want to use this function that's uh awesome note that the amount provided by this function is the theoretical maximum possible from withdrawing the real amount depends on the realized losses incurred during withdrawal but this is on shares note that the amount provided by this function is the theoretical realized losses so the one thing that perplexes me about this comment is that we are asking how many shares can be served so i believe that even if the shares were to take a loss in the token denomination uh you could still withdraw them you just lose value the total you your token is worth less but you can still redeem those shares although there may be uh some others that uh prevent that but again this means that we may have to go back to withdraw perhaps as we uh continue you know we're halfway the file perhaps we will go back to withdraw to figure that out once we have more context on uh the entirety of the code then we have the if we return the total quantity of shares this vault can provide amazing so self shares for amount which we saw before amazing which uh checks the shares for amount given the sell the token the balance so given the balance of this contract the balance of this token it uh so basically it takes the balance of token that this contract has and it gets the shares for amount it gets uh the the shares that are serviceable and then for strategy in withdrawal queue if the strategy is zero will break because the last strategy is denominated by a zero and then it will check uh it would just add shares from the shares or amount given the total debt of the strategies total debt so the max available shares gives you the shares for the amount given the sum of the total debt of each strategy so it's not the assets in the strategy it's not the uh deposit in the strategy but it's the total debt i'm um honestly not sure why maybe uh we'll we'll uh see that as we go in the strategies code but this may also be a way to uh because you you should given yeah that may be an intuition that i'm getting but this is pure speculation but let me show you something without it that is really easy to understand so if you deposited one uh matic you can borrow 50 0.5 matic right that's all you can do if you the positive one you can borrow 50 because that's the ltv that means that this 50 i can withdraw at any time as long as i repay them because as long as my health factor is above a threshold and we saw that there is a min and a max then i can always withdraw this without any risk there is zero risk to withdrawing this um so that may be an intuition as to why uh it's doing this because again this is for sure the amount you can withdraw the one in the deposit may be leveraged and i can show you an intuition for that it's very simple i have one here and i have 0.5 here i can at this point i can't borrow more because i'm uh above my l factor but i can actually quote and go borrow more by withdrawing from here okay we draw up to 0.22 setting my health factor uh to a lower number right which is kind of basically compromise my l factor i'm risking of getting liquidated however at this point there is still a way for you to withdraw the 0.5 uh but this number is basically uh if you were to withdraw anything from the deposit you will lose your money basically you you literally can't uh they will actually revert and i'm gonna uh give it back whatever that was 0.12 0.22 all right so i'm guessing that's why we use total debt in the uh max available shares but again we'll investigate then we have a report losses it's an internal method receives a strategy and an amount loss can only be up to the amount of that issue to the strategy told that cell strategy strategies total that assert that total debt is greater than equal to loss because you can only lose as much as what was owed that makes sense and then the total loss yeah i just uh changed these variables for the total debt and total uh loss for the strategy also make sure we reduce our trust with the strategy by the same amount that's actually really interesting so we get the debt ratio from a strategy we get the precision factor which is just uh like this entire precision factor thing i'm not sure if there's an easy way to uh avoid this but maybe there would be like a utility function called the precision math where it's just where you basically always put the precision factor uh at the beginning for multiplication and for division so i just need to learn to ignore it when reading this code and then we get the ratio change is equal to the minimum of the loss times the bps which is uh ten thousand divided by the total assets and then uh um and the debt ratio so we either take the debt ratio or we take the loss times the bps divided by total assets that changes the the uh that's used to declare his valuable ratio change which will change the debt ratio to a number that is less uh than that so the debt ratio gets decremented by ratio change which means that now our strategy can take uh up to that ratio that which is less and i'm guessing it's again as i said a way to reduce trust in the strategy because the strategy is not performing as expected and then i just change the debt ratio less by lowered by the ratio change as well so we're seeing that this change of the ratio change changes both in the debt ratio of the strategy and the debt ratio that we have and that may be because this strategy is taking some debt and we are taking some debt as well so again another thing to keep in mind next up we have withdraw max shares um yeah by default said to that recipient said to you max loss set to 1 0.1 one basis point 0.01 and uh that may be a way to uh basically block uh withdrawals and this actually gets us back to the um the stuff we were looking at before let's see what we got withdraws the calling accounts token from this vault redeeming amounts underscore shares for an appropriate amount of tokens see note on set withdrawal queue for further details of withdrawal ordering and behavior see note on set withdrawal queue for further okay yeah because it's uh gonna use the queue from the uh the vaults queue then we see measuring the value of shares is based on the total outstanding debt that this contract has the expected value instead of the total balance sheet that it has the estimated value we're gonna take the outstanding debt instead of the total balance sheet the estimated value and i think this goes back to this idea that i have 1 and 50 and if i uh deposit my 50 because i'm doing the strategy where i take the borrowed money and i put it back in ave then i still have borrowed only 0.5 but i currently will have the positive 1.5 and so if i ran the map from this i am massively over inflating my numbers which are it's bound to cause issues so uh i may have to change my own math and base it on the borrowed amount because given the borrowed amount i can always uh get back the real uh amount but we'll we'll see again and blah blah blah consideration if this value were measured against external systems it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim very limiting their shares on withdrawal this means that shares are redeemed against the total amount that the depositor capital had realized since the point it was deposited up until the point was withdrawn on withdrawal this means that shares are redeemed against the total amount that the depositor capital had realized the shares are remaining against what the deposited capital realized yes since the point it was deposited up until the point it was withdrawn okay so that means that your shares are taking in the value that your shares the the collateral the corresponding shares generated from the point it was deposited from until the point it was withdrawn so basically you're getting the interest that those shares generated if the number were to be higher than the expected value as a future point withdrawing shares yet this method could entitle the depositor to more than the expected value once the realized value is updated from further reports by strategies to the vault the number were to be higher than expected at some point during sharia this medical entire deposit to more so yeah if you again if you use the stuff you borrowed you would expect to be able to uh earn more and uh that may uh you basically will end up receiving more than than what you should be receiving and that can be exploited under exceptional scenarios this could cause earlier withdrawals to earn more of the underlying asset than users might otherwise be entitled to the vault estimated value were otherwise measured for external means accounting for whatever exceptional scenario exists for the vault they aren't covered by the vaults on design okay so that means that there may be an arbitrage opportunity i'm honestly not sure but uh uh you know if you if we're gonna spend you know the next hundred hours exactly figuring out why this is the case uh there may be uh there definitely is a lot more to uncover literally in these words right here then we have the parameter max shares how many shares to try and redeem the recipient the guy the address that receives and max loss is the acceptable loss uh to sustain the withdrawal because every other strategy has to cascadely earn and lose value we have the shares may reduce this number below that's the max shares we have the max loss which can only be up to the bps because you can only take a 100 loss which goes back to the the previous idea of on lockdown when when the uh the vaults are locked uh there may be losses but uh you can specify a slippage on your losses which is great the we're going to check that you can only try and withdraw up to your uh maximum balance limit to only the shares they own yup ensure we're withdrawing something it doesn't let you waste gas for no reason and then uh it will uh get the value by calculating share value of shares so now this is the value of um the shares given given the amount of shares it will tell you how much they're worth then you have the total loss and if value is greater than the balance of the token that this vault has that means that the vault has to withdraw from the strategies we need to go for saw to get some from our strategies that we draw a queue and if you were to write your own uh yield farming uh contract something that i did is i withdraw everything and this is actually uh you know because it's so much easier to code uh just divesting and you're gonna withdraw until you can repay everything and you're just gonna repay everything and just withdraw everything that's highly inefficient because you're wasting gas because you're gonna have to redeposit and you're gonna have to rebalance anyway so this problem that uh the the wire team solved by having a list of strategies um it's actually something that every uh smart contract developer will have to face so let's see we need to get some strategy blah blah this performs force withdrawals from each strategy force withdrawals during force withdrawals a strategy may realize a loss that loss is reported back to the vault and the and the will affect the amount of tokens that withdrawal receives we we gotta uh do a uh we gotta do like a suggested fix here for a typo or something reference a new issue and they will affect the amount of tokens the bird back the loss is reported back to the vault and will affect the amount of tokens that the withdrawal receives for their shares they can optionally specify the amount the maximum acceptable loss in basis points to prevent except excessive losses on their withdrawals which may happen in certain edge cases where strategies realize a loss okay so let's see first strategy we basically turn it over each strategy we're gonna break when we get to the empty strategy the balance of the volt is calculated every time that we do the loop and we check at which balance we are if value is less than vault balance we're done so this is how you will stop withdrawing because value is less than equal to volt withdrawal so in a simple example that i have when i loop loop loop loop i will check for current less than amount if current is less than amount i will continue looping otherwise i will eventually stop now we have amount needed is going to be equal to value minus vault balance because we got the new vault balance and uh yeah so now amount needed is going to be the minimum between the amount needed and the total debt of a strategy and that's because the strategy cannot withdraw more than the total debt because we have this intuition that the total debt actually represents the real value that the strategy uh has because the total debt is a way to cap the amount that the strategy can immediately turn into usable tokens the amount needed is zero continue nothing to withdraw from this strategy because um there is no total debt or amount is zero amount needed should never be zero because you will break here if value is less than volt balance the value let me see amount needed is equal to value minus vault balance and vault balance is the balance that the token that this vault has of token so i have this balance and then if value is less we're done where value is the parameter up here which is the shares value that we need to uh repay so anyway if either of this is zero it means that uh we're going to skip the strategy first withdraw amount for each strategy in order to in the order set by the governance so loss strategy the withdrawal amount needed and you really calculate the loss by calling the withdrawal function and that withdrawn is equal to self.token.balance self minus fault balance because that's what you withdraw it's equal to the volt balance token yeah basically this is the difference between what you just received and the amount that you uh had and if loss is greater than zero value minus equal loss total loss plus equal loss and software report loss so the withdrawal is gonna incur the losses from uh liquidation or basically it's gonna incur these losses here so and that's uh cool or at least it's really yeah it's cool it's cool implementation because what's happening is that we're getting the loss for the strategy here and if loss is greater than zero then we're also going to reduce the value which means that the loss is not uh the system is not taking the loss the loss is being passed on to the uh withdrawer so if you try and withdraw too much because you're in a hurry you pay that it's not paid by the the protocol so that's actually uh clever it's a really clever solution now we have total loss plus equal loss and then you report a loss which uh yeah just probably just emits an event and maybe updates a global variable now reduced strategies that by a month withdrawn realized returns this doesn't add to returns as it's not earned by normal means strategy strategy dot total that minus equal withdrawn because there's no longer that and save the total that that is minus equal to withdrawn as well okay and then we're out of the loop which is really convenient by python the fact that the loop is uh nested so it's actually easier to see and we have withdrawn everything possible out of the withdrawal queue but we still don't have enough to fully pay them back so adjust to the total amount we freed up throughout forced withdrawals we learned everything possible but we still don't have enough to fully pay so just to the total amount we've freed up for withdrawals we'll balance this is the vault value is greater than value is going to be equal to what balance and sell shares for amount value plus total loss and it's going to burn the number of share that corresponds to the vault has on hand including the losses that were incurred so basically in the case in which you're withdrawing so much that the uh vault uh can't even pay you back uh it basically will do this act of uh setting the shares to the shares equal to the value and the loss so that way you are uh basically uh paying those losses and i'm guessing this is how you will be able to go back to zero in terms of withdrawals well if you didn't do this uh you would still have some um you may have some shares left because some shares are worthless because of uh the loss that you incurred then you have this loss protection is put in place to revert if losses from withdrawing are more than what is considered acceptable so this happens here that uh is uh uh is this the best they can do though so basically because this assertion will make uh the the call failed it means that you literally went you your worst case is you went through every strategy for every everything to be able to do this and um and then it will fail here which means that you're gonna pay uh i'm assuming like yeah 99 of the transaction cost 90 of the transaction costs you're gonna pay it because uh you put the slippage here so uh i guess uh uh if you're really unlucky uh that's what happens although you know you will basically need to be the sole owner of the vault to uh i guess even consider this but yeah there may be a scenario where uh i think it makes sense uh because uh the alternative will be for every withdrawer to always pay for each check at every loop and so every single person's withdrawal will be more expensive while this situation will happen exclusively if you're literally withdrawing like 90 percent of the uh the uh you went through every strategy and you withdrawn a ton and then you have slippage due to liquidation so this would be like uh uh you know it's not really uh it's i think it's fine you basically you're gonna lose a lot of gas if that happens but again i think uh you you probably would uh you you're basically the one person that can take that that hit and then we see uh yeah it's basically done next we have a view method called price per share gives the price for a single volt share share value uh is equal yeah share value with uh um self.decimal yeah it's basically the value of one share and you use the share value function which we saw before was uh a really uh pretty straightforward function plus our uh the rounding factor next we have organized withdrawal q value between reorganization actual values then the empty value should be replaced by the later value okay so this seems like a way to clean up the queue so that you ensure that the last value in the queue is the zero address because the zero address signifying every of these loop signifies the ends of the queue so that makes sense then you have add strategy which receive the address the debt ratio the mean per harvest max per arrest and the performance fee adds a strategy to the vault this may only be called by governance the strategy will be appended to withdrawal queue call set without queue to change the order which we just saw up here and then the address of the strategy to add blah blah this is a parameters we saw already we have we're going to assert that with oral queue is not full now we're gonna assert that withdrawal queue maximum strategies minus one is zero so there is a empty uh slot in the queue then we're gonna assert that there is no emergency shutdown and then the governance is doing this then we're going to say that the strategy uh cannot be uh receive also this um uh strategy and then it will set the withdrawal queue uh it will basically put the strategy at the end of the withdrawal queue and then it will call organize without key which we saw will simply sort them uh i'm assuming you will sort them by uh yeah just cleaning up the zero address and putting the zero address at the end this is not a way to define the sorting order of the withdrawal queue it will literally just append it and then clean up the the uh the list next we have update strategy debt ratio it changes the quantity of asset strategy may manage the quantity that necessary may manage this may be called by governance or management it requires that uh it's either management through governance it requires that the strategy is active then that ratio minus equal the debt ratio of the strategy so it will uh take the debt ratio from the vault to the strategy then it will uh set the strategy that ratios to be equal to that ratio where that ratio is uh this number right here and then it will increase the the debt ratio of the vault to uh this debt ratio value it will assert that the debt ratio cannot be above 100 percent you can't and then it will just uh be done with it then we have update strategy mean that per harvest you will just change the minimum that per harvest call we don't know what our school is but we'll figure that out we update the strategy max that we saw that then we update the strategy performance fee the performance fee strategy performance fee it will just change the performance fee which is uh the uh you know the the extra fee that you get on um return above expected and then we have a revoked strategy which basically calls removes the debt ratio sets the debt ratio of the strategy to zero and uh revoked strategy uh is uh you would assume that the strategy gets deleted but what actually happens is you just put the debt ratio of the strategy to zero which basically means that the strategy cannot receive anything it cannot borrow so we'll see exactly what that means as we get into the strategy code next we have migrate strategy which migrates the strategy including alaska from old version to new version okay it moves all assets as we said and let's see what this says this can only be called by governance strategy must successfully migrate all capital and position to new strategy or else it will or else this will upset the balance of the vault the new strategy should be empty and you have no previous commits into this vault otherwise you could have issues let's see it cannot be done by governance the new version cannot be zero the activation of the old version is to be uh greater than one greater than zero so it's active while the the activation of the uh new version needs to be zero sergey peron self strategy old version we're getting the strategy param from the old version we're revoking the old version we're setting the debt ratio of this vault to the debt ratio of the new strategy of the uh strategy which is which is the uh old strategy currently then we're setting the old version total that to zero because we're migrating it then we're creating this new strategy with these new params that we got off of the old version and then we're gonna migrate we're gonna call the migrate function on the old uh strategy and then there's this loop for edx in range maximum strategy self.withdrawal queue edx equals equals old version so uh seller without qedx equals equal version if okay finds the old version and puts the new version in the place of the uh new uh of the old strategy now we can revoke we saw revoking a strategy just requires that it can be held down by governance strategy but study messages in strategy self-governance of guardian can all be done by the strategy the governance or the guardian and it revokes itself we can add the strategy to the queue it's basically a way to just add it to the end of the queue that we remove strategy from queue same thing just removes it and then he calls organized withdrawal queue which is the way to remove empty spaces then we have the debt outstanding so this is uh a new thing the debt outstanding c note on that outstanding which is probably down here and uh we have a precision factor so we're just doing math given the strategy it's going to get the debt ratio of the strategy it's going to multiply by the total assets of this vault and then it's going to divide it by the uh 100 basically so it seems to me that the debt outstanding is equal to the amount that the uh strategy took divided by the amount that the vault has uh or sorry multiplied by the amount that the volt has divided by uh basically 100 percent so this is the strategy debt limit yeah it's just the percentage of how much the strategy can take in terms of total assets and then we're going to use this debt limit uh let's see we declare strategy total debt by getting the total debt from the strategy and then if it's on shutdown we're going to return strategy to total debt otherwise we're going to check if strategy.total that this variable here is less than strategy debt limit then we're going to return zero which means that there is no that outstanding otherwise the debt will be equal to strategy total that minus strategy that limit let's think about this for a second we got the debt limit which is the percentage of the debt ratio multiplied by the total assets so that ratio is already a percentage and then the total assets is a value so the percentage of that that the strategy can have at max that's that number this is the strategy that limit and then you have the total debt the actual value that the strategy is taking in that and what is saying here is that if the strategy totaled that the amount that the strategy took uh in that is less than equal that the debt limit then we're going to return zero because yeah that outstanding because basically the strategy can return this money instantly these tokens uh instantly it doesn't have to uh repay anything otherwise it's going to return strategy total that minus that limit that outstanding is a function that determines the strategy in the past yeah basically it's using this function up here so it's uh just the external version of it then we have the credit available let's see uh the credit available if it's in emergency shot and it will return to zero it gets the precision factor which again i need to ignore when i see it then we get the total assets and basically we get the debt ratio of the vault multiplied by the total assets divided by the uh basis points so it's a percentage between the total assets and the debt ratio and this is the credit available because this is the amount of um stuff that we're willing to uh borrow i'm guessing and then we have the total debt we set the total debt here we have the strategy debt limit because again we're looking at the credit available for a strategy so we have the strategy debt limit which is equal to the debt ratio of the strategy multiplied by the total assets of the vault divided by the basis points so it's a percentage of all of the debt that the strategy can have given the total assets of the vault then we have the strategy total that we actually take the actual debt then we have the mean debt per harvest and the max debt per harvest and so if and we see the comment exhausted credit line so if the strategy that limit the maximum number is less than the strategy total debt or the volt debt limit is less than the volt total debt then yeah we we have no more uh credit available if the debt limit has been reached or the vault that limit has been reached there is no more credit otherwise let's see available is equal to the strategy debt limit minus the strategy total debt and then we're going to have the minimum between the available from the strategy and the available between the vault and that's again because we're checking how much credit is available to the strategy and then available is equal to the minimum of available and the balance of tokens that we have can only borrow up to the contract as in reserve okay because you don't want to run near 100 same idea that you can only if you deposit one you can borrow up to 0.5 or in this case up to 0.99 although we'll have to see what the total debt uh variable looks like and then we see here adjust by min and max borrows limits per harvest if available is less than strategy mean that per artist then there is nothing available and otherwise it's going to return the minimum between the available and the strategy max that because yeah basically uh if uh if we're trying to borrow cents on the dollar we're just gonna ignore that and otherwise we're gonna get the minimum between what is available and the max so that we don't go over the max per harvest then we see credit available which is the calling that function let's see the context for it it's the amount of tokens in a vault the strategy has access to as a credit line this will check searches that limit as well as the tokens available in the vault and determine the max amount of tokens if any the strategy may draw on in our case the vault is an emergency shutdown this will return zero okay then we have the expected return finally we see expected return let me just do a peek of what we're gonna have later deposit limit expected return assess fees report we have quite a little longer to go and then we have sweep we're gonna we're gonna finish this file and uh then i'll take a quick break and i'll also do the strategy file so let's see the expected return the er let's actually just uh um because as you can see we have the underscore expected return which is the internal version and then we have the external version and the external version has a comment so it's probably a better idea to just skip ahead and check this and then check the other one so the expected return will receive a strategy parameter and then and it can even be called by the strategy itself that's the default value action and then uh the comment says that it provides an accurate expected value for the report the return this strategy will provide to the vault the next time report is called so it provides an accurate expected value for the return on the strategy we'll provide to the vault the next time report is called since the last time it was called the strategy is the parameter and it returns the anticipated amount of strategy should make on its investment since the last report let's go and check it out inspector return receives the strategy address strategy last report will be the last report here it will uh check the time by comparing the block.timestamp minus the last one this is this variable here it's going to check the total harvest time which is equal to strategy last support minus the activation time so this is the total time if time since last harvest is greater than zero and total harvest time is greater than zero and strategy is active then the feeder time is zero we can short circuit to zero okay that's cool but basically if everything works then precision factor we get the precision factor and then we calculate the total gain of the strategy multiplied the time since the last harvest divided by the total harvest time so it's basically a percentage uh gain and uh we have this expected uh yeah basically the expected return is equal to how much the strategy already got multiplied by the time since the largest harvest divided by the total time so it's just a percentage uh that allows us to figure out what we got and what we expect to get we see this a function called available deposit limit it checks that the deposit limit is equal to the total assets and if the deposit limit uh and it returns the difference between the deposit limit minus the total assets otherwise it returns zero okay then we have assess fees which is the internal function so let's check the external first seems like it's used in this big report function so i'll check the report function first and then i'll go back to the assess fees report will receive you in for gains you went for losses and the debt payment as they you went as well reports the amount of assets the calling strategy has free usually in terms of roi the performance fee is determined here of of the strategies profits if any and that's sent to governance the strategist fee is also determined year off of profits to be handled according to the strategies on the next harvest this may only be called by a strategy managed by this vault for approved strategies this is the most efficient behavior the strategy reports back what it has free then volts decides whether to take some back or give it more note that the most it can take is gain plus underscore debt payment and the most it can give is all of the remaining reserves anything outside of those bounds is abnormal behavior okay so we have a most gain plus that payment and uh now this is a take and then most can give is all of the remaining results all approved strategies must have increased diligence around colonies function as abnormal behavior could become catastrophic yeah if all these numbers go out of the bounds uh the entire system stops working because it's all based on the strategies reporting proper numbers which basically means higher emphasis on uh the code that the strategies are running so we see prime gain amount strategy as realized as a gain on its investment since the last report and is free to be given back to the walters earnings so again as we just define it is going to be the float the amount of tokens that the strategy has and that it's not no one we're using and that the vault can actually take for profit the loss its loss and investments is the last report and should be accounted for on the vault balance sheet so this is stuff that has been uh lost and it could be for example by paying higher interest on other tokens then we have the debt payment it's the amount of strategy has made available to cover the outstanding debt okay so this is the amount of uh token that the strategy can use to pay the outstanding debt and then it will return the amount of that outstanding if total debt is greater than that limit or emergency shutdown all right so let's see we assert that the strategy is active we want the balance of the token of uh this sender to be greater and equal to gain plus that payment let's see what message of senders i'm assuming this is done by the um strategy yeah strategies message our center so the the strategy needs to have a balance that is greater than gain plus that payment can be greater or equal which means that uh basically if this this for this function is called the exact time the strategy takes a profit then the balance should be exactly equal to gain plus that payment well if this is delayed a little bit then the uh strategy may also have a little bit more in the balance off and as such it could uh just uh not ever reported yet and if loss is greater than zero we're going to call the report loss function we have total fees which is going to assess fees of message sender gain which means that it will assess both management fee and performance fee an issue both by shares of the vault issue both as shares of the vault assess fees given message.sender and gain then it will then it will set the total gains to people sequel the gain that were reported by the vault and it just sums them up then it will set the uh variable that this variable that which is a unit 256 to the result of the debt outstanding um function which receives the strategy basically gets the strategy.that outstanding the the debts that it still has to be paid and then it will call that payment the amount that can be paid will be equal to the minimum between the debt that is outstanding and the debt that the strategy can afford to pay if that payment is greater than zero we're going to remove that payment we're going to remove total debt and we're going to uh set that to minus equal that payment and i'm guessing we're gonna use that to repay the debt i'm not seeing the actual repayment of the debt it's probably gonna come up later then we see credit is equal to seller available on master.center again we get the credit available for the strategy if credit is greater than zero we're gonna set tool credit plus sql to uh the credit that we got and then we're gonna also increase the total debt of the uh vault to be plus equal the credit that the strategy has and then it says give take balance to the strategy i'm guessing this is where uh we're gonna do the rebalancing so now we have total available and that's going to be equal to the gain the amount of what's gained plus the debt payment the amount that uh can be used to pay off that in total available is less than credit then credit surplus give it to a strategy total available is less than credit then we're gonna do a safe transfer from uh software token. uh erc self basically we're gonna do a safe transfer of the token from the strategy give to strategy token.address message.sender so this is actually not the default erc20 uh send method or at least it doesn't look like it to me because this is taking the address of the token so i'm guessing now this is a safe transfer of this token and i'm get yeah and this is a safe transfer of this token to message.sender to the strategy for the amount that is equal to credit minus total avail so that's what it is and then if total eval is greater than credits then we're going to do a transfer from the messenger sender from the strategy to this contract for the opposite value the total unveil minus credit update the reporting time we get the time stamp for the last report we said that also to the thing and then we have the locked profit which is equal to the gain minus the total fee profit is locked and gradually released per block it's gain minus total fees then if the strategy is debt ratio zero on self-emergency shutdown we're gonna call strategy.estimated total assets take every last strategy as and yeah basically it's going to take everything let's see what sweep actually we haven't checked the um function up here called uh asses assess fees which uh receives the strategy and then uh a gain parameter precision factor yeah we get the management fee is equal to the total debt minus the delegated assets which we don't know what it is we'll see it later and then multiply by the difference between the timestamp the current time minus the time of the last report multiplied by the management fee so we're basically getting a percentage yeah we're getting a percentage based on time uh of the difference between the total debt and the delegated assets multiplied by the uh fee so we're getting a cut of management fee and uh it only applies under certain conditions we have set to zero if gain is greater than zero then the strategist fee is equal to the gain multiplied by the performance fee divided by the max bps where gain is being self-reported by the strategy now we have performance fee which is equal to precision factor times gain times delta performance so we have gain times performance fee again gain as a gain yeah the performance fee is a percentage so we just take the percentage of gain times performance fee divided by max bps to do the performance fee and that we do total fee is equal to performance fee plus strategy fee plus management fee if the total fee is greater than gain then the total fee is equal to gain we set that then if the management fee is equal to gain minus the performance fee minus the strategy fee so if total fee is greater than gain total fee will be capped to gain and management fee is equal to gain minus performance fee minus strategies fee if total fee is greater than zero we're going to skip and if total is greater than 0 then reward is going to be equal to issue shares for amount self total fee it's going to issue an x amount of shares to the zone vault for the uh total uh based on the total fee basically uh that's the amount that it's going to be uh and the reward is just the amount of shares that is issued so the amount of shares that are issued is stored in the reward variable given the total fee and it's then sent to the vault itself um if the strategy is fees greater than zero which means that we're gonna skip it if it's not uh zero then we're gonna just give them a reward by doing again strategies fee times award divided by total fee and it's gonna transfer them to the um strategies reward it's gonna trans it's gonna call this transfer function to uh transfer i'm guessing to the um to the strategist or to the strategy reward i guess or the strategy uh contract and lastly if cell phone balance is greater than zero if we still have something then transfer that from self self.words yeah transfer it to the self.words and transfer the amount they specified by the balance of this account so basically it's just going to send everything that is left after calling assess fees will be sent to uh the rewards um the rewards uh contract so in conclusion we have the sweep sweep removes tokens from this vault that are not the type of token managed by this vault this may be using in case of accidentally sending the wrong kind of token to this vault tokens will be sent to governance this will fail if an attempt is made to sweep the tokens that this vault manages this may only be called by governance so uh yeah this is just a function to withdraw any token that is not managed by the vault or managed by the strategies we say we assert that the message does sender is equal to the governance we assert that the token is different from the token that the uh vault is using we check that the value is if the value is equal to max then the value will be equal to the balance and then we just do a safe transfer and we send the tokens to the governance so this this idea of the sweep which i like to rename it and call it the rug it's obviously it's ironic but fundamentally the sweep function um is coded in a way where even a malicious attacker can only send the money to the governance the governance can only call this function and the governance can only send the funds to itself so it makes it uh very uh safe or very deliberate at least because the only person or the only contract that can call this is the governance and you can only send them to themselves i think we covered the vaults um fundamentally the big the big thing is the mafia intuition shares and calculating profits let me see if there's unit tests for all this stuff registry wrapper strategy vault test config test losses let's just check a couple of these i really want to check the shares for the test for shares define vault government token vault voltage deploy initialize set deposit so these are just setting that uh setting up the contracts test deposit with zero funds approve rewards okay this is checking that it reverts if you try depositing um from rando test deposit with the wrong amount tester let me see the issuance of shares i'm guessing you just do a deposit we brought in our reverse val balance okay all right so we see set guest guest invited from gov the positive violence balance voltage deposit balance token the balance voltage balance random equals to balance so this is testing that when you make your first deposit you're going to get uh amount shares this is a fine test deposit all and withdraw all from gov all the positive imbalances balance volatile balances balance withdrawal token balance is zero token balances balance deposit limit delegated deposit withdrawal delegate deposit withdrawal transfer from do not issues your shares emergency test transfer [Music] withdraw from b2 this may be the one that we're looking for test delegated deposit withdrawals we have five accounts original token amounts no returns token dot approve talking that the deposit in the vault from a we assert that the balance of a is zero we assert that the the val the volt balance is zero this doesn't have any shares and then we see that b has been issues volt but that's because they're depositing on the alpha of b yeah we're sending the shares to b now we draw from b to c b volta withdraw of all the balance of b c from b so b is going to call the function to withdraw and send to c we check the b as nothing and c as the token amount uh approve deposit see no longer yeah basically just just continues doing this uh tour of stuff let's see with withdrawal i guess okay test multiple withdrawal we initialize we approve we deposit one million we uh one million away so whatever that is we uh strategy of deploy strategies for rearrange we add a strategy no harvesting limit no fee and ten percent of all tokens involved then we have uh see all the strategies with that c dot harvest from gold for us in strategy asserts that the token balance of volt is the starting balance if 50 is in the strategies and for s in strategy for each strategy is asserts that the estimated total assets is equal to the balance of s starting balance they're all the same that we draw only from volt volt withdrawal balance of assert token the balance vault is zero it calls the withdrawal function with the balance of gov from gov it asserts that the vault is empty and that the uh total ass sets the balance of s and sorry imbalance are all the same and that withdrawn all the debt volta withdraw volta bar from gov assert vault.total 0 for s in strategy s estimate at this point i'm searching to see if there's any calculation on the ratio for the uh just a calculation of the ratio for issuing shares that's what i'm really looking for blob of a blusher value let's see maybe it's here no no i'll check uh uh probably offline uh if i can find any specific test on that uh up next i'm gonna read over and comment on the uh strategist code and uh which is a uh the thing that is more pertinent for a strategist is to check the base strategy and then there's literally a brownie mix here burning strategy mix that you can use to write your own strategies but that said i'm just going to go over the uh strategy real quick and i'll try and see if there's any uh thing really interesting we can uh learn from and uh perhaps i can do a second follow-up video on this if uh you're interested so if you're interested let me know in the comments i'm gonna uh check basically have the same strategy perhaps we already saw this is the interface for the vault we uh went through that uh fairly heavily credit available how much we can borrow basically the debt outstanding is how much if you how much the vault would like to pull back from the strategy because it wants to pay back expect a return this is based on the previous returns and the uh the difference between time now we have a report the act of reporting the gains and losses and now we have a bunch of governance stuff then we have the strategy api each strategy will have a name a vault we said that it's associated with one volt i want which is the token of the vault api version a keeper will check that later but a keeper is something that automates processes is active you need to have an active strategy in order for it to be used delegated assets i'm not sure what it is we'll see estimated total assets is uh we'll see again 10 trigger 10 harvest trigger harvest so these are our four keywords that uh we really want to check and then everything else is kind of uh ecosystem that we want to just uh look at the base strategy we're going to be using safe maps if your c nothing crazy here let's see delegated assets is the amount in want of the total assets managed by the strategy and should not count toward yearns tvl calculation total value locked calculation so the delegated assets is the amount of assets that the strategy our men is managing and it's not part of the yearns uh tbil you can override this field to set it to a non-zero value if some of the assets of this strategy is somewhat delegated inside another parts of what uh uranus ecosystem in general revolt now the disaster this value must be strictly less than or equal to the amount provided by estimated total assets below as the tbr calc will be total assets minus delegated assets also note that this value is used to determine the total assets under management by this strategy for the purpose of computing the management fee involved the amount of assets this strategy manages it should not be clear total value locked calculation across this ecosystem okay we have vault strategy rewards keeper the events for harvesting updating strategy updating keeper etc minimum report delay the distant in blocks or seconds i guess minimum number of seconds between a report max report maximum amount of time maximum number of seconds between harvest calls okay and that that means that each harvest is associated with a report as well so at this point we're starting to realize that harvest is the act of reaping the rewards i'm guessing so that which corresponds also to the act of reporting the gains and losses and paying the debt back so that makes more sense in the full ecosystem now that we have the profit factor minimum multiples that call cost must be above the credit profit to be justifiable see set profit factor for more details the minimum multiple the cost must be above yeah i'm guessing yeah this is just a way to avoid throwing out away gas for no reason this is to adjust the threshold which running at that cost service trigger see that threshold for more details and then we have emergency accident only authorized only strategy these are just basic modifiers only keeper and you can see the only keeper actually allows everybody and the keyboard to do it so the strategy to governance the guardian and the management and the keeper can do the only keeper stuff and that is really just a fallback to ensure that you know chores can be executed by as many people as we can afford then we have the initialize function which is an internal function versus vault strategies rewards and keeper it just sets all of these values up and it approves the vault for the maximum amounts of rewards next uh we see used to change strategies actually volatile approved rewards you int means that the vault we're calling the approve function on the vault giving the approval of the rewards address for the maximum amount so that means that whatever these um my airpods die whatever these let me check that the audio is fine speaker yeah so you should be fine so basically um yeah basically we're saying that whatever this strategy will accrue uh the uh it will allow the rewards to be sent there because this strategy will earn shares we saw that in the the shares math the strategy will earn shares and it will be able to send them to the rewards contract which can then be used for whatever purpose then we have set strategies set keepers set rewards and you can see they're only only uh you know high level then you have set minimum report delay max report profit factor debt threshold where the debt threshold by the fault is zero meaning any losses will cause a harvest which would successfully subsequently report the loss of the vault this may only be called by government strategy this will set off our strategy can go into loss without our harvest so the debt threshold is basically the amount of debt that the strategy can can tolerate without closing in on those uh losses um that's good to know and then we see the metadata uri just to to change metadata they start to sort of uri of the file describing the strategy so actually really cool each strategy will have a metadata uri so maybe there's literally a graph that shows each strategy that's uh that's actually really cool governance if to want is uh um provides an accurate conversion from am in way the nominating way to want it basically gives you the conversion rate estimated total assets this will provide an accurate estimate for the total amount of assets principle per return that this strategy is currently managing the numerator in terms of want this total should not be realizable a g the total value that could actually be obtained from any strategy if you were to divest in that position based on the current the total should be realizable so the estimated total assets needs to be realizable which means that it has to be um i guess conservative compared to uh other estimates that you may use care must be taken using this functionality relies on external systems which could be manipulated by the attacker to give an inflated or reduced value for the space function based on current chain conditions it is up to governance use this function to correctly order the strategy relative to its peers in the withdrawal queue to minimize losses for the vault based on sudden withdrawals this value should be higher than the total debt of the strategy and higher than its expected value to be safe so yeah the total assets needs to be greater than the total debt but at the same time this value can be manipulatable so uh basically you need to have um you know it needs to be taken with very uh attention we have is active and we actually see that active is checking on the debt ratio being greater than zero so um that goes back to uh setting the um strategies to inactive was literally setting the debt ratio to zero so that makes sense prefer and then we see the prepare return function which will perform any strategy unwinding or other calls necessary to capture the free return the strategy has generated since the last time its core position were adjusted so i'm assuming prepare return in the example that i started with with my naive example will literally be the act of divesting everything from ave because when you divest everything you are realizing uh the returns the all the interest from borrowing and uh uh depositing and then you will also call uh a function to withdraw your uh rewards as well and let's see this culture will be used in a normal operation and then this method returns any realized profits and realized loss is incurred and should return the total amount of profit losses debt payments in one token for the vault accounting okay so we i think we covered this but basically that payment should be less than or equal to that outstanding yeah i'm assuming this will literally unwind the entire strategy and make make it basically liquid so that you can use as many funds that the strategy can have then we see adjust position performs any adjustment to the core position of the strategy given what change the vault made in the investable capital available to the strategy note that all free capital in the strategy of the report was made is available for investment also note that this number could be zero and you should handle this scenario accordingly so adjust position uh and you have all the free capital strategy after the report because i'm guessing the report is called here we prepare returns or it may be colby harvest but basically you have a bunch of stuff that is liquid now and so you need to have a function that given the liquid will take the liquid token and use it for uh something let's continue liquidate position liquid up to amount needed or want of the strategy position irregardless of slippage any excess will be reinvested with adjust position this function should return the amount of one tokens made available by the liquidation if there is a difference between them loss indicates whether the difference is due to realized loss of there is some other situation at play g-locked funds where the amount made available is less than what is needed this function is used during emergency exit instead of proper return to liquidate all of the strategy so this would be the liquidated version of the function where uh it just doesn't care about the realized loss it just will take a loss just to liquidate and we see the tender trigger which provides the signal to the keeper that 10 that should be called the keeper will provide the estimated gas cost that they will pay to call 10 and this function should use that estimate to make a determination if calling it is worth it for the keeper this is not the only consideration intuition this trigger for example if the position will be negatively affected if 10 is not called shortly and this can return true even if the keeper may be at a loss keepers are always reversed by urine okay so this basically tells the keeper whether they should work or not then we have 10 which adjust the strategy position the purpose of tanning isn't to realize gains but to maximize yield by reinvesting any returns so uh if you have like a way to get your rewards you will literally get your rewards and then you will reinvest them and then tending may actually be also the the act of uh also re uh using the investment to generate even more yield so that's that now we see uh so tender is one of the most important function that we have the harvest trigger which provides a signal to the keeper that harvest should be called the keeper will provide the estimated gas cost blah blah blah this will cause if it's worth it and then this call and 10 trigger should never turn true at the same time see min max report layer private cloud threshold to adjust the strategies control parameters that will influence whether this call returned true or not these parameters will be used in conjunction with the parameters reported to the vault determine if calling harvest is merited it is expected that an external system will check harvest trigger and this could be a script to run off of desktop yeah basically it's the python script and let's see so we have harvest trigger call cost he calculates the cost in way then he will check the strategy gets the strategy params if it's not active it's not going to do anything should not trigger if it's minimum than the last report it should trigger if it hasn't been called in a while so uh it requires that the last report is greater than equal the max report delay and in this case it will return true then if some amount is owed it's gonna pay it back since debt is based on deposit it makes sense to guard against large changes to the value from triggering harvest directly for user behavior this should ensure reasonable resistance to manipulation from user initiated withdrawal as the outstanding debt fluctuates so what it's saying is that if outstanding which is the debt outstanding is greater than the debt threshold then it will return true then we're seeing that if the total assets total is we add the total plus that threshold and if that is less than the total debt then it will also uh return true so if we have a loss to report we're gonna do that and it's if we have total plus threshold is less than the total debt so the total debt is higher than the total plus the debt threshold then we return true if profit let's say total params the total that if total if total is greater than the total debt then profit is equal to the total minus the total debt and that means we earn the profit and so i'm guessing yeah we check here otherwise credit credit will be equal to the credit available from the vault and so we're gonna check if profit factor dot uh call cost is less than credit dot add profit then we're gonna uh we're gonna check these two we're gonna multiply the cost of making the call with the profit factor and we're going to check if that's less than the credit plus the profit and then we have the harvest function so harvest harvest strategy recognizing any profits or losses and adjusting the strategy position direct is the strategy is an emergency this will exit the strategy positions that's the only keeper can call it which means that only uh trusted uh individual scan we have the debt outstanding equals to vault.that outstanding then where everything else is zero if we're in emergency we're gonna basically liquidate everything with liquidate positions otherwise we're gonna prepare return which is the function we already checked which basically will set itself up to uh convert those hypothetical gains and losses into actual gains and losses and that's why we have profit loss and debt payment now we have that outstanding which will be reported for the report function of the vault we checked that already and basically the vault will tell us what we need to uh uh repay and then we have adjust position which will show us the debt that is outstanding so if there's any other amount of funds that we can use we're gonna use them in adjust position which as we said above can be set to zero so it can be also do not do nothing i guess we have withdraw withdraw amount needed it will check by liquidating so withdraw will literally just liquidate position and then do a safe transfer so we draw being calling withdraw and in fact it requires that it's called by the vault because calling withdrawal is basically uh a act of brute force because it will liquidate position to get the money even uh ignoring the slippage so uh i'm i'm if i'm not mistaken we saw that the vault has a slippage protection in it and that makes sense that you don't need to have a slippager because again you're forcing it to be called by the vault we've prepared migration which was the way to um migrate funds we have the act of migrating which changes the addresses and it should also do the safe transfer i just send the entire funds here and prepare migration should basically um remove all the funds from that and just make them liquid so we can send them around we've set emergency exit once activated the strategy will exit its position upon the next harvest and so uh it's basically going to liquidate everything and then we have a list of protected tokens override is to add all token tokens position this contract manages on a persistent basis do not include want which is already included in suite below now we have sweep removes tokens from the strategy that are not of type of tokens and uh basically it's just a way to withdraw and it just loop checks if you are trying to sweep a protected token because the vault uh the vault may or sorry the strategy may have a bunch of tokens that are not uh the want so it could be for example a avi uh governance token or compound governance token and uh it will uh protect them so it's they can't be just rag pooled even if they try beside that we have the interface so i think we covered what a vault does we cover the strategies i think the biggest thing is really the math of calculating shares that has to be the biggest thing and then the rest of the stuff is just um you know lingo uh for the specifics of how um yield farming works with the harvest and the tent function uh which you know some people may call them something like uh you know harvest i think harvest makes sense and then you would have you know rebalance uh or uh something like that so hopefully that was informational let me know what you think and uh let me know if there's any protocol you want me to cover specifically i think i'll do a uniswap v3 next i think there's a lot to be learned there and yeah let me know what you think about this format and have an amazing day i'll talk to you soon
Info
Channel: Alex the Entreprenerd
Views: 1,228
Rating: undefined out of 5
Keywords:
Id: CdPOIROu6Ag
Channel Id: undefined
Length: 119min 54sec (7194 seconds)
Published: Thu Apr 29 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.