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

Loading player…

Security Pitfalls when building with DeFi Money Legos Ioannis Sachinoglou

Ethereum DenverSun, Oct 9, 2022, 12:00 AM

Transcript

uh thanks a lot first of all for joining this presentation my name is janis and i work for science security i don't know how many of you know chain security we're smart contract auditors so the last four years we had the chance to work with many super interesting projects and today in this presentation i want to summarize some of the common pitfalls we see repeating again and again when we audit projects especially projects which built on top of this the so-called defined money legus so i have structured this presentation in a way so that even if you get lost at any point or if i get too technical you can follow the next slide so i hope it's going to be quite interesting so yeah we all know that the last couple of years especially there has been an explosion in the number of protocols we have protocols for trades we have protocols for landing we have protocols for staking all sort of protocols and interestingly the protocols are getting more and more complex and our work as auditors but your work as developers as well has become more and more difficult uh today i want to focus on this property of ethereum of the smart contract technology the so-called composability where we can essentially build protocols i'm going to refer to them as second level protocols where you essentially create a financial model which relies on interacting on other protocols for example trading or landing or whatever and i want to point out even from this point that it is really hard and it is really challenging for developers and auditors to really understand the behaviors of all sort of protocols that they want to interact with so in my presentations i will i will present just eight of these issues that i hope cover a wide range of uh what we see and what we've seen and we might continue to see at same security so in order to make the presentation a little bit easier to follow uh let me give you a more concrete example of such a second level protocol so let's imagine we want to build an on-chain fund right so what is a fund is it's essentially a pull of money so we can store this money in an onsen uh smart wallet that's easy and we have uh then a manager who creates a fund and manages the assets the fund holds so the manager tries to increase the value of the fund by interacting with various protocols then we have the users the users want to participate and invest in a fund and for that they deposit some value and they get back some shares of the protocol and of course they need to know the search the price of the shares right and the most important feature is that we want to give as little trust as possible to the manager because remember the manager will be essentially controlling funds and assets that they don't own so what issues do we see here the first and i guess the most important issue is that if we want to interact with external contracts we essentially need to pass at some point make an external call and pass the execution flow to an arbitrary contract with which implements an arbitrary logic that we we might not be aware of this is of course quite tricky in raises a lot of security questions so for that most protocols we've seen choose to to implement these so-called adapters so what is an adapter an adapter is just a contract that will be sitting between our fund and the external protocol so our fund in order to interact for example with uniswap needs to go through the unit swap adapter make a call to the adapter and then the adapter will make a call to uni-swap so this way we manage we have like a win-win situation in the sense that not only do we limit the number of protocols the manager can interact with because we they can interact with as many protocols as the adapters that are available but more interestingly we limit the actions that the managers can perform using uh these protocols for example uh we the the unit swap adapter will implement only specific calls to unisp for example swap tokens for tokens and nothing else i want to insist a little bit more on the adapters because as i told you it's super common uh pattern so first of all as you know gas fees are really high so we don't want to deploy adapters for every fund we create right so we want the adapters to be shared among fans what this means is that the results of the result of interacting with an adapter shouldn't be affected by other entities also interacting with the adapter right because we have multiple fans that will interact with this adapter so in a way we want the adapter to be stateless another really interesting issue that we commonly see is that the logic of the adapter somehow doesn't make clear to the external protocols that the adapter is just representing a fund and it's not itself an entity that makes an investment to give you an example imagine that you want uh your fund to stake on curve uh of course you have to pass through an adapter to do this right because as we said we don't want to directly call curve then we need to make sure that in our adapters logic we show that the fund is the actual staker and not the adapter another really important point is that sometimes people forget that the adapter might end up in a state where it is not expected by the protocol for example the adapter might end up holding some funds and if this is not expected when we implement the protocol then the adapter might be useless or maybe the internal accounting might be wrong so what is internal accounting and there are a lot of issues which relate to this so internal accounting refers essentially to how many tokens a fund holds right and how the number of tokens that are held by the fund change when we interact with a protocol so it is really tempting and we've seen this many times that people use the api that the extra protocols expose wrongly for example it is quite tempting to use the return values that a function call returns to to do this internal accounting and just to give you a more concrete example imagine that we want to interact with uniswap and we want to call swap exact tokens for tokens for example and we say okay then the return value is essentially the tokens we received right but unfortunately this is not true because we might have also tokens that have faced and uniswap will only tell us how many tokens it send to the fund but not how many tokens the fund actually received this is quite problematic especially if we do this again and again so the internal accounting might end up being quite off for that people usually implement the logic this way so that the fund itself is responsible for this internal accounting and of course this requires squaring the balance and entails higher gases because of course this requires to do many reach from storage so another really interesting issues that we see a lot is has to do with trading so as we said the manager always tries to increase the value of the fund right and for this they do trades many trades many trading platforms allow the manager to specify a path to do this trade so let's imagine that we we have a malicious manager who wants to trade usdc for die you'll know that just the same day both are stable coins that are pegged to one dollar but what happens if the manager creates a malicious token and defines a path that includes this token it can make it look like we can make the first pair think that you that the malicious token is worth for example one thousand times more than usdc so if we give one thousand usd we will only get back one malicious token then since again the manager controls this token it can make it look like the malicious token is worth the same as die so when we do the next exchange we have remember only one malaysian stocking will get only one die back and of course this is not what we want because we gave one thousand dollars and we got only one dollar back so there are many ways to mitigate this some people have tried to for example sanitize the paths and only allow specific tokens but i think this issue points to the need to be quite for our fund and for our protocols to be quite thorough with how they do the value estimation or in other words how to derive the prices of the tokens they want to hold so value estimation unfortunately is also problematic uh for well-established tokens uh things are easy because we have oracles available so there is not so much room for manipulation however what if we want to hold arbitrary tokens many people have tried to rely on taxes but dexes decentralized exchanges are also easy to manipulate so for example back to the example of usdc and dye we might manipulate the pool in such a way for example with a flash loan so that usdc and i are not worth the same another point which is a source of a lot of hacks and a lot of issues has to do with the derivative tokens derivative tokens are tokens that rely that get their value from an underlying token so imagine that we stake a theorem in a protocol and we get back a derivative token which represents uh the shares of the of the vault that we staked the ethereum usually what happens with these protocols is that they expose a function a view function uh where people can query which which people can query so that they get the price of the derivative token but unfortunately if the the protocol that exposes this function gets hacked then again we can manipulate the price and either under value on or overvalue the assets that we have this is we've seen it many times and unfortunately since an audit is only limited in the scope of uh in that case of the onsen fund we are not able to be sure whether external protocols are safe enough so what i want to point out here is that we need to be really careful about which tokens we include in our protocol of course it wouldn't be a security talk if i didn't talk about re-entrance right so what is re-entrancy uh we have very interesting when an execution is interrupted and another one uh begins and both uh complete so unfortunately there are many re-interesting opportunities when we work with multiple protocols just to point you to an example many standards give opportunities for entrances for example when we transfer an erc 721 or a near c777 the receiver of the token is allowed to execute an arbitrary logic to give you an example how bad this can get imagine that we have a fund and imagine that we have a contract that holds some shares of these funds of this fund and it calls withdraw then at some point the fund will give back some tokens and it will make this call back to the contract the contract now can execute as i said arbitrary logic so what happens if the contract now does that makes a deposit if the withdrawal is not completed then our contract our fund is in a sort of limbo state and of course the the results the result of the deposit might be completely unexpected and have detrimental results of course a way to to mitigate this is with locking but unfortunately locking is not always easy to to implement so another point that we usually see has to do with reading mobility so as we said people participate in the fund and they get some shares and at some point they want to materialize uh their shares and get some profits or some losses unfortunately but how do we do the redemption can we should we allow users to redeem in a specific as a token or should we allow users to redeem using all assets that our fund holds this is a quite tricky question for example what happens if our fund doesn't hold enough of the tokens we want to redeem in should we for example exchange some other tokens what should we do the answer is not clear and it's a source of many problems the most important thing about the mobility has to do with the availability uh for redemption so there are many actions of the manager that can completely block read mobility for example imagine that i'm a manager and i get the whole the full value my fund holds and i use it as a collateral to get a loan then of course i cannot withdraw right because all my all the value is is used as a collateral another case might be that we want to for example redeem in a token which has some peculiarities in its behavior and that it doesn't allow transfers all the time and this brings me to to the last and maybe most important point each protocol is unique and it's really hard to really know all the behaviors that it can exhibit and for that you really need to go down this rabbit hole and fully understand the protocol just to give you an example of a really hard protocol to handle the synthetics protocol and this peculiarity that it has for tokens when for synthetic tokens when they are exchanged i don't want to get into more details but it's it's quite interesting and we see it really often people not getting it right another source of peculiarity has to do with uh with the reward tokens that are issued and how they are handled by the fund but most importantly sometimes we forget that we interact with protocols that have moving parts which can upgrade and an upgrade can introduce a new behavior our protocol does not expect this can be a source of many attacks so not only do we need to know the protocol when we develop it but we also need to know uh the protocol and how it changes over time so to sum up we've talked about how to limit interactions uh with external protocols how to do the accounting and the value estimation correctly and most importantly how to to be prepared to to handle unexpected behaviors unfortunately the future looks way more complicated because we have more and more protocols coming up and of course now we have many layer 1 and layer 2 solutions and there is a requirement for communication between these solutions so thanks a lot for your attention and i'm more than happy to answer some of your questions

Automatic transcript — names and jargon may be misspelled.