ERC-4626 is a standardized interface for yield-bearing vaults that enables seamless interoperability between different vault implementations (like Compound, Aave, Yearn, and Rari Vaults) by providing a common deposit/withdraw mechanism using share tokens. The standard uses a share-based model where users deposit underlying tokens and receive share tokens representing their proportional ownership, with functions like calculateShares and calculateUnderlying abstracting away exchange rate calculations. The standard includes hooks for strategy integration and supports both approval-based and direct transfer vault paradigms, making it a foundational specification for DeFi vault interoperability.
ERC-4626 Tokenized Vault Standard: Technical Deep Dive with Creator Joey Santoro
Added:into enterprise software learn some like enterprise java it's funny like when i first started coding solidity people always made fun of me because i coded it like java and java and i still do a little bit but um but yeah i'm much more uh i'm much more like solidity native now um i had the idea for fake protocol as i was like dejenning around in some algo stable coins back in 2020 and then i um i went to launch day that was a whirlwind um we could talk a lot about that but i i'd much rather focus on the erc 4626 spec because that that's good that's like a pretty exciting thing that we're we're pushing right now and um and yeah we're doing a ton of other cool stuff in the tribe we just merged with rory capital i collaborated with some of the rari devs on the sp on the specification transmission is 11 and jet um so yeah like it's been a pretty like compressed journey as it has been for a lot of people and really exciting and i'm pumped to like be able to be writing an erc that i i think is going to have a really cool impact on on the space and um yeah it's really exciting to share that with you guys that's awesome man um i know quite a few people actually who sort of got into the salinity space i guess um coming from a java background and at first often yeah i think people like have issues with their style but then like they take off and it they become such great developers so it's actually quite an interesting correlation even though it seems that the the styles these days are a little different from like what java recommends um sweet uh so i was gonna ask um can you give us an a sort of an overview of the standard um and at a high level what it does where it's useful and how you see it sort of playing out being adopted and and changing d5 as we know it yeah yeah i'm i'm happy to so the original idea for the spec was a a yield bearing vault so basically um any token which like accrues interest in a native token if you have like kind of three different classes of yield bearing tokens you have um like lending markets like compound and ave and then you have um yield aggregators which aggregate various different yield sources and strategies like yearn and rari vaults and idle finance and then you have like intrinsically yield bearing tokens like like x sushi or geom where they're just like rebasing in an underlying asset through like some other kind of value accrual mechanism and you can already see that those are like some pretty diverse use cases and there is no standard interface for a token which generates yield and so um that just makes it a nightmare for integrators at every part of the stack and i think a lot of people think that this is just a problem for yield aggregators but it's actually a problem for like you know lending markets like fuse which might want to plug in collateral unless unborrowed collateral to other yield sources they can't do that without like custom connectors all over the place and same thing with balancer their strategy for v2 is to have asset managers which can re-hypothecate capital outside of the liquidity range that they're in they also need to develop custom connectors for everything so the industry is like exploding because it's green field but there's no standard so everyone's just wasting developer time and resources and the cool thing about the standard is that it's completely backwards compatible with every system that i know of and so we can just develop single adapters to the standard and developers can immediately start coding for the standard and we can retro everything back in and then eventually new versions like urine v3 and you know ave v3 or v4 or whatever like those will all use the standard but in the meantime we can retro everything back into it so it's just like a no-brainer and an immediate time save and developers say i mean also for the because they're used as a middleware though no like if urine wanted to keep the urine vault structure at least they could also provide like a 4626 yeah exactly that that's kind of what i meant by the adapters but yeah middleware better analogy like um yeah you can wrap kind of anything and then what we what we realized was actually like you don't have to be like a monotonically increasing yield generating strategy to use this interface it's really any vault that is just token in token out um so you could have lossy strategies like ribbon vaults you could have like guild farming strategies where the yield token is a different token like convex so we renamed the the standard not it was originally the yield bearing token vault standard but now we're calling it the tokenized vault standard so we're just keeping it very abstract on like what exactly the standard is doing it's just an interface for depositing withdrawing a token from any kind of strategy really that that handles a single token and the yeah we got some great feedback from some really awesome people in the industry to kind of make this a really really robust spec that can handle a lot of different use cases in an elegant and minimal way the question is if makeup will ever use it if you don't need it something like the frapple yeah i mean we're pretty bullish on maker names at the tribe so our new product turbo uses a bunch of fun maker names like gib and and slurp so i think um yeah like we'll see we'll see if they use it all right awesome awesome i mean the nice thing about this space also see if maker doesn't someone else can always launch that as a middleware muscle so yeah i mean cool so what do you say then think we should die then yeah i'm keen i don't really need to get into the code here all right so let's take a look all right so well let's we're starting off here on on the the actual interface it's just yeah all right erc 4626 how do you say it joey by the way did you say 460 4626 okay four 626.
46. having that like six yeah so it was funny we were actually debating whether we should try to wait for like a better number and we were like maybe we want it to be like divisible by 10 or something and we were like 46 30 like that's cool but it's not that cool and then we realized like the next dr was 46 26 and we were like that kind of rolls off the tongue you know like yeah we just went for it and um i'm actually like pretty attached to it now i like it there's there's a funny little piece of errata in eip1 actually that if the editors think that somebody is trying to mine a number like they're like making kind of garbage pr's so they can get her number that they have the right to confiscate that number from them but i mean it's like waiting for one to pop up it's hard because there's so many non-eip prs there and then the pr number is the one that becomes vip for people who aren't familiar with them but yeah there's some funny history around eip4444 you guys should go like read the unresolved read the resolved comments like unresolve them and like take a peek at them they're pretty funny like the editors are like always going at each other about about like you know getting cool numbers it's pretty funny uh yeah yeah yeah it sounds like it's been a big issue in the past i don't have the history on it yeah yeah cool all right so we got two basic events here uh deposit and withdraw you're indexing the addresses over there uh but not the values i mean i'm assuming that basically if you're building a subgraph or something like that on this you're very likely going to want to be able to search by address so that makes it a really easy target for indexing but searching by a particular value sounds a bit weird like you know you want to get all one token deposits or something so i'm assuming that's why you left off the indexing over there uh yeah as a general rule of thumb i usually just always index addresses if possible and i pretty much never index integers um addresses and bytes anything that's like an identifier is something i would index and anything that's like a value type you would not really index what if so there might be an age case uh what if it was like an id but an integer id would you yeah of course i mean like like the the governor bravo uses integer ids and so in that case yes you would index it that's kind of what i mean it's like that's like the general rule of thumb but really the the the practical reason is if it's an id you index it so if it happens to be an integer id then yeah like you said then awesome awesome all right so then looking into the functions we deposit um which returns the amount of shares so i mean basically again just speaking this out for anybody who's not so familiar with these structures any time you've got a tosh a token a token like say sushi for instance where you're in the sushi platform you're getting back another token called x sushi so then basically your deposit is a percentage of all the sushi that's in the pool and then the the x sushi that you're getting back just represents the amount of shares that you have in that pool and the dividends that are divided to it so for instance in sushi's case you've got sushi in the pool you you stake some sushi you get some ex sushi back but as sushi swap itself across they distribute that into the pool and it's distributed proportionately so that if you are some super whale and have ten percent of the pool you'll also get ten percent of every distribution of sushi that's coming into the pool i mean assuming it remains a static ten percent there um so that's why over here we're seeing a returns you shares i assume this and you're getting your ex sushi or whatever it would be back and then that's just representative of how many shares and any dividends that are distributed or exchanged to the amount in the underlying token that you've mistaken say is that right yeah that was a perfect explanation um so we just formalized and you know put in the spec this idea this concept of a share which is used very extensively um it's the predominant you know urine uses shares compound uses shares um x sushi uses shares so we like that we we kind of made that a first class part of the spec because it's such a common implementation cool cool so then withdraw also so with draw works by saying the amount of the underlying token that you want so for example with uh you to carry on with this example you talk about how much sushi you want to draw now not how much ex sushi you want to put back in correct yeah exactly and this is actually that if you if you look at the pr there's some debate about the naming um the reason why we went this route and we actually feel pretty strongly about it is that depositing and withdrawing are inverse operations conceptually and so they should be operating on the same value type which is the underlying um but if you look at for example the urine interface withdrawal uses the shares not the underlying so this would be confusing if you're used to the urine style vaults but um we feel that like paradigmatically like deposit and withdraw operates on the underlying and then minting and redeeming would operate on these shares and we don't have minting as part of the spec um it was a suggestion from alberto so we're we're considering it um but yeah like that's the idea rc20 erc721 and 1155 all don't do men yeah exactly so we probably won't either but there's a there's a good argument for it um so yeah what like you know if you have any opinions and you're watching this video you should go comments on the vr um just just a side thing uh this is kind of a funny question to ask but the interface the interface does compile so it honestly might not because i think the functions need to be external yeah so this the it's well if you scroll up this is actually an abstract contract it's it's it's kind of mislabeled interface okay there we go yeah okay because it it inherits from the soulmate erc20 implementation which is like an actual contract which you can't do so i just made it out you probably should drop that eye though to be honest uh yeah yeah you're talking like the i usually does mean interface dude yeah that's incorrect yeah i mean like if you read this class it's an interface but if you compile it it's not so yeah we should we will take the eye out or we'll like use an actual interface for the erc20 but yeah does soulmate have an ie or c20 it doesn't i don't know why but i need to make one for this yeah because i think like soulmate is now at least my go-to library like i'm not really using zeppelin anymore if i can help it friendship i mean and and we like we want to continue that trend with the the minimal erc 4626 uh implementation so yeah um cool well i mean hey ben if you want to be a contributor to soulmate you've got you've got some low-hanging fruit over there yeah my dad make a pr [Laughter] yeah okay so that we have withdraw from uh so then okay so it's like the transfer from this and you're doing it on uh like for someone else as in you've got address you've got alice and you've got bob so alice is the one who made the deposit then bob is the one who's withdrawing so i assume this just takes yeah okay 20 approval 3626 shares by sender so it uses the same approval system as erc20 um and since it's a soulmate drc20 that means it comes with 2612 out of the box if i remember it yeah so you have you have permit as well in the base class at least in soul mate that's not officially part of the spec but if that if that uh if that eip becomes final then we might we might also include it um i i think not including 2612 is a requirement you can always put it in as like a recommendation yeah yeah absolutely um so definitely a recommendation even if it is not like formally recommended in the spec because it's a great it's a great you know thing to add to your token um and withdraw from is actually a recent addition i i'm pushing for it after having written the router which we're going to go over i'll explain why i think withdraw from is really important um so that that is actually really cool i would be really interested in hearing that yeah sorry you you cut out for a second could you could you repeat that yeah sure handle my wi-fi situation look at different structures out there i've noticed that a lot do put in a like a set of from functionality so that alice can do things for bob and i wondered why it was so important actually so i i'd be really interested into it it's more organic like why it's important to have all of these like delegate transfer functions yeah it's not strictly necessary because you can replicate all of the actions with erc20 token approval but it is very elegant so yeah we'll get into that for sure that's i have a pin in that one because that's like that's that's my like my contribution that wasn't in the original rari vaults spec is is the withdrawal from so cool using the sushi example again that would let you put in the amount of ex sushi that you want to burn and then get back sushi tokens however many uh sushi tokens are are like you know proportional uh and then if you do if you don't mind scrolling down a bit rory um i'm assuming the next one is or wait then i think venturing um the next one is from just guessing from the nets back here uh so that again is like the alice bob scenario and then you do the view function so you're doing your view functions after your state changing functions the the uh if you don't ask of course everybody's style is different but like why do functions after state changing functions yeah i don't know i yeah i used to i used to like and also like i i wrote these pretty recently so i'm these are not like like frozen or anything like i'm definitely still cleaning up some bugs i'm sure like you know it might again it might not even compile um because i normally use hard hat but transmission is like a huge gap tools like so so i like my my dev environment's not set up for adaptables and so i wrote it i wrote it i sort of eyeballed it and then um jen wrote some tests so i'm pretty sure it compiles but there might be there might be some weird errors here and there so um we'll make sure it's very pretty and and finalized um by the time the erc is finalized so that everyone has a really great resource um for for the standard and it is i think it's pretty i think it's pretty clean we're looking at it i think foundry like obviously is is getting a lot of hype for good reason so we're checking it out yeah but anyway yeah like view functions after state changing functions i mean for the interface it doesn't really like i don't think that makes a huge difference but we can uh yeah we can move it around that's pretty easy easy change yeah so well yeah i've heard people uh say that they like to do the view functions after they're state changing stuff um for the perspective of auditors because then auditors they don't necessarily need to care too much about view functions because it's not where the exploits usually lie um and they can just sort of get to the [Music] so we've got underlying for getting the address of the underlying token so like that would be in the sushi example sushi um you're scrolling it's a little bit all over the place sorry that's a good laggy i've stopped scrolling on mine now do you mind scrolling down a bit more i can't see the functions sure thanks um okay cool so yeah we've got under balance of underlying oh which is at any given time how many like you know how many sushi you've got in the pool in total total holdings are would be the total amount of sushi that the pool would have um [Music] shares so what's this oh if i want to know given an amount of sushi how much x sushi i would get so this should return that yeah exactly and then the symmetric functions right below it and that's the last one got it so this was um so yeah a couple interesting points about this one for underlying it is enforced that it's an erc20 um so like the address that returns should conform to the erc20 spec um which is kind of unique um but obviously it makes sense because it's a it's a it's a token wrapping vault so you have to wrap a token not like some random address um and yeah balance of underlying pretty straightforward total holdings we might rename to total underlying because holdings is not like this is the only place that the word holdings is used so it doesn't immediately connect to the rest of the spec so we're we're considering renaming that to total underlying um and then calculate shares and calculate underlying are kind of replacing the exchange rate functionality that we initially proposed in the spec this was a an idea that alberto contributed in the pull request and um at first it was like uh i'm not sure it really matters whether you use an exchange rate function or a calculate shares and calculate underlying but then what we realize is that it's really beautiful to have these functions because then you don't actually need to take a stance on some kind of exchange rate or fixed point math you can you can do like different types of exchange rate calculations that are non-linear or whatever you want and you just abstract that away through the interface and if you think about it yeah perspective of an integrating contract all you you're never going to want to know the exchange rate other than to calculate one of these two quantities so you might as well just use the two calculations as the interface and not like make integrators have to do fixed point math or whatever yeah yeah cool all right so yeah like you said this is actually a really clean interface i mean we're talking about what i think that was a total of six state changers and then like five or so view functions so like yeah this is i'm impressed like you know this it's it's a really easy interface just like read get a grip on like you know get what's going on so yeah and you'll see with the router it's very clean to integrate with which is which is really like what we're optimizing for here um which is why like all of the all the functions return the corresponding value um you know the the share amount returns the underlying amount and the underlying amount returns the share amount so that when you're integrating it's like you're really getting maximum information and like a minimal interface so um yeah we're we're i think we're pretty proud of how how it looks and we think that it's it's got there because we got some experts like alberto and people who really want to see this interface do everything that they need it to do um kind of chiming in so it's pretty cool to see that like scoopy from all chemex is super excited about it like you know i think a lot of people who deal with like sort of arbitrary yield sources and making a bunch of adapters and stuff are like really wanting to make sure that the interface like addresses their needs you know very cool yeah um yeah so anyway thanks yeah we're we're pretty hyped about it what do you say we jump into an implementation yeah let's do it i'm keen yeah i would also like to add yeah the interface is so clean and like it just makes me want to start coding and building implementations of it so hold down on that yeah i've already i've already written like two or three and i have i have another one like i already i was just talking to some of my devs about one that i think is gonna be pretty cool so maybe i'll tease it later but um but yeah like we're yeah i i feel you awesome so here we are on the implementation right yeah so this is a unfinalized soulmate implementation of the of the interface um it's literally just a token wrapping vault um there's no strategy being done here it leaves in some hooks for developers to go plug in their own strategy um if we get some extra time at the end i can even show you the convex implementation that i that we're going to use for um for faye but yeah like i think just going through this is like pretty pretty ideal um so yeah it's in soul mate obviously you know transmissions 11 is part of the tribe dao huge soulmate users um all around so we are yeah like we're trying to get this in the base soulmate repost for everyone to be able to use just right out of the box get all the functionality you need um and it uses all of the logic from the rari vault so you guys should go watch the linum labs transmissions 11 and jet went over vaults um a couple weeks ago and that was a really good a really good overview so you'll see a lot of familiar code here cool awesome all right so we have um storing the erc20 token for the underlying as an immutable means that it gets passed in the constructor after that it can't be changed makes it cheaper to access uh that's the same factor i assume [Music] so like you know for the the base unit i take it that's the scaling factor like you know 10 to the power of decimals basically got it um all right so then you take in the erc20 arguments in the constructor underlying name symbol because you need to uh launch with that then underlying that decimals actually actually called underlying dot decimals in the erc20 right there on line 38 yeah that's really cool yeah i mean you can only do it if decimals is technically not part of the core erc20 spec but pretty much everyone implements it so this vault is only compatible with like full erc20 implementations but the soulmate implementation does include a decimals call so you can call it um yeah you got to be careful when you're calling it because there are some really weird vulnerabilities you can introduce but because we're doing it in the constructor in an immutable way you can like inspect your contract after and make sure that like nothing funny happened that's an interesting point also what does happen if the contract has not implemented decimals though um it would just reverse yeah it would just oh just like it wouldn't yeah it wouldn't find the it wouldn't find the function selector and if there's no fallback function then it would just revert oh yeah but wait a second if sorry but if it does have a fallback you would call fallback yeah so then you just get the return value from the fallback right so there's a good chance i could just end up blank no if the fallback doesn't i don't know if fallbacks can return data actually they probably can uh i think they can i think there's a gas limit on it though like a really low gas limit yeah it's a super low gas limit i'm really like i'm not as as evm level as like jet or transmission so i don't know the answer to that but um transmission is getting pretty beasty over there yeah yeah yeah yeah so um but you would expect there to be an implementation here and so we'll just call that this unit very cool all right so let's take a look at this we got the events um [Music] interesting this is just like a random style question um you have to check contract you can also put this in an interface um when you put events in an interface well or actually would you prefer to put events do you prefer to declare events in an interface and then leave them out in the main implementation or do you prefer to put them in the main implementation yeah i think this is one of those things where i like the repo was not final and i forgot to take them out of the imp of the implementation when i wrote the interface so um i would definitely leave them i prefer to leave them in the interface um that was i wrote the interface after i wrote the implementation because people were asking for it on the pr they were like i don't want to read all this markdown i want to read solidity so i i wrote an interface i need a mark i need a i need to link it in the pr but um yeah i would take these out you know and then you just leave the the events in the interface cool cool cool all right and then we get into deposit all right now we're going um okay underlying amount dot f div exchange rate base unit so you're oh you know what i think this is i think this is not um this is not the right implementation can you can you scroll up to the top of the page and click on pull requests um yeah pull request yeah and then updates the interface files change yes try to like view repo from this branch yeah i don't know why i don't know why this is not um i think it's the three dots on the side right next to viewed i remember right g5 yeah v5 oh you know what maybe i just didn't maybe i just didn't update this function um i'll explain what i mean when you get there so this underlying amount dot um you know fixed point division we don't need to do that here we can just call calculate shares which is one of the read functions so that's why i thought i fixed that but i must not have for the deposit function so i need to go i need to go change that because it's a little bit cleaner to read yeah but it should just say shares equals calculate shares underlying amount on line 67 makes sense nice yeah yeah that makes sense good all right cool then you get the mint it's gonna meant like you know just to keep on with that sushi example like meant your ex sushi over there for and that takes the address of shares that are supposed to get mentioned so it's like just the same standard function most people are used to from erc20 you put in where it's going you put in how much it's supposed to mean and it does that you emit deposit right there then you do the tr of the amount right after the event uh and then you have a hook afterwards after deposit underlying amount um hmm what's the after deposit doing yeah it's an empty hook there's nothing in there it's just an empty install virtual function so this is similar to the before token transfer hook inside the erc20 implementation and opens up line um the the idea here being like let's say i want to make it for example i want to make an x sushi vault that's erc 4626 compatible the after deposit hook would take your sushi and deposit it to the ex sushi token um so like the line 74 would transfer sushi into the vault and then line 76 would deposit that sushi to ex sushi so now the vault is atomically holding x sushi and you're holding shares in this you know tokenized vault rapper as in you anticipate that a lot of the times the this 4626 contract itself will not be where tokens are held i mean if you're looking at a middleware kind of view that makes a lot of sense it's just kind of moving the tokens between a and b yeah for example like we have a convex adapter in the after deposit function we would approve the convex booster for our lp tokens and then deposit to the convex rewarder um so that's like that all happens in the after deposit hook if we want to do it atomically if you wanted like that then you would just have a separate like poking function um so you can spare users some gas but um yeah i like hopefully that makes sense uh i have just a quick question here um is i i don't know if there's like a reentrancy vulnerability here if we're doing minting shares before the the actual taking of the token yeah i think this was brought up um so we may have to add a reentrancy guard and or like reorder some stuff but this is the order that it happens for rory vaults so at least it's you know it goes like line 66 68 74 those are all identical logic to rari vaults um so if you have your um yeah it's going checks effects interactions at the end so the interaction being like transferring tokens um so like the the problem is that there's a dependency but there could be interdependencies between like line 74 and 76 and that's where there could be some kind of reentrancy so um yeah you have to be careful um and we're gonna like double triple check that before rolling this um before rolling this out and we might have to take the hook out and just you know let let people kind of develop their own um hooks on top of the functions yeah just recent reasoning about it by looking at it um if you're willing to assume that the token is not malicious as in you feel like you can trust the safe transfer phone call um like if you're willing to operate on that assumption so then at least using the token itself as a vector for reentrancy on the callback from safe transfer from because that is a callback in it i won't worry about being able to call men multiple times per deposit but then the after deposit hook itself like i mean i guess the the mitigation to some degree is if they're using reentrancy out of after deposit it should mean the transfer gets called each time um so at least yeah i don't think um after deposit is is really the problem because i guess that would require you to be the the implementer of of the vault um it's it's more just like if there's a malicious token but yeah as you're saying it if there's a call back in it though my concern would be that there'd be a call back in after deposit and someone would be able to leverage that call back for it for a re-entrance e even if the implementer was not melissa potentially yeah um but yeah i think i think you've got a good point in saying that like if the token if the underlying token it's probably to a level trusted uh because you you're you're creating the vault with it and you can check it as well once the has been called yeah and of course everybody thoroughly reads erc20 code before they implement a vault for it everyone knows that yeah sorry yeah uh all right great so let's take a look withdraw uh so this is cool just like looking at this and seeing oh okay so it's going to an internal i was like wow they got that in one line of code that's really cool um but since you've withdrawn so you're you're referencing an internal um okay cool um withdraw from okay so that just has the allowance like the classic allowance check over there uh it works from message center is not equal to type you in 256 max so then basically what's happening here this is this is the this is the same allowance check that's used in the soul mate years and the implementation for transfer from so basically what this is saying is that if your allowance is that you went max then you're literally just allowed to go nuts and it's never decremented from your allowance it's like infinite approval functionality um and then if you don't have infinite approval you have to have enough approval to decrement and that's that's um that's checked arithmetic so if you under flow then it reverts and yeah um so yeah that's that's that's that's efficient condition for um making sure that the allowance is high enough yeah yeah it took me a second just like get my mind back into it but like i mean coming from nft dev it's kind of a way of hacking is approved for all into erc20 yeah exactly yeah yeah this is classic transmissions 11 opinionated implementation like um i think the uh the balancer code also has an opinionated infinite approval inclusion so it's like i think this is a pretty popular interpretation of the that makes sense the erc20 approval yeah yeah one could argue anyway that if you're decrementing off of um you like max you and 256 that you're looking for even on an 18 decimal token going to get anywhere near zero but at the same time actually it does remind me there was a bug in zk sync um on zk syncs bridge between uh ethereum mainnet and then where if you did not have max unit 256 it wouldn't let you bridge which meant that you had to reapprove max unit 256 anytime you were bridging assets this is ancient history they've fixed it ages ago but for one of the bitcoin rounds where they were offering uh zk sync integration um it first of all you just burnt the tx if you did a not infinite approve and then even if you did do an infinite approve you would have to reapprove each time i was checking for maximum 256.
so i mean the truth is it's useful for it not to decrement there at the end um yeah cool so then you've got withdrawal uh the internal withdrawal now so you've got the shares equal calculate shares um right okay fine only in deposit have you already calculated the shares so here is the first time you're actually calculating the shares you burn then admit the withdrawal have a before hook this time um comment says you want to do a before hook as opposed to an after hook here because any time oh right because you do it where you're pulling the money from yeah exactly so this is kind of you think about withdraw as the inverse of deposit so when you're depositing you're getting erc20 tokens from the caller and you're putting them somewhere someone withdraw you've got to take them out of that place and then send them back so it's kind of the inverse logically speaking which is why there's only a before hook in withdraw and there's only an after hook and deposit some people were making some good points about why we might want to put some hooks in other places so we might do that but um in terms of keeping it like minimal logically these were like the two directions optimized yeah sorry the most sense yeah yeah i okay cool wait i'm doing that yeah all right so now we get to redeem so redeem was kind of that flip side of withdraw instead of putting in the amount of the underlying token that you want [Music] the guild token or whatever that you want to put back in uh so that also is going to reference an internal function because there's also redeemed from redeemed from also the same the same allowance check then we had [Music] you were talking about before you already kept a few functions there so you can just go ahead and leverage them then you burn based off of that emit withdraw have the hook and then do the transfer right underneath that yeah so i mean like once we went through with like what's going on the calculation instead of calculating the the um the amount that needs to be burnt from the amount of shares or withdrawing it calculates the amount of the the amount of underlying that you're withdrawing from the amount of shares that are being burned and you have the 250 hooks right oh i missed one didn't i join this one no you got it i got it okay um then we get the two hooks over here so before after deposit all right cool vault accounting logic so we have balance of underlying is a particular user's the amount of sushi so to speak that a user has in the vault that does user fixed point multiplication base unit why do we need a multiplying yeah so actually this is another case where we could use calculate underlying if you look at calculating underlying it's the same logic so what you're doing is you're taking the shares that you have and then multiplying them by the exchange rate and then dividing by the base unit to scale it back oh right because that's just the shares underlying yes right okay yeah so this is balance of underlying yeah that'd be cool very cool uh and then calculate shares would be going in the opposite direction um oh right because you're entering in in there it's not an address it's an underlying yeah so there's actually a rounding error here that alberto found so we need to fix that um but there's this you know you have truncation in solidity math because you can't you know there's only a fixed precision and so um f div and f mall are not in inverses of each other because you have to ceiling the multiplication instead of truncating otherwise you're truncating in both directions and you have rounding errors um if that makes sense so you have to do what's called an f mul up which ceilings the result instead of truncating um interesting if that makes sense so that's a true inverse of f div and that's not implemented in the fixed point math library in soulmate yet so transmissions11 is going to add that and then we're going to fix that that issue funky wow yeah and there's an invariant that we define in the spec that this implementation doesn't in doesn't hold yet which is that calculate shares of calculate underlying of a share amount should equal the original share amount at all times and we can actually fuzz that on any implementation of this likewise calculate underlying of calculated shares of an underlying amount should always equal the underlying amount so you can kind of you can kind of fuzz that these two operations are inverses of each other for any um you know for any input and that that's an important invariant for the specification to hold mm-hmm um and you could do flat-out invariant testing on that yeah that's really cool yeah for anyone who wants to know more about fussing and invariant testing um tools talk from transmissions uh the like how to be adaptable chat in 30 minutes or something like that he spends a while going through like what fuzz testing and invariant test datal's foundry actually does build that in very very nicely um all right so then we have the exchange rate so exchange rate were you saying before like are you seeing every function here or are you gonna take that we're gonna keep it because we need it for the implementation we could make it internal i guess because it's not part of the spec anymore but a lot of existing implementations use exchange rate like compound and yearn so we'll probably keep it i don't know if we'll keep it public but it'll definitely stay here because it's still useful it's used in the two calculate functions above so we need it um but instead of instead of exposing this as part of the interface we abstract it away through the two calculate methods cool cool cool all right and that takes us really through the the whole fall so you really wanted to jump into the router also i would say won't we why don't we take a crack at it yeah yeah absolutely awesome all right so so yeah yeah this is a contract that's like really special to me um it's it's probably not perfect right or it's certainly not perfect but it's probably not like implementation finalized at this stage because i wrote most of it today and yesterday but um i think it's i think it's really um i think it's a really powerful illustration of how cool this spec really is um so this is a router that can take you from any erc 4626 vault to any other vault regardless of the implementation details um which is super if i'm understanding right that's like a zap zap it's a zap between any two vaults uh period i have i have y die and i want to turn that into y usdc for instance no so so rather why die to any fuse die or wide or like oh or um or a sushi or some other like yeah so it's any two tokens that are underlying that are the same you can go between any two vault implementations around that token i got it very interesting so in terms of rotating positions it would make rotating positions on the same underlying asset like super easy and you could imagine writing a router a 4626 router for any amm so what we might do is we might actually make a 4626 router for unispot that lets you go from a vault through uniswap to another vault in a different token so now you can go from one to right to another like you don't even like like you know you don't even need zapper anymore like this is zapper it's one router and it's immutable um like in if you think like that that's the implication of this contract like obviously you still need zapper for things like leverage like if you want to like you know take out a debt position on liquidy and then do some cool like you need zapper but yeah um i think a lot of zappers know just also through ui exactly and so we're probably going to want to work with with them like i'll talk to seb and see like if they want to integrate 4626 into their front end because like we're going to need some good front ends for this um but this is the core router yeah i've been thinking before like i just wasn't sure if like if i should people attention or not but um i i actually was thinking a lot about insta dap and defy saver just because those in terms of like the heavy integration smart contract wallets i would think something like this would be really interesting to them in terms of minimizing their business and because right now if you look through against adapter defy savers code there's a ton of uh just integration logic i mean if they want to integrate a platform they literally have to have smart contracts that know exactly how to communicate with the platform being able to give them something a little bit more generic so that they're able to offer platforms without having to like redo their entire smart contract suite uh and like redeploy and like make a new version and everything i would think would also be really really bad for them yeah i didn't even really think too hard about the the interface aggregation aspect of this but yeah like the d5 savers and zappers and instant apps of the world could really benefit from this interface too because they're also huge consumers of adapter integration logic that is no longer going to be necessary after um after seeing this the spec kind of come to fruition so okay what do we have here we have deposit to approve vault oh yeah so let me let me yeah let me let me explain something so the terminology is not finalized but you can think about it like this there's two kinds of vaults um there's vaults where depositing requires a token approval which is like compound style um or there's vaults which assume you already transferred to the token in the same call so like uniswap style and this router is based heavily on the univ2 router conceptually like obviously there's not a lot of similar logic but just like the way it's architected is very similar to uni v2 and so you need the two pairs assume that tokens are already transferred in to the pool before doing any swapping logic so there's no like you don't need to approve every single uni pair when you're swapping um like i not so let me like break down the user flow to make it really clear in an approved style vault first you approve the vault of the erc20 that you want to deposit and then you call deposit and the vault will pull those tokens from your wallet into the vault using transfer from an optimistic style vault we're not sold on the name yet we might call it something else but an optimistic style vault um would assume that you already just directly transferred the tokens into the vault before you called mint and then it would use internal accounting to figure out how much shares to send you um does that make sense like there's your differences there i i'm good with it i think that is yeah that you be muted sorry you cut out there yeah i'm good with it oh whoops all right cool yeah uh so yeah i'm good too that's cool i the problem with the word at this point is that i do feel like it kind of got reserved overloaded so i think we're like one thing that um transmissions and i were discussing is potentially calling it like an atomic vault so instead of doing approval it's just like you should transfer and call deposit in the same sort of atomic transaction um so maybe like i don't know what do you guys think about atomic vault we also thought about calling it like a prior vault or an advanced vault just kind of capturing this idea that like you're sending the tokens beforehand instead of using erc20 token approvals i'm like i'm sitting here i'm wondering about it like i'm actually like a big stickler um conventions i am actually wondering if maybe i'll take a page out of like you know the maker book and say that since it's so hard to find a word maybe it's just better to have fault a and fault b you know i'm down for that too um there is there's clearly two different implementations for deposit paradigms so i i wanted to make sure that the router could accommodate for either um i don't i don't i don't want to take a super strong view on how we named them but it's very clear to me that we want the router to be able to handle both cases and we wanted the router to be able to operate between both cases uh yeah so that's kind of yeah that's the idea that yeah and if you look at the implementation of these two methods you'll see there's a very clear difference and there's some clear trade-offs between each um each implementation yeah yeah because i guess what's happening on my end is like with the explanation i totally get it but even if you'd switch like optimistic to atomic or come up with different wording it's always going to need the explanation and if it's always going to need the explanation i kind of wonder if like you don't want to like make people look at this and be like optimism why am i depositing on optimism or like whatever the case yes no and we're probably gonna scrap the word optimist i was actually debating with transmissions and jet earlier today about um you know what to what to call this and so we we're gonna figure out a good naming paradigm for it and then stick to that and it's probably gonna be something that's not overloaded even if it's like a little bit sub-optimal in terms of how it explains it but anyway further for the purposes of like you know the rest of describing this contract what do you want to stick with optimistic uh autonomous whatever okay yeah cool so yeah there's um so there's two kind of deposit wrappers these are the least interesting functions in the router it's it's just a normal deposit um but then the rest of the logic is about like routing between um routing between implementations so actually if you don't mind scrolling back up to them though the one thing i really do want to get before we move on is like having a good grasp on what the difference between the two functions are over here yeah i think it's definitely worth it to dive deep on that is it just the approved step that you're sort of skipping out here there's one other nuance which is if you look at the transfer from the transfer from is going to the router in the approval step and it's going to the vault directly so so this one basically the vault pulls it in and this one sorry no the vault assumes that you pushed it in so it's like pull versus push basically yeah and if you'll notice this is where like the interface kind of really shines um the deposit function returns the amount of shares that you're supposed to receive so you can actually do a check that um you're receiving at least a minimum amount that's passed in by the user that could be zero but if you want to be very opinionated about how many shares you're getting you can you can check that extremely efficiently from like a gas perspective and from like a just a logic perspective like um you're checking that the return value the amount of shares that returns from the deposit call is less than some some minimum so that's kind of a nice like additional safety that is very cheap to add in here yeah that's pretty cool um when when do you think that that would be like sort of a needed because it's very similar to sort of like a slippage check on uni swap um so are you sort of like anticipating kind of a front running thing going on here or something yeah i'm imagining that like there's certain types of lossy vaults that might actually have their exchange rates change due to external factors such as oracle updates or even like um you know liquidations like you could think about like a ribbon covered call writing strategy that all of a sudden if like the east price moves outside of the strike price now your exchange rate goes down um there's an argument to be made that this isn't really necessary to be included but it's so cheap to include that um i feel like it's worth it but um i'm gonna run this by people that are smarter than me and we might take it out but you know definitely doesn't hurt yeah i think it's a nice feature from my end uh well are you ready to move on or did you want to look at the no let's go um just uh also joey like i know that we originally scheduled in for an hour we're able to if you're interested also yeah for sure i mean um there's really like i think four or six more functions and then you double that for the permit implementations but those are literally just the same thing but same thing permit yeah so um i'm totally down to across the rest of this all right awesome let's do it uh imagine ben actually making it through everything in one in one sitting we usually end up like saying we're gonna do it and then like having to add a second week and then just finishing everything and being like okay fine time to move on anyway so yeah i think it is a testament to how to how minimized this code is like it really is a very good minimalist implementation uh yeah so yeah yeah we've covered like three whole smart contracts at this point this is amazing for us i love it yes what do we have here withdraw to approve fault so we've got the from vault it's coming from one vault it's going to another revolt address to what is there to address if it's going from vault to vault we already have the vault oh because you're just using the interfaces and you need to know where the interface is going okay i got it yeah exactly so this is kind of like a if you if you are a dj and you're on uniswap in uni v2 and you want to do a add ascend as part of your swap this is like the add ascend so the two address is like you could you could go from like you know you could go from your die vault on compound to a die vault on fuse that you also send to ben because you owed him money so he could be like i don't want your c die i want f because i'm a fuse maxi like you go from vault a to ball b and you give ownership to ben all in the same route okay cool underlying amount and then shares out cool so be under erc20 underlying is the from vault underlying if underlines not the two vault done underlying so then okay then you revert because there's a mismatch um custom i i haven't pointed this out before but i will throw in now custom solidity it errors uh fro withdraw from [Music] message.sender to address this amount underlying okay fine um all right so that's going into the vault router underlying dot safe approve address to vault so you're approving that vault on a underlying because it's going to pull it out of here so then if two vault dot deposit is less than then shares that then reverse yeah cool cool and speak that out amazingly clearly but basically what you've got is you set up the rc20 token you make sure that you're on the same page as then the vault that you're pulling out of has the same underlying token uh as the vault that it's getting sent to so that way you're keeping dye to die or whatever the case is you do the withdrawal it pulls it into the router then you approve the destination fault on the amount and you have it pulled from the router there i'm like just sitting here and trying to figure out if there's a way to take out that middle step um why don't you have the two vault pull directly from the original vault um because then the original vault would have to improve the two volt yeah yeah there's no way to do that um if you can think of something that we could add to the interface to cut that out that'd be pretty sick but um i do think logically i think you might be able to yeah but you can't permit from a smart contract so um i'm not sure if yeah they're so i mean you're right they're permitting from a smart contract not but use okay i mean i'd have to go on a massive tangent about eip 2098 and the ip-1271 i think um like maybe making a permit structure for alternate signature schemes but uh who knows maybe you write the permit equivalent of you know going from one vault to another and that makes it into some future erc like that would be pretty sick i was literally thinking about writing one over the weekend text on 2612.
i love it i love it here's the thing with 2612 2612 split signatures into vrs bites 8 bytes 32 bytes 32 that only works on let's just call them canonical signatures like the ones that pop up in metamask and things like that there are other iep through signature schemes like eip2098 which has a 64-bit um signature whereas the vrs signatures are 65.
um sorry bite snippets um and then 71 basically creates an interface for there to be like a delegate signer for a smart contract but the thing about 1271 which is kind of interesting is it's a very open-ended signature like you can get a lot of weird signature schemes in the 127. i have to look at it again though but basic both of them are like trying to address like the ability of giving a smart contract some kind of signature um i'd have to look into them again i don't know if they help here but like that that could be something that might be worth looking into because you're right normally contracts can't generate you'd have to think of some way yeah all right maybe maybe i'll like sit there and try and think like puzzle about that a bit um i'm one like even 1271 i don't know like now that i'm thinking it throughout the help here because there'd have to be some kind of eoa attached to it that would be able to fire off six i think but i'm not sure maybe i'll try and look into that on the side cool yeah um yeah why don't we why don't we check out the withdraw to opt optimistic uh the optimistic version of the last blast function true let's see here what we get so again we set up the underlying make sure that it's the same then we have the withdrawal from from vault withdrawal from so it goes to the router you deposit in the two vault again with the error so the only thing that's missing here again is the approval like ben pointed out and then the address destination is different as in here you are directly to the duval um without without any other um without any other intermediate stuff yeah this is the same difference that we have in the deposit versus deposit deposit to uh you know approved versus deposit to optimistic it's um you're sending it straight to the vault in the optimistic case versus you're sending it to the router in the approved case yeah and that parallel exists for all um for all of these pairs of functions and guessing without looking so now i see the next function is called redeem so these two the withdrawals they take amount underlying is an argument i'm assuming the redeems are going to be the same thing as the withdrawals just with the shares and so like basically go on a quick tangent about the withdrawal ones before but you're spot on for the redeem like it's the same two functions but using the redeem paradigm instead of the withdrawal paradigm so you're living in shares world instead of underlying world yeah so yeah what would you want to say about the withdrawals right so if you remember from before we talked about how withdraw from is like not strictly necessary in the standard um because you can approximate it using token approvals but let me show you why i think it's like pretty important to include so um if you look at this withdraw to optimistic vault case um let's imagine that withdraw from doesn't exist so we have to we have to like re-implement withdraw from using the interface and the way that you would do that is you would say calculate calculate shares so you do from vault dot calculate shares from amount underlying and that's the amount of shares that you're going to need to pull into the router or rather um into the underlying in order to or rather to the two of all excuse me sorry i had to correct myself twice but you would calculate the amount of shares you need to withdraw withdraw it um from the caller to the router and then send it from the router to the two vault that makes sense so um you have to do an extra calculation you have to call calculate shares inside and then you have to do an extra token transfer um in order to basically do the withdrawal because you can't draw behind somebody else so well yeah so basically you are you're adding these two functions you're adding calculate shares and you're adding a transfer on top of the withdrawal because you have to withdraw from the holder of the shares unless you have withdrawal from it it only ends up being one extra i mean sorry the calculation doesn't end up being extra because you need to call that under the hood anyway though no yeah so you need to call that under the hood anyway but here's the interesting part so what happens if the calculate shares function is stale what happens if you have a continuous compounding like on compound or on urine where from one block to the next um you may have a different amount of value accrued but you need to have some state change in order to reflect that in the view function then you're left with some dust so if you want to be complete you actually have to like burn that dust or send it back to the caller at the end of the function and that makes it like really inelegant and kind of sub-optimal which is why i elected to include withdraw from because instead of having to deal with dust or anything you're a first-class um operator if you have token approval you can do withdraw and redeem operations as if you were the caller versus having to like that calculate everything and hope that there's no like exchange rate rounding errors or any dust or anything and that's why i think it's pretty important to include the withdrawal from if that makes sense very cool yeah makes a ton of sense very cool yeah i mean just to summarize like what you're what what you're doing as you're answering before like why it's important to have with rough run functions so that it gets really important to give them the ability to natively move tokens from a point a to a point b that's not them uh because of just different like like you're saying the state changes that that can crew it is neatly implemented that's really cool yeah exactly anything so i'm trying yeah oh no that's it yeah i'm glad you guys see it too because i i feel like um it's probably going to make it into the final spec like i said we're going to run that decision by a lot of people but i feel pretty confident that it's the right move so it also doesn't it doesn't bloat the state of the contract too much because as you saw in the erc 20 vault soul mate implementation you're using the same internal function for doing doing the withdrawal between withdraw and withdraw from so um it doesn't add like too much byte code to the contract deployment so it's probably a pretty good trade-off to include it i mean you could also look at the if someone needed inflammation where there is a massive increase in bytecode between the two if anything that's probably a sign that they actually really need it yeah because whatever extra byte code they're going to get there means that anything in the middle would have to implement themselves right and um if you didn't include withdrawal from you would still be compatible with 90 percent of use cases so it's not like it's like it's like totally strictly necessary to include it but um it is probably going to be a required part of the spec if it does make it into the spec at all cool cool cool all right awesome so let's take a quick look at the redeems then so again yeah from to uh instead of underlining shares out uh check to make sure the underlying is the same from vault redeem from instead of the withdrawal from then the safe approval to it then i'm doing the mystic got the same basic structure just sending it directly to address vault and then um this check again just to make sure that you're getting at least min shares out yeah yeah they're it's the same kind of paradigm between approve and optimistic i want to highlight yet again another place where their interface really shines here if you see like the amount underlying is returned from the redeem from call and you can use that directly in your approval and deposit logic uh uh yeah instead of having to calculate the underlying beforehand it you just returned from the redeem from call um which is pretty nice because then you know how much you need to approve without doing any fancy math very cool very very cool all right awesome man like i almost don't know what to do when i finish a contract now because we never finished the contract yeah so we're there i mean the permit implementations are literally just the same six methods we just looked at but using the erc20 or not arc20 but the the permit extension yeah exactly 2612. um and this uh this is a straight fork from the univ2 router so it uses the same approved max pool and um you know permit logic very cool that's awesome man like just this point here that you were making uh it just like shows how elegant the um the 4626 standard is uh like i'm just getting much more of an appreciation now that you guys are like diving deep into it yeah and a lot of this stuff honestly was kind of emergent like um you know obviously transmissions and jet did a lot of kind of back and forth debating about the rari vault interface and so i think the kind of these these nice little final touches that you see are things that we realize from implementing things like the router um so i could summarize kind of the differences between the 46 26 spec and the original vault implementation because that there are um there are i think three or four that are um noteworthy and we've touched on them all so the first one is that withdraw and deposit take a 2 address that wasn't included in the original rari vault implementation because um you know transmissions and jet were really hyper optimizing for gas so they were like if you want to do anything fancy you're going to do that at the um at some kind of abstraction layer on top of the vaults they didn't include this concept of depositing on behalf of somebody um but then what i what i really convince them of is if you think about one layer above if you think about routing implementations um you want to have the ability to deposit on behalf of someone as a router you want to have the ability to know how much shares you received after depositing or know how much under underlying you received after redeeming so we added these return values in order to make use cases like this just like super seamless so what i was really convincing them of is think about the routing layer think about the integration layer when you're thinking about an interface and then they realized um just these two little changes made it so much more elegant and then what alberto showed us was that using to calculate shares and calculate underlying instead of being opinionated about having a fixed point exchange rate also makes it just extremely elegant for use cases about like knowing how much underlying you need for some um you know some implementation and then like we already talked about the redeem from as well that wasn't included in the original spec so there's all these nice little touches that i think really make this kind of a complete spec that we found just by um playing around with it reasoning about different types of vaults and um yeah like i i'm sure it'll change one or two more times but i feel like we're really converging on something that can can be a really great specification for for ethereum i like i just want to point out that this is this is like what is what i find so beautiful about defy is it's so so collaborative and so rapidly iterative um that you as you say it's like these properties are emergent when you just start um plugging things together and building things out and we've had it's just like deeper has just been around for i guess what like two years now maybe three um but we have so many iterations that you like that you can look back on and be like okay so this is what was needed these are these are all these standards that are fragmented and not really compatible in the same way and then you throw this together and these emergent like beautiful properties come out and then you you collaborate with with everyone on twitter and on github and you just like it just refines these like these beautiful standards i don't know i just find this beautiful and i'm like kind of rambling about it sorry no it's awesome yeah i mean i'm everyone's really pissed at me because i keep like i keep like talking about 46 26 too much like i'm like so proud of this and um but yeah it's awesome and i learned something like i own multiple things on this call with you guys like i'm gonna go talk to seb from zapper immediately after this call and tell them about how cool this router's going to be and have them integrated on their ui and like i wasn't thinking about that before it just shows like there's even more to this than the authors of the spec knew when they set out and i've been learning new things about it every day so yeah it's awesome i can't wait to see what people do with this you should know also if you want your eip to get traction you do have to show it but it's just the way it is so like you know go out there be proud of it i don't even know if you noticed i copy pasta like this is like the peaky iep it's changed the theory and thing on twitter because i have any idea that yeah that doesn't have amazing traction um and like when annette especially was like you know this is what you have to do to get your eip out there i was like no joke i'm going to launch a 46 26 nft series and each one's going to cost 46 26 stable coins and we're going to send all the funds to like the eth core devs or something but we're gonna do whatever we can to hype this thing like awesome awesome if you're looking for a destination get coin matching price you're easy to sell option yeah yeah that was like one of the suggestions that we really liked i also um i want to plug trent's project protocol guild i think it's kind of exactly what i was thinking or something like this yeah i forgot about that what they're doing is they're trying to make like a you know so when i when i think like as a d5 founder who has you know been blessed by the ethereum ecosystem like all i want to do is is make sure that the ethereum ecosystem thrives and no one's more important than the core devs and they're like we're we're standing on the shoulders of giants and all the fun and tokens and yield farming like that's all because of the hard work and the blood sweat and tears of like an absurdly small group of people so we need to trickle as much value back to them as possible so protocol guild is literally like a dow that is sole purpose is to to to do that and what i what i like about that over like a git coin matching funds that get coins kind of a black box like if i'm gonna go match a bunch of grants i have no idea what grants are gonna get funded it's not very specific um and i'm not sure about curation or anything like that when i go to protocol uh protocol guild it's like ethereum ogs who are going to like you know this is the crap out of ethereum ogs you know and like yeah that's what that's what i want and um you know like people like tetra node and so on so i'm like really excited about this so um tldr like yeah i want to make a ton of hype about this standard and i want everyone who's like so grateful for this standard to think about why why they get to be grateful for this standard and that's like the ethereum core devs and so um that's where we want to like send all the value from this back to cool cool all right so that was a totally unrelated rant i also want to plug that i got 4626.ed and i'm really excited about it i'm gonna i'm gonna probably point the router to router.46.264626.e very nice and we're gonna do some vanity mining so that it starts and ends with 46.26 like we're we're really gonna go hard on the on the meme like 46 26 is my new favorite number if you look at my twitter handle it's four plus yeah equals twenty equals twenty six took me a minute pr campaign going hey since the merge we had the like one plus one equals three meme which is like right the sum of the the sum of the parts is greater than the whole kind of thing or the whole is greater than the sum of the parts so um we just like sent 44 plus 6 equals 26 as like kind of a double meme where we are meaning the standard and meaning the it's like it's like 10 equals 26 it's like wait that's like huge gains yeah you know i love it memes all the way down average memes yeah exactly and then the other cool thing that we're going to do is we're going to probably make a repo with like canonical 4626 middleware so that um you know the aves yearns compounds of the world like you make one wrapper and then you're done and now everyone like can just look at this repo and we're probably going to use ens for that too just really make it like so easy to adopt this standard like like i want you i want it to be like the like there's the greatest developer experience for this um so that's what we're gonna try to leverage all the tools to like you know really get it across the line in a nice way i think it's probably a good place to rap was there something else you want to add sorry yeah as you say dude if you guys want to write one or two of those rappers that would be very much appreciated and some cool pr around this like if you're if there's a protocol that's near and dear to your heart so maybe x sushi it'd be cool if you guys were with the egg sushi one that's a super simple one um just because we like talked about x sushi so much on this car yeah yeah maybe down to right the xushi one with you will if you want to do that as a little side project yeah just uh just pull what once the once it hits soulmate you know once the vault hits soul mate you literally have to like implement two transfer hooks and i think you're done like it's very very very simple yeah yeah we'll see about that um awesome though anyway yeah going over this with you guys this was awesome yeah listen thanks for coming this isn't like uh yeah awesome stuff here and um so i guess just in terms of wrapping it up if people weren't familiar with you before joey so they can find you on twitter at joey santara right joey two underscores and then santoro um i tried to buy a better handle and i don't think i'm cool enough yet for that but if you know that joey santoro or jay santoro on twitter i want their handle good luck joey 2 underscores santoro yeah um all right yeah and awesome all right so this has been another awesome episode of solidity fridays over here and catch us next week or anytime as we try to fumble our way through more solidity code yeah thanks so much
Up Next

Yearn Finance and YFI Token: DeFi Yield Optimization Explained
@Finematics
134.5K views•2020-08-31

Hybrid Key Establishment in Production: Post-Quantum Cryptography
@durumcrustulum
14.7K views•2025-08-27

Operational Security Essentials: A Guide for Hacktivists (OPSEC)
@hitbsecconf
157.4K views•2012-11-26

Understanding Ethereum: A Comprehensive Beginner's Overview
@99Bitcoins
3.1M views•2018-06-26
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Blockchain & Crypto






















![Intro to Blockchain Programing [FULL COURSE 2023]](https://i.ytimg.com/vi_webp/cGQHXmCS94M/maxresdefault.webp)




![[LIVE] How To Find Vulnerabilities In Audit Contests - GTDA | C4 Contest](https://i.ytimg.com/vi/WjCVT2hRNXE/maxresdefault.jpg)










