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

Loading player…

Secrets of Uniswap V4: A Deep Dive into Hooks Security - Damian Rusinek

NapulETH MeetupThu, Oct 9, 2025, 12:00 AM

Speaker

Damian Rusinek

NapulETH 2024 Open Village

Transcript

here and my name is Damian I'm co-founder of composable security we provide security services to various web three projects um you may know us from scvs which is the first security checklist that we have uh created uh back in 2018 2019 um and of course we do we do audits so I'm a security researcher and today I'd like to show you some uh security insights on Unis swab V4 which is going to be released next month so they're are they're they are at this like end step of their security Journey now so just before the release and I'll focus on the architecture so the differences between V4 and V3 and also show you some examples of the security threats and how to be secure simply so let's start with a simple question who knows this equation raise your hand all right so this is of course you need V2 the first the most common I would say version the the big success why because it was very simple that equation was like the core of their project right that was the core of V2 but it had the downside the inefficient liquidity uh so whenever you put any liquidity in Unis swap V2 you put it on the whole range so most of the liquidity is almost never used right so that's how the uh V3 has risen right the main thing about V3 was this concentrated liquidity so you put the liquidity in a specific price range it made uh the your liquidity could be very easily fully used right and you earn more fees so that was the down the upside the downside was that now you cannot use erc20 to represent the liquidity so they had to use nfts to represent the position whenever you add liquidity uh so the architecture of the of V3 was that you had this Unis swap V3 Factory and whenever you wanted to create a new pool uh you had to call it and it created like like deployed a new pool so each pool was a separate contract in V3 then when you are a liquidity provider you have to use this uh helper contract which is called uh non-fungible uh position manager that was official contract by Unis swap apps and uh it calls the uh pull Unis swap pull on your behalf the Unis swap pool does the Callback and the Callback is handled in this non fible position manager so you actually uh it's transparent for you as the user right even though there are those callbacks uh there and then when you do swap uh it's very similar you also have to use this um helper contract called Swap rter and uh there is also this callback mechanism oh you cannot see that much but basically you call the swap function uh and it calls back your swap router and the swap router like handles accounts your your balances right and now like over 3 years after V3 has been deployed there is like 90% of the new pools that are created are still uh V2 right and also there is still like over one and a half billion of dollars of liquidity in V2 so that's the idea behind V4 one of the ideas because the goal here is to make it even more gas optimized than V3 now to make it customizable and uh also attract LPS possibly to move from V2 and V3 to V4 because now V4 can also be a V2 and I I'll show you an example in a sec and there are some changes I'm going to cover them on future slides but one of them is the the big one right the the transing storage which came with Denon uh that allows you to really decrease the gas cost of some operations like semi storage operations let's say so what's the first difference the first difference is the pattern used in V4 so there is there are no more multiple um pools multiple contracts for pools there is one contract that manages all pools it's called pool manager so it stores in its storage mappings uh information about all the pools it has all the uh tokens on it like all the liquidity is in one contract then you have this contract this helper contract called uh pool operator which um has this lock mechanism so it it's not um it's not like you make a call to add liquidity and then get call back from the pool but now you you make a call to unlock function the pool calls calls you back with unlock cack function and from this point you can make a a lot of different operations like minting liquidity removing liquidity swapping doing whatever without more callbacks you do it directly on the pool manager and in the end the pool manager checks whether your accounts are uh settled so you can you cannot owe any money to the pool manager and pool manager cannot owe you any money it has to be cleared and then it's successful right so it's it's not reverted so this is this locking mechanism and also flash accounting because you can make those operations on multiple pools you call the same contract multiple times but do the operations on multiple pools multiple assets asss multiple fees whatever you want H and then the biggest change the hooks so whenever you make a um operation on a pool uh the pool can have a hooks contract Associated so and then if if there is a hooks contract um next to the pool it gets called on multiple operations before and after swapping before and after adding liquidity before and after removing liquidity so it's not like it's always cold but it can be called The Hook contract tells the pool manager when to call it with this with this Flags so if the hook has set flag for example before before swap flux Set uh then the pool manager will call this before swap function or before initialize function just before the pool is being initialized and this also gives you some uh additional power as the hook contract because you can manage the fees now so you can even change the amounts being swapped and return to the user and if you set the change the the amount to be swapped to zero you can actually do any other curve so you can cover any other curve in the hook and just simply saying that we will not swap any tokens on the unisa vory pool so you can have a pool which is function uh functioning pool without any liquidity on it because the liquidity stays on the side and is used whenever you need it just as an example so now let's move to the meat the security of V4 we have done a threat modeling session for uh for V4 and uh here's an example of some threats uh all those clouds are the threats and today I'm going to focus on a few of them uh specifically on six of them and just move forward because you cannot read it now so the first one is unauthorized direct call to hook contract and here is an example of a hook this is a full range hook that you can treat as Unis swab V2 on uni swab V4 because whenever you uh whenever you add liquidity to a pool that has this hook it uh puts the liquidity on the whole curve on the whole range so like UNIS too right and also it creates when just before you initialize a pool it creates erc20 token uh that represents the liquidity on this on this curve so you can think of it like Unis swap V2 on Unis swap V4 but the problem here is that the before initialized function so one of the hook functions it is external because it's called externally by the pool manager right so it has to be protected somehow in this example It Isn't So anyone can call this before initialized function it should be called only by the pool manager when when you when you initialize the um pool uh so when you call the initialized function on the pool manager but now anyone can call it and simply what happens if you call it again directly it creates another erc20 and overrides the previous one so if somebody added an liquidity uh they got the previous year C20 now when they want to remove their liquidity the the contract will try to burn erc20 but as we called this before initialize directly it's not this erc20 anymore it's on a new one without any balances so this burn will revert and you will not be able to withdraw your liquidity so your tokens are locked how to protect from that simply add a modifier which is uh which checks whether the call comes from the pool manager so only the pool manager can call uh your hook contract and actually that's it for this threat another example is on the other side so it's also an unauthorized call but to the unlock call back so the call flows looks like this there is a user he calls some uh function on the pool operator which is this helper contract used to operate on pool manager and the pool operator calls the unlock function and passes some operation some some some data this data is returned in unlock callback function and then pool operator knows what to do right so that's why it's needed uh because you can do any operations in the unlock callback you cannot do any of them before you reach unlock callback function so what happens if I try to call this unlock callback function directly by some kind of malicious contract or by Me by my EA directly if the pool pool operator doesn't protect unlock cack function I can make it any operation for example in in this example I can make it withdraw the liquidity on behalf of some victim and transfer the tokens to my address right so the protection here is very similar you also make sure not only in the hooks contract but also in the pool operator contract uh that the unlock callback function is called only by the pool manager only pool manager can call your unlock callback function and like there's no case where uh somebody else might need to call that the third case is a bit more uh complex and it's about reinitialization of the of the uh hook so here is an example of a different hook uh this is this is a hook that uh calculates some Dynamic fees right so Dynamic fees is one of the features of um V4 so they want to achieve that and here you can see that the before initialized function is protected there is that that modifier called the pool manager only right so nobody else can call it we are safe but well what it does it simply takes some pool key from the uh from the pool that is being initialized their current price and uh the block number when it started when it was initialized right and also the hook itself is a kind of pool operator because you can add and remove liquidity uh through through through this contract so you as user can have liquidity calling the hook and it does it on the pool and then you can withdraw liquidity and when you withdraw liquidity you actually are making the pool operator uh calling the pool manager with this specific pull key that he saved during initialization right so you initialize the hook with the pull and then on this pool this hook will operate right so what happens if you try to initialize another pool with the same hook right so it's completely different pool because you cannot reinitialize the same pool the only thing that you do is that you use the same hook address as the hook contract for the other pool if you call it again like if you initialize another pool with the same contract it will the pool manager will call before initialize again right so it will again override the pool key so when somebody wants to withdraw their liquidity the pool operator will not try to uh make a call on the correct pool uh on the correct pool the initial one it will do it on a new one which is probably a fake one because you just want to lock their tokens because that what happens right their tokens are uh locked so to protect from that you must use mapping well you can either make sure that only one pool can be um initialized using your hook or if you want to support multiple pools you can use mapping to store specific data related to the pool in this mapping with the key of pool key right like on this example with pool data oh there's a typo here it should be pool data not the pole data okay number four impersonation of the center here is an example of interesting case uh a hook that wanted to make sure that nobody can get more tokens that some threshold so you have a token and you just want to make it make sure that it's not collected in one address not too many tokens are collected in one address so there is this after swap hook function that gets sender parameter and what they do here they check whether the balance after the swap whether the balance of this sender is over the threshold if it is they revert because they want they don't want that right but if you look at the call Call's flow uh flow you will see that the user which they think is the sender actually calls the pool op pool operator pool operator calls the pool manager and then pool manager calls the hook so when the pool manager sends the sender to the the uh to the hook they send the address of pool operator not the user right uh okay so the the hook the creators of the hook think that the uh the sender is the user while it's pool operator so that's the uh that's how you can bypass their check very easily but there is no impersonation yet right so stay with me how can you fix it well your PO operator can actually get the message sender of the user and send it in the hook data so it's it's it reaches pool manager and is is sent back to the hook so that's how the hook can know what's the real address of the of the user and what if I used a malicious pool operator and told the malicious pool operator that uh they should send not my address but the address of some victim this will be sent to the pool manager and pool manager will send it to the legitimate hook and if the legitimate hook doesn't check that they will think that the victim just wanted to do some operation and a great example of such exploits is uh abusing uh approvals if there is an unlimited approval then you can easily exploit it this way and last two things the first one is theft via Dynamic fee so basically the fee can be up to 100% if you think that the hook can be malicious it can set the fee to 100% if you try to swap without uh simulating the swap you will lose everything right and then uh another thing is that if the hook is not malicious you can actually um end up with the fee being more than 100% they tried here to calculate the fee if you reach any situation that makes you makes makes your Fe over 100% you have a denial of service because pool manager will not um will not uh allow to do that they will revert any further Swap and last thing uh quite easy but I have to mention that the upgradeable hook so the hooks can be upgradable there is no like protection from that there are those permissions so still there is some kind some layer of security but still the the logic can be changed for example to 100% fee so so we still have to remember that the upgradeable hooks is a real security threat so I'm not going to go through that because I'm running out of time so if you want to have some great takeaways take picture take picture of this slide and you can also find me uh on Twitter or X whatever you however you call it uh simply scan scan this QR code and you'll find me there and you can ask me any questions so if you're building or or uh want to build a hook uh that's that's uh good thing to to connect and ask some security related questions and last thing we did a security research for uniswap foundation on uniswap V before so we've got a series of blog post on our uh uh in on our blog so you can check it out it's on our composable security blog and that's it from me thank you thank [Applause] you we have time for one question if someone wants to ask use this opportunity yes please go ahead David I just uh about what is your gut feeling that the evolution from version three to version four is uh increasing the let's say complexity and the surface of attack and if this is well balanced with the new opportunities that's probably the the protocol the foundation they they foresee yeah so actually this question is asked multiple times uh almost every time I give this talk yeah so it's it's about the modularity right uh all projects are now being modular and give a lot of um power to the components to the Legos that want to integrate with them right and also they delegate the risk uh to those uh like to hooks hooks can simply steal your money if they are malicious so uh there is a bigger opportunity to build on top of them and bigger risk but what we H proposed in the research is to build some kind of framework for users and Builders uh to rate the hooks because for yeah of course simulation like anyone who wants to build a uh front end application that uses uh unisp before will have to do simulation before to show you what's the outcome right because the logic in Hook can completely change uh the the logic of um of Unis swap right you you may not expect what's going to happen so that's why we need simulation and then uh the some kind of dashboard um that shows you that these pools are let's say blessed because they used uh very well-known implementation or there are no hooks so this uh these pools are like V3 basically these hooks are very common and were audited and are safe there are no risks uh like we've CH because there are for example fixed um fee and here are uh hooks that bring some some risk and like simply be aware of the of the threats that come from that thank you so much thank you

Automatic transcript — names and jargon may be misspelled.