 One line of code spurred a series of momentous events in blockchain history the line of code in red It was moved up to where the green line is and That was done to neutralize a re-entrancy exploit In the following line reward account dot payout Which when performed on an attacker's account would Would lead to what happened to the Dow The description for this talk was before these momentous events and There's too much security advice to share and not enough time that the BTC relay portion of this talk is omitted Here's a bonus tip label your untrusted contracts so in the Reward account dot payout account line Already you can see that there are two accounts here, and it's not as clear maybe immediately Which account is untrusted? So a better way to even rewrite this Maybe is to reward account dot payout untrusted account and Then when people see that It can help help you be more aware of what might happen and As an additional tip Message sender can also be untrusted so If it's always untrusted then you definitely need to put a comment in your code that Just to make people more aware Namil Dalal Simon Della Ruvier and I starred the committee resource for smart contract security tips We're grateful to seven others so far who have Our list as contributors in github The emphasis is on community Because security is not just for a handful of developers to write about and the content needs to be aggregated and easy for people to find Instead of being fragmented and scattered We start with some points about general philosophy before extending much further and getting more technical The first point is to prepare for failure The first this is not about defeat or giving up This is to try to be ready for the unknown unknowns This can be very difficult to do But it is possible in some cases and the next slide is an example of this The second example the second point is to roll out carefully Production a production system needs baking time in production The strongest swords are forged by repeatedly Processing them in the process of putting them in fire and hammering them. It takes time So for contracts, they should be put through test nets and then a beta on main net before a production launch on main net Keeping contracts simple is an obvious tip But the process of simplification can lead to surprising results even in a system that already looks simple To stay up to date There's a bibliography at the repo for the community resource that everyone is welcome to contribute to Be aware of blockchain properties is what the rest of this talk relates to as promised Here's an example of preparing for failure The contract keeps track of its expected fund balance Check-in variance throws if the actual balance of the contract is smaller than the expected balance and This check-in variance is called at the end of some of the key functions in the contract Now the emergency call Sends the balance to the workshop account Only if the invariant is broken The invariant should not get broken But just in case it does The emergency call will send the funds away Anyone can invoke the emergency call and the plan is to have a server call it every second If there is a breach that the contract's balance is smaller than what it expects The hope is that most of the funds can be sent to the workshop Instead of being drained to an attacker Contracts Calling each other is powerful and can lead to emergent use cases But care must be taken for external calls that a contract makes The recommendation is to avoid calls to untrusted contracts as much as you can Untrusted means any contract that you have not written This is because if you call someone else's contract They or one of their dependencies could accidentally call a malicious contract in The chain of contract calls All it takes is for one contract to make a mistake Thus Assume that untrusted contracts are malicious Avoid calling do something or address dot call on an untrusted contract The key point is that after any untrusted call Assume that the state of your contract has been manipulated Here's a diagram to help. There's a few things here, but let's start at the foo function It decrements X and then it calls a an untrusted contract The fallback function of the untrusted contract executes and it can call foo This is an example of recursive re-entrancy It's important to realize that re-entrancy can use any of the contract's public functions Meaning an attacker can re-enter using the function g or bar This is why after the untrusted call The contract can't assume anything at all about the values of X or Y Second tip is to use send and avoid call dot value If you've seen examples of vulnerable code especially regarding re-entrancy They all involve call dot value Because using send instead of call dot value Does not give the attacker enough gas to do damage with re-entrancy The attacker only gets 2300 gas With great power comes great responsibility And that applies to call dot value And so the tip is to use send and avoid call dot value Perhaps the most Mature best practice is to handle errors in raw calls Raw calls such as address dot send and address dot call Return false if they fail This is unlike invoking a do something method Which propagates an exception if it encounters one so the good example is to Check check the result and the bad example is an unchecked send a tip that goes together With using send is to keep fallback functions simple The last fallback function is advised against because one it uses more than 2300 gas Second it asks callers to break the tip of using send and Asks them to use the riskier call dot value a Call depth attack can be used by an attacker to make all of your contracts calls to fail The theme the ethereum virtual machine has what the yellow paper calls a contract a message call contract creation stack and it has a maximum depth of 1024 an attacker can make recursive calls to bring the depth to 1023 call your function Which brings the depth to 1024 and Now all of your contracts calls will fail In this example simple example an attacker can force a recipient to lose their refund So the attacker recurses to bring the depth to 1023 then calls withdraw refund using the address of a victim recipient and The depth is now at 1024 The refunds for the recipient will be set to zero this pointer doesn't work well to show that and When the victim calls withdraw refund that the send will fail and then when the victim calls Tries to withdraw their own refund the refund will already be set to zero. So they can't get it back As an improvement the return value of send could be checked However a preferred solution is to write this contract so that message sender will pull their refund as opposed to the insecure contracts approach of Pushing the refund to recipient This has had to be a quick presentation and there's plenty more information and examples such as pullover push Denial of service against contracts and re-entrancy that can be found in the repo in the wiki page to recap some of the main points for smart contract security are Prepare for failure roll out carefully Keep contracts simple and Calling untrusted contracts is always dangerous The danger may seem small But if an attacker finds and exploits a bug in a compiler That is targeting the EVM They are likely to do much more damage if their untrusted code is executed Then one where they only have a compiler bug to work with Here are the links to a security resource of the community by the community for the community. I Also have slides regarding denial of service and pullover push or can take two questions in the remaining Three minutes any questions? Okay, I'll I can quickly go through a couple more so so quickly in this a Denial of service against the contract. There are many ways that pitfalls that you can encounter them One is an unexpected throw, which is what this code example here is about but Hitting the block gas limit is another example Iterating through an unbounded arrays another example misunderstanding gas refunds will also cause the same issue So in this example contract the The line with the throw means that a current leader that refuses payment will permanently be the leader and The throw cannot be removed in this case because otherwise some other Person can do our call depth attack against bid and What that means is that they will get to be the current leader without having had to pay the previous leader so in this example you can't just remove throw and for the final Tip that we only have time for here is to change this into a pullover push system and so the left side is the Auction contract that was shown just a couple of slides ago This time instead of doing a send to the recipient. It just the contract just keeps track of the refunds that That are owed to whoever the highest bidder is and Then on the right side is the pull Method where everything works based off message sender and By doing this when an attacker can basically only attack themselves so That's it