Live Smart Contract Hacking (Devcon4)
Devcon·Wed, Oct 9, 2019, 12:00 AM
Visit the https://archive.devcon.org/ to gain access to the entire library of Devcon talks with the ease of filtering, playlists, personalized suggestions, decentralized access on IPFS and more. https://archive.devcon.org/archive/watch/4/live-smart-contract-hacking In this break-out session, a panel of well-renowned hackers and builders will perform security assessments of contracts that the audience submits - and anyone in the room is highly encouraged to help out and take part in the audit. There will not be time to perform full-scale reviews, but the panel will discuss the contracts both from a high-level perspective and also dive into the nitty gritty details, to see if we can find faults in the implementation. This is a panel session, where we want to interact with the community and bash as many bugs as possible, and hopefully demonstrate how tricky it can be to program for the EVM. Mistakes are what makes us learn: There shall be no shaming of anyone who submits a contract for review. Speaker(s): Martin Holst Swende, Nick Johnson, Richard Moore, Matthew Di Ferrante Skill level: Expert Track: Security Keywords: hackers, builders, bugs, audit Follow us: https://twitter.com/efdevcon, https://twitter.com/ethereum Learn more about devcon: https://www.devcon.org/ Learn more about ethereum: https://ethereum.org/ Devcon is the Ethereum conference for developers, researchers, thinkers, and makers. Devcon 4 was held in Prague, Czech Republic on Oct 30 - Nov 2, 2018. Devcon is organized and presented by the Ethereum Foundation, with the support of our sponsors. To find out more, please visit https://ethereum.foundation/
Transcript
so welcome everybody to this session which is called live hacking smart contracts we're not actually going to do like depth con style hacking into live systems kind of interactive session with the audience where we discuss security that's one thing discuss it from like a high-level perspective and meanwhile also trying to actually find bugs in the nitty gritty details of the contract there will be technical glitches we will have to switch over the viewport from different laptops and stuff and hope you have some patience with that person so I'm marked in whole Sanda I work for the etherion foundation with security at the rim security and also kept development with me we've got the Matthew differente here founder of seeker labs and smart contracts auditing and yeah creeper research and stuff and we got Richard Moore authors or author of ethers ojs and also I know does random stuff and we were just joined by the awesome Nick Johnson came right from a DNS AMA so the idea is that we take a piece of code which someone here submits and we discuss it and if possible we will be very grateful if that someone is willing to come up on stage and chat with us for bids and talk about the contract and as far as I know we've received one submission so far over Twitter so is mr. Appleton present and would he like to join us in the room I guess they're not here they're not there that's a bit unfortunate because one of the things like from a security perspective that it's good to do is get a general high level understanding what is this contract do and what are the assets so we kind of have a bounds on what can be lost and what would be like the worst case to happen and get an idea on what to look out for him since this particular contract was submitted yesterday I think all four of us have probably taken at least a peek on it is that one of you guys wanna has seen something interesting sure to go from top to bottom or say what we what we think about this so it's a token contract which to most appearances is quite normal it has an owner there is a transfer and this is actually a pattern here which I'd like to race as a good example which I call the double dispatch ownership no sorry it doesn't have that [Music] so when you transfer ownership of this thing to someone else it has to check to see that you don't actually transfer it to no owner and then it just sets the owner to the new owner there's another way to do this the double dispatch is that you set you don't set the owner to new owner you set the potential new owner to the new owner and then the actual new owner needs to make a call to accept the ownership and that means that you know for a fact that the owner of the contract is capable of making their messages and interacting with contracts [Music] then we have the ERC 20 implementation [Music] and we have safe map so anything's there nothing real to mention about the safe math is kind of standard although it might be worth noting when you're looking at Elsa's contract you might want to check to make sure the safe Mac what Scott was copied over and they aren't hiding bugs in that you might just loss over I trust it and then who's that yes I think I feel like that's one thing that is like would be really helpful to have like a compiler level support for like import the code that has this hash rate right because oftentimes like yeah it's very easy to just assume this is this is fine it looks like it turns up Lin or ENS name maybe so the yeah import safe math eath as opposed to because that you guys easily lie about the hash it's well I camps like a bunch of red I mean if the tool grabs like something based on the hash like I'm thinking if I'm looking at ether scan I see like import some crazy I'm gonna trust this is safe map and not some sort of oh yeah but it says safe math dot eath I have more faith that it's like so I think eath p.m. is trying to accomplish this sort of thing and with some compiler integration that would be a good starting parade so here's the ERC xx implementation of the specification and so I'd like to ask you guys and and to give some context the ERC xx specification states that the transfer method should return a boolean whether the transfer was successful or not and as you can see and this is quite common to see that it actually never returns false it either returns true or it throws so worried what it was your guy's opinion would you make a note of this and in order to do you recommend against it to for it I would definitely make no like the problem is something another contract might be calling us to do something and I Eve called cause that to fail as a result of you know supposed to return false if it didn't work as opposed to bail out of the universe I'm of the opposite opinion ESA 20 was broken when I said that you should return false and not revert state changes if you try and do something illegal and tried to fight to get people to actually revert when you know illegal changes are made because it's far too far too error-prone to try and handle things with an undo mechanism yourself rather than relying on the vm's mechanism and if the if it's hard to handle a return a reverse in solidity then it's a problem with solidity that we should fix well I think it's also just it's probably better for the next at least the next year or two to just use the throw pattern just because you know I don't think you literally wouldn't have enough gas for non-trivial contracts to do try accepted locks right like the amount of checking I mean it's it's already a nightmare to do try accept walks in in normal software if you're trying to do with all the constraints of the blockchain and of the EVM and and like the amount of sub solidity doesn't support out of the box is I think the amount of errors will go up a lot and I think yeah the ERC 20 standard was a bit messy because i mean like this could only ever return true right I mean this is never going to return false most contracts do that so like why even have abilene at all well the original idea was that it shouldn't even throw that should return false if you tried to transfer more tokens than you add for instance and I think that's broken yeah I feel like I've been overthrown but I mean mymy Argan is even the specific specification kind of sucks we should still follow the specification and make an ER C 20 plus something that says don't do dumb things so so to be fair I don't think this is non-compliant because the ERC 20 doesn't say anything about whether you can throw or not if you return successfully you have to return true but throwing in a case of a failure isn't prohibited that's very and then like on the this is this is like a real or has been a real bad problem to compile it's not strict enough like you could for example right at least up until very recently you could write this function without ever returning true right so like take away that return true and it would still like it would just put a deer on the sack basically right silently false and then between compiler version 4.2 two and four point two three like a bug was fixed with a call data return where I guess like it was made more strict so now those contracts actually returned zero in under wire yeah so the output area is cleared before the call is made right yeah and earlier the output area was they input ordered the recited there and because so this because the compiler was too lenient and now like within if you compile a checking contract that requires wraps to require around the token transfer and that transfer goes through okay but it returns zero now like it properly allocates at zero then the like the contract will throw even though it's actually gone through correctly don't quickening here is the one lines 123 and 124 I think I can't quite make out the alignment 124 and 125 are redundant if if the sorry like 124 isn't the check that the value is less than the balances is also enforced by safe meth depends on the version of safe manner using okay yep yep for the room to hear it so the comment was the the safe mouth faison revert assert as art right it's a good question like it's kind of a philosophy question and are you using safe math because you believe it should like throw in the case of a honest mistake like the idea that if say if a safe method method ever fails it represents an error in the contract or are you doing it because you want it to automatically catch overflows for you and and one philosophy leads to reverse and the others were assert so the comment from the audience's I remove the safe math check on line 128 and I start do a regular - yeah so these are basically the same check and we'll the the one on 129 cheeks against overflow so 128 could succeed in yeah so and one important stuff to see that they got right here in this section is that you do the subtraction in addition in the right order so that you don't like I want to transfer ten tokens from myself to myself and then you add it to yourself and then you tend to it tell it wrong so you get the double if you do it the other way around and you have zero tokens you can still transfer a million tokens to yourself all right let's move on if there's any submissions coming in while we're talking yeah keep coming keep coming [Music] so it's it's not a necessarily a security issue but it is a events issue if you add to the balance before you subtract and you start off with a zero balance and you're transferring to yourself then you add a million tokens to your balance and then you subtract two million tokens from your balance and that succeeds and it emits an event saying you seen yourself a million tokens which shouldn't be possible but it wasn't there act also a case of one of these tokens where you could increase your own balance so the consequence would be that it could be read to fake overflow if you first increase the balance and you if you're transferring from you to yourself then you effectively double your balance and this kind of our flow even though that this is impossible because the total number of tokens is rather than maximum value but I wanted to comment about the safe Martin fermentation actually it's um that style there I mean this one implementation top because it allows our flow actually to happen and then try to detect it off the worse no not this but the implementation of yeah safe month right because it's heavily relies on the particular behavior of overflow which particular one we talked about for example this one multiplication right so it first allows other flow to happen client 58 right and then tries to detect it afterwards heavily relying on what exact result so it's obvious that if I / 14 happened that at Lyon 59 everything will be fine but the opposite is not obvious I mean it's hard to prove that if ever for actually happened then condition at 59 will be violated it's not that easy to understand and do you know you need to know the particular behavior of however flow works I mean what exact result will overflow return right so it's better to check before doing an actual multiplication to check that is easy check I mean you need to define marks a lot value by one argument and compared to another and the same problem I think with addition but not with subtraction subtraction is okay but like from a practical point of view no actually the other flow behavior is predictable at least in nvm but it's not that predictable in solidity right because for example the division by zero behavior already changed in solidity while isn't change in Abraham right and so we can't guarantee that overflow behavior will not change in solidity in the future despite it in EVM and will stay the same but here we rely on the particular other blow behavior instead of preventing other flow at all and so in terms of gas cost it will be the same I mean preventing overflow or detecting it afterwards so I wanted to point out something that transfer from isn't doing which is the what I consider at least the anti passion of requiring sorry not transfer from approve of requiring someone to sit there approvals to zero before they can set them to another value that was mooted in result fright of the the issue with sort of front running with transaction approvals and in my opinion the the correct way to handle that is for end-user clients to seem to send an approval to set it to zero first and then just to reset it not for contracts to enforce it because give some context on that so it's basically if if Nick approves that I can use ten of his tokens and then at some later point he says no Martin you should only be able to use spent five of them and I see his approval is on the network for five tokens so then I quickly grabbed the ten tokens and his approval comes in and I can go up another five tokens then I got 15 that's and the correct way to handle that is either with first sitting there the app either first setting the approval to zero and then back but not for the token contract to enforce that because there are for instance smart contracts that use the approvals mechanism they're doing that atomically in a single transaction so they're not vulnerable to this race condition but they will nevertheless be broken by a token that does this and possibly irrevocably broken I mean they're the contractor has increase approval on the role but then it also has approve I mean so it would have been great to just know how to prove then it wouldn't be a c20 of course so there's an increase approval is that standardized in a way not really it's a de facto standard it was an audience question - yes and nothing can stop you from doing that it prevents if it was ten and I'm sitting into five then without loss mitigation you could spend a total of fifteen because you could the teen and then I reappeared you for five and they used to be m25 it also prevents you from the other direction even are you approved for ten I changed it to approve you for 20 in this scheme you could take a 30 right because you take that initial 10 and then when I bump it up to 20 you're actually able to so it works in both directions besides setting it to zero and raising at the end of five has to be two separate transactions I think in response to the tweet was the the official submission venue yeah we can post it somewhere afterwards as well but I think he wants to know how he can get it draw the draw a submission to our attention now Oh is there a submission somewhere in some queue cool right we'll go through this a bit more until because I think there was some and then we'll jump to the next one this is the actual contracts implementation and not just boilerplate well there is actually mostly boilerplate in the constructor it says issue cards for where is that from line 255 there's a hundred of them my counter and every call to issue card here in this constructor will increase the total supply to 100 and set the balances of these hard coded addresses and then there's this and that's an internal thing so now I'm gonna call that external and then we have the bike card there's actually one quick thing I want to point out with the issue card on this part they actually did write oftentimes in the constructor people allocate tokens and don't call transfer which means that there's no transfer events so if you are writing a tool that works against like status or when those other apps that that looks at the history to figure out how many tokens you have if you were allocated five tokens for example in the constructor and a transfer never happened and you're just looking for those events don't actually know that you had five tokens so that I thought was right from zero to whoever yeah and it's also good it's also good like a reminder that the transfer event is like merely a helper writes a lot of a lot of apps like just kind of assuming transfer events as the absolute truth but I but it's good to always at least check on chain whether that transfer event were you know like represents reality right and one of the quick come on I might make as a shameless plug is there's a system called Merkel airdrops that might have worked better here for 100 maybe not so bad but you can imagine you don't want it if you're putting this out into a thousand people's hands not everyone maybe use their card it makes more sense to you to Merkel eyes it and just submit the Merkel hash and then force people to claim it if that works in your case it might not work in all cases but I could imagine situations we're deploying this especially if you want to issue ten million cards would be infeasible use the microphone cause I still has I think that if you card has a pocket here because it can lead to inconsistent total supply because if you issue card to the same address twice then the balance will be still one but total supply will be increased twice yes yes hard-coded this can be discovered at the you know at the code at the this stage where we're at but you total right that I mean in itself yes that is flawed you also very good point if I was doing this I would probably sort the cards so my inspection you could tell easier if there was a do forget one yeah I think this is a good this is I think regardless I would change this because this is an example of like very fragile code if the guy decides oh actually I don't have like you know hard coded list I might I need I wanted to be dynamic and then he changes us and then he forgets to say Oh issue card wasn't made for that and he'll deploy that and then that you know like somebody buy something once and then he'll lose like you know he'll lose one of them right so yeah it's like always it doesn't really cost it we know it would probably end up being like five more opcodes but it's it's good yeah we like it to dot and then plus yeah oh no okay yeah always always they try to make your code as anti fragile as possible just because it's it works if it's work if it's wonky but it works in this specific situation just change it so that it works in the general case because you'll forget to change it later on having been a security auditor in like general IT security one thing that I've learned is that ask a lot of stupid questions and don't be afraid to look stupid because it makes things go faster if you just spit out things you don't understand and I actually don't understand really how bike card works because here money comes in I check some stuff and it amidst an event yeah someone bought a car and then sends the money off out to somewhere else doesn't actually make any storage changes about who owns the cards so there's no like I have a little external context on this yeah the author of this contract is present at Def Con and in selling physical cards if you transfer one ether using the buy card function with a hash and then you provide him in person was the preimage he will give you the physical card right so it's a one-off purchase physically that you get the Gordon right so that's where there's no actual state change meaningful state change in the bike or function sorry along the question of asking questions and maybe you know silly but use of a pre-image for securing an asset means that you may be front-run because it's a symmetric secret meaning that if you observe someone attempting to claim this and you're not modifying the state of the actual contract someone else can observe the fact that you've emitted that transaction and attempt to perform the same action to claim the card yep so that would be a concern actually in this specific case all you would be doing is just like paying for someone else's card right because I think like the the the data isn't exactly a secret like it's not meant to be a secret right well it's a hash of a see right so even if you submit somebody's else's hash of a secret then you just want to be able to reveal it in person yes and if you're talking about front-running Lee revealed in in this case this is an innocent reveal so you would have to literally jump in front of them and shout the secret but yeah it's a good point like about hair or commit and reveal schemes in general you if you you need either the commit needs to contain some data that makes it possible impossible for someone else to front-run it such as the target address or you need to use something other than just a simple hash reveal like using a key pair so quick question I didn't realize the context of this contract but you just mentioned that how-to is house the owner actually issued the card to the person he'd hands it to them in person I move it in the contract or or they don't they're buying a physical object each of these each of these cards he's handing out has a key pair on it and each of those cards is listed in the contract here and owns one token and then he will physically give you the physical card and you will now own the key PFF owns the token representing that you have a card oh yeah they should probably be in if days yeah it's a weird I just like to imagine one one more thing on this contract before we move on to the next and if one of you guys can start bringing up the next contract so we switch over to that and this I think it's very good to have an emergen on a contract because you never know what people are going to send to it so even if you don't expect I mean you can prevent getting ether but you can't prevent getting tokens so if the tokens wind up there is nice if the owner can ship them up somewhere else and I think this kind of also nicely demonstrates a minor pet peeve that I have with solidity and it is that owner in this case is an address and doing the only butt transfer actually means you doing a call with next to no gas which I cannot is not vulnerable to rien principal so protects it if it fails it would throw whereas in this style where it's an ear see 20 interface and this looks oddly similar I mean it's something dot transfer but actually this is a full-blown call with all available gas and totally different semantics it also has a return value which you might might not read out and as an auditor it's when you're doing manual or did you have to be really careful about all these things is this an address or is this an address in the geese of an of an interface and actually a full-blown call that's that's kind of a thing that you can trip on are they are wasn't there like like a talk of deprecating that or or no a recent I'm with it I simply okay so transfer was a recent introduction to the address object is there how will you transfer to an address in future let's see okay so there anyone that didn't hear there will be a new data type payable address which you can cast an address to and it only has that method if it's a payroll type sorry so the comment is you have to make it explicit in the constructor for that happened but what I mean the constructor of what if you have an address as some objects within like a function and the function itself does not have payable it won't be registered like you won't allow that to actually happen no you can you can always send funds out from a non payable function we're talking here about whether you can simply calling the transfer method on an address and apparently in future there will be an address subtype and only that will have the transfer function too right right so this is know with the right terminology maybe it's a key word but it's like oddly so in this case it's the key it's a synthetic thing which has been added the syntactic sugar on the address type and this type it's a method with an actual concrete method called transfer on an external account and for security there are very different semantics and they matter a lot yeah so I've had a couple of people sent me things and tweet diems I only have my phone here so please send them to other people as well yeah while I well I set this up you just describe what the contract does if you could yeah so everybody my name is Brennan we've created a work we've created a work contract so that you can deposit tokens in it and then be eligible to be selected to complete work so you say deposit a thousand tokens and then now you can start working in some capacity so it's still a work in progress so I think it's gonna get shredded but the idea is that you you to positive so amount of tokens and then the work manager is able to withdraw from that deposit for jobs and as soon as that deposit drops below the size of the jobs requirement like the stake then you'll become suspended and so you have that forces you deposit back into the contract to refill your your work tokens so if you can imagine it's like the work deposit is sort of that is the number of jobs you can have on the fly if you will so so there's a few things that we haven't implemented like being able to withdraw but or sorry I have a having a restriction on the timer but I'm not sure if it's absolutely necessary so I guess I'll hand it off to you guys to have a look so so that is there is there Nate in Utah margin or are there like it's I've actually left that out it's just er c20 so you can just you know in say okay so will will this thing be dealing with assets of value such as ether or whatever valuable token just a custom work token that's the custom work token yeah so at this point is there anything you know what what are the asks are there any assets that are have value no just the inherent value of being part of the work contract so you can participate in the jobs so that the value exchange is outside of that you become eligible to take part in that value network by staking tokens in the work contract so alright yeah and who are the difference actors in this model so you have someone who does work yes so you've got the worker who stakes the initial deposit you have the job manager who's responsible for pulling out the the job deposit if you will which is gonna be smaller than the initial deposit and then of course you have the owner of the contract you can deploy and the owner of the contract is this any do administers administrative stuff on the contract mm-hmm like what if I recall there's a couple weeks ago I believe it's just instantiating it and then there might be they can set the stake limit for example right right yeah there's a few public variables that you can that you can adjust so hopefully it's small enough for you guys to croc okay so let's see um where would a user what would be the first action our user does let's deposit stake okay so let's go it's quite hard for a lot I have to look at through different things so the owner is just like an admin that manages this okay so okay so the owner deposits their stake and it seems like they get tokens just bought it I mean sent back to them right yeah and just to add add to this so the the worker has to approve the the transfer before this deposit stake is called so one thing I noticed in the deposit stake is it doesn't seem to care whether it actually succeeds like token uh transfer from you might have the allowance but you can yeah there could be other restrictions like can't send to a contract address or something weird like itself or you might just not have enough tokens great this ambiguity right where if this token is actually an implementation of the ERC 20 specification which conforms exactly to the letter of specification and this transfer from fails and returns a false we just don't care about that yeah so it's a it's a case of being liberal with what you accept and careful thought you omit if you call transfer you should always write that in a require yep yeah the the check for the allowance isn't necessary because the transfer of call will fail if you don't have an allowance and in this case the the check for the allowance is actually call out to another contract so there's a minimum of 700 gas plus trance state reading fees all right yep so yeah always wrap your important stuff in requires which again is the sort of thing you're talking about because transfer and solidity is explicitly doesn't require you wrap it and require also one thing here so going through the scenes since that deposit stake cause the deposit function if you're gonna use if you're gonna import safe math and use it in some places best to use it everywhere consistently at least in my opinion because otherwise it's if you get used to seeing mixed code you know mix it some safe math and sometimes otherwise not it'll it's also to become become too easy for you to look at a line that needs safe math and then just ignore it because you're just used to you know like the cognitive overload of like keeping track of what which threshold am I using safe math on you know it's you can easily get mixed mixed up as a more generic thing I want pointed as well like a lot of auditing is just kind of getting your head wrapped around with the contracts trying to do the first place yeah going back to the description like it's a yeah that's kind of why being an effective auditor ties well together not being afraid to ask stupid questions exactly yeah yeah oftentimes like the the biggest vulnerabilities are the ones that are most obvious or the ones where like you you know you're reading the code and it kind of it's structured in a way to make you believe something what that isn't actually true and so you know like when you get that inclination to be like oh should be really this should be should this really business this way it's important to like you know voice those concerns and actually act on them super being oh I'm sure that's fine nobody would get that wrong you know like you know we've seen some pretty pretty drastic outcomes based on you know that kind of right mind said two lines being flipped yeah our message is like the other way around so it should say steak is over a limit because that's what it throws when it fails no no this is an error message that will be thrown right so it should what went wrong but he stated what was violated yeah I I agree with you but I can see the the other side because you can imagine the output would say fail and then explain what was supposed to happen it's I this is a question going back maybe like one or two steps when we were talking about wrapping the transfer function and a require is that like a general good practice for when you're making a call out to another contract function that you should wrap it or acquire if you don't have some other mechanism to check to be sure that it's exceeded yes or like it I became yeah I mean it that's a good question so like definitely don't take from this that you should all anytime you're always calling out you should always represent our car because that in itself can create vulnerabilities right like if there's a contract for example that I to rates over a bunch of addresses and it wants to give a payout to each of those addresses right if one of those addresses is a smart contract that's malicious it can just throw the moment you you give something it and then you you send something to it and then all the other payouts are stuck because of my malicious contract and I could blackmail a with that saying now you're gonna you're all gonna send me one either otherwise I'm gonna block your to either payout forever right so you should always you should first first of all I try not to do that loop contract which is bad but besides that you should you should wrap things weren't requires if and only if that line failing is just critical damage to your contract right if it if like if this line fails then nothing should happen right otherwise try to catch the return right if there is a return you need to be very context aware yeah it looks like important has something yeah so I think isn't there an hour program on in deposit Texas I mean internal function but an overflow because the balance the amount is you in 256 which arrives from a couple of lines above and it is addition there without overflow checking it will overflow the new balance will be below the stake limits or well not necessarily so or maybe necessarily from from a quick look through I think all the places deposited called the amount of seat by the smart contract so it can sure you know that last total suppliers not overflowed but it's it speaks to talking about making ng fragile code we you should add these chicks even if you don't think they can happen is the code more readable even if it's gonna be guaranteed it's nice for a read really point of view just scroll up a bit so we see where it's called the deposits so there's one a deposit jobs take as well yeah it's called a few times so that calls deposit but required stake there comes from public as state variable contract and I guess that's the only one there as well it was required several calls to it but an HS I think it comes from a state variable yeah yeah given the context that's fine but it's not robust yeah yeah and I think this is also another good point I always sort of suggest that if you have multiple functions right calling a lower-level function or like an internal function and there is some a security issue that could arise if those wrapping functions do not do a performance or an action in this case making sure that the allowance is within a certain value then you should absolutely move the track or the constraint to the shared function right so in here for example like you know buy buy buy work wait by you know putting safe math here you you take away an overflow vulnerability from any function that uses this function and so the people you know when you're extending in the future when people are billing against your API they don't have to have the cognate overhead of or oh this function is vulnerable to overflows right so if there's if there's a mitigation that you can build in that's you know the where there's an issue that's suffered that multiple functions may suffer always put that mitigation in the most deep function call another question there's a function a a select work or I assume the goal is that that gets called off chain the select worker function does that get called off chain no it does get called on by something else that supplies the entropy okay by a another smart contract then essentially the job manager right one thing to bear in mind there is you may not be selecting uniformly at random because of your range the range of your random values is modulo of the size so probably a better approach would be to expose the number of stake is expose a way to index the stagers and then let the caller figure out how to select uniformly at random because this hides the fact that it's doing modulo and you think it's just you know magically gets an even distribution if you google modulo bias you'll find a nice concise way to take the backs minus the modulo minus the size it's like a little more complicated but you you defeat modulo bias and of course if you're doing the chicks on chain doing the pseudo-random generation on chain and all the usual caveats about apply and yeah and this is also vulnerable to a front running if you can you know increase the length of the stagers before that select worker gets a called yes so if you are off by one from being chosen yeah yeah so I have a question will you be using some kyc system for the workers okay it depends because if you won't the stake limit does nothing it's it's not the steak limit you know telling me the maximum steak so much my chance of each worker can be get like bypassed by just registering with multiple addresses inside the steak limit so it's not super resistant without a kyc system right it's funny we actually explored that because we were considering letting people have a lot of steak and then wait the workers proportionally according to how much steak they have but computationally that's a that's not that's very challenging because basically this is a one for all the operations and best to Bo n depending on how you want to balance read optimization versus write optimization so we decided that kyc be damned I guess we just let them if they have a million they can stake that many addresses so but it's a bit again I think it's kind of outside the scope of this it depends on how you want to use it but you you bring up an excellent point I think I mean the stake limit is the question was wouldn't it be better to get rid of the stake limit then so you can stake as much as you want and that's still an open question that we've been talking about because really if you can just only do one job at a time then really you only need like the job stake amount minimum yeah and I think it's something to keep in mind in general when you're doing these sorts of things is to keep in mind because that's definitely an issue like wooden people can be mole when many people could actually be one actor and this is a pattern we do see a lot is people just trusting no no one address means one person but like you said if if you have a million addresses and there's only two other workers you have a 1 million out of a million a 2 chance of being picked for this things alright should we so we got one tiny submission the wicked we could take a look at that we have like 10 minutes left alternatively we could just talk about our favorite piece thanks guys yeah this is pretty small pretty straightforward and I wanted to kind of kick off the discussion I mean I think all of you will immediately see what I'm getting it [Music] 9:21 so I I mean given that there was some changes in the new open Zeppelin version 2 and so on in this direction I wanted to kind of kick off the discussion towards reentrant see protections and so on and what all you guys think about that given that you were also partially in Worcester State and so on yeah so I think the first thing is that this contract is you know like just generally stop doing this you know don't check if things are contracts there is no way to there's no way to do this on a theorem that's foolproof there is no no no well actually you can prove that it's not a contract by checking that the message that sounder equals origin sure but you cannot prove that it is a contract it's like when the big issues is current factual I can compute the address a contract will live at and now I can use that but in the future becomes a contract so write a 50 X origins equal yes and but I think in general it's it's I think it's an anti-pattern because we want to build a system that is interoperable and if you can't build a secure contract unless it's being called by an externally under count then you need to rework your contract so it is right and this was for the mechanics of this Nick you wanna yeah so if you call self-destruct the contracts code size will be 0 even though the contracts are still call of all for the rest of the transaction so you could exploit this by having your contract self-destruct itself and then called us and then do a entrance e and then die afterwards no no no no no the X code size will not be 0 and I get back to the end of the yeah the X code size would still be the actual code size until after they but the constructor that's it yeah because they construct during the constructor right then the exercise of that address will be 0 and I would still not I don't know the TX Orion thing doesn't make it's not a comfortable essential for me long term because like for example what if we have to text abstraction in the future right like the you know things coming from the unsigned address that there may be actually be code there because I'm a countess depending on how its implemented in the future and may count the stub us code there is actually I think maybe only one foolproof future-proof way to do this which is check the hash of message sender against a signature of message from that address right because smart contracts obviously anything that is a public contract can't have a private key so if you if you make sure that you get a signature from whoever's calling then that's that's like a I would assume a foolproof way probably yeah who knows what well is he moon math will having a few million I mean I think in this particular case it might not actually be exploitable because it didn't realize they calling the thing as asserted wasn't a contract so if it's still in the constructor it has no code and you can't call it back yet but I didn't touch that so what was the idea [Music] yeah in this case message sender has no code it so works cuz it's just a valley transfer yes but it can't be exploited very entrance II which I assume is what the author was worried about question actually can you set the unit code to be empty so you can have a contract with no code yes you can you can just literally return zero vibes great so that idea by the way with that depends on that the idea that for a transaction a later transaction they cannot have a zero code size again because the constructor will not be run again and if it's in a different block and that is true for about another month but then we have create two coming we kind of changes the semantics and the pattern of contract creation a bit so that and it will have quite an impact on security on the security aspects of how you deal with external contracts and assumptions that you can make because it will be possible to take down a contract and replace it with something completely different on the same address through the use of loading the actual body code from an Oracle on chain in the constructor because address is determined from the from the init code and not from the actual runtime byte code and actually I take back what I said before I'm smart contract there's technically and extremely statistically unlikely possibility that you can create as more contract address that you have private key to there's collisions in this in the name space but it's meteos simultaneously has ev'ry etherium practitioner in the world unlikely yeah yeah what I mean you know possible yes yeah I mean it's it's like getting that collision is like you know one in ten billion universes please don't do it please please don't do it because it's systems are much more useful as they can be interacted with by other systems than if you try and enforce that they can only interact to us by users we kind of giving up on security do you think the interview happened everything that we think is the reentrant egad structured like this where it can only be called by external code yep so I would call like a mutex like a last like a last resort it's better than this but it's still like you should be able to write your code without mutexes if you really can't then actually mutexes will get more efficient in the next hard fork because of net gas majoring yeah yeah but be careful yeah everyone read up on create two because that's gonna break a lot of assumptions you guys have a lot of opportunities as well yeah so they're like only a couple of minutes and the next team are back to back so we can have like one more question or so so why wouldn't this contract be vulnerable to reentry couldn't I just call deposit and send in the constructor of the contract yes but if you call seemed then it will try and call you back and because it's in the constructor you don't yet have any code at that address so it won't be able to be reentrant yeah the code the way that he theorem works is that the constructor returns a string of evm bytes and only at the end of the transaction or those okay go to the contract Thanks don't have time for one more what's the best way to with transferring some value to set the gas limits the easiest way is to use dot transfer which saves it to the minimum which is 29 Amick if we want to choose the limit and not have the 21,000 in solidity you can do a function named gas in brackets and then second set of parentheses for the function arguments but the thing is even if you do if you provide zero there is always the 2300 gas the only sleeping transfer value yeah you have to send at least one way yeah but generally generally it's friendly just seemed at least 2300 guess even if you don't have to because that way they can log events which means you know otherwise it can even no effect whatsoever I think that's all we have time for yes thank you guys
Automatic transcript — names and jargon may be misspelled.