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
you