so yeah my name is Jake and we're gonna
talk about smart contracts and in
particular how to sort of detect what
ether scam calls internal transactions
this is notoriously hard sort of thing
to do and we've heard from lots of
people that it's challenging so I just
want to kind of present our experiences
with it issues we've seen and how to
sort of handle these safely and how to
prevent you from having similary sorts
of problems in the future like you said
I'm on the crypto currency team at
coinbase we're the team that runs our
blockchain integrations for all the
currencies hot wallet cold storage sends
receives we're hiring if that's
interesting to you just come talk to me
afterwards so yeah we started though and
so who should care about this stuff
these are kind of the primary three we
see here is like exchanges wallets and
explores the highest risk comes to
exchanges which we'll talk about but
really it matters for everybody
and anybody you know building on
aetherium and the reason is because if
you're sort of accepting deposits of any
sorts of aetherium there's different
ways that can happen and so your primary
responsibility is to take a transaction
and sort of turn that into a set of
debits and credits to accounts or to
update balances or whatever you're
trying to do here and so if we take a
transaction like this we're gonna go
here and you know inspect it and say
okay we should credit alice 1/8 and we
do that but the risk here is you know
what if that's not actually what
happened right what if we shouldn't have
credit as Alice's and there's some sort
of bug in our code this is what comes up
with contracts because it's not as
straightforward thing to do and there's
a lot of nuance to how to handle it and
so what this can lead to is a couple of
different things
invalid data is sort of the first one
here right just having bad data showing
a wrong account balance is you know not
ideal it's not the worst but it can lead
to pretty bad experiences if somebody
thinks they have 10 8th and they try and
send that and then it just consistently
fails they might switch to a different
wallet and if you have systems building
on top of this if it's some sort of API
and you have downstream customers then
they're gonna get bad data and they're
gonna have to update accordingly their
database and that's gonna be pretty
challenging and there's not really good
ways to handle that so you want to avoid
this sort of as much as you can and like
I said the real risk is actually two
exchanges here with lost funds because
what they can do is this type of attack
where you send in ether but you don't
really it just kind of looks like it you
can trick the system and then they can
sell that for some other currency and
it off somewhere else or they can you
know just send off ether and in
exchanges cases a lot of them have
pooled wallets so everybody's funds are
together so if you send in and you send
back out it's probably not going to be
the same ether it's gonna be something
different and so you can actually just
steal if you're in that way and continue
this until you know you're caught and so
if you have these types of mistakes this
is the types of headlines you might see
written about you it's it's not good if
you see hacker one reports like this you
also don't want to see these kinds of
things and this is what we sort of saw
at some point early in the year and yeah
you don't want that and so what can go
wrong here and like how do we fix it so
start that we need to talk about how
etherium moves so as I'm sure most of us
are familiar with everything happens in
a block then you have a set of
transactions and in those transactions
the theorem can move but within the
transaction it's not just one way you
sort of have two different types here
you've got what we can call account
transfers it's just a standard
transaction sending from one account to
another and you can also have this other
bucket here which is like contracts and
contract can do pretty clever things
which we'll talk about here but the
account transfer is like I said are
pretty straightforward this is what
you'll see on ether scan and this is
kind of what you'll get back from your
like note if you're just asking hey give
me a transaction it's gonna look a lot
like this and calculating you know how
much value went to where there's a from
there's a to all that's pretty easy to
do and there's not really much risk here
if it says the transaction happened in
this format it did and you're pretty
good to go
but where it gets complicated is
contract transfers they might look like
this so now instead of you know which is
sending to one user you can send to sort
of n amounts of accounts and it scales
up and there what's really sort of
difficult about these is that this is
custom code people write so they have a
lot of room outside of just what the
protocol allows to trick you and to
specifically target like issues in your
system and you know attack you because
of it and so there's not a great API for
this what you have to use this API
called the tracing API which is fairly
low-level and not that easy to parse and
it looks a bit like this you know you be
able to read it but it's pretty
complicated and this is actually a
simple one this is you know basically
one of those sends where I showed like
ten in the previous slide so it gets
more complicated there's a lot of nuance
here but if we started to think
about inspecting these and seeing what
it looks like if you zoom in you'll see
like there's a from and a gas in a too
similar to a transaction but if you were
to take it and just treat this as such
you've been for not a good time
and so we refuse examples of here
different types of problems that can
happen and and the right ways to sort of
handle this and so on this left side we
have what we're gonna call traces here
there's different types of calls and we
see one we send Alice one eath another
to Bob and if we just turn that into
credits and debits accordingly we would
do that and the issue here is like I
presented earlier it doesn't actually
happen that way in this transaction and
it's because we're missing something so
not everything's gonna be on the slides
here and we're gonna sort of bring those
in over time and so in this case what
you actually need to look at is this
thing called the transaction status
which we'll see here so this came with
an upgrade I believe last year I think
the Byzantium upgrade they added this
new opcode and they also added the
status to this thing called the
transaction receipt and so when a
transactions included in a block the
blockchain will generate this thing
called a receipt which tells you it's
similar like a store receipt it's just
you know here's the final state of what
happened and so if you didn't use all
the gas or it failed for some reason
that kind of information will be there
and so in this case we see it the
receipt is a failure and so what that
means is actually none of the transfers
that we might have that might have
happened if it didn't fail can actually
happen or didn't happen and so
accounting for that in this example we
see here that nobody received any and
we're good to go so for example - this
is the same sort of scenario here except
we do you see this thing that says fail
on one of these calls and I didn't
really describe the calls yet but a call
is this sort of it's this type of a
trace there's different a few different
types and so these sins are also calls
but these ones are other ones that may
just like call some function to you know
log something or it's that doesn't
actually transfer anything anywhere it's
just you know calling a contract and so
generally you might ignore these if you
just care about sort of your customers
information and so learning what we just
learned we do check the transaction
receipt status and we try and parse this
and we see it's a success
so we credit Alice and Bob
and if if you sort of caught on from the
previous example that didn't actually
happen but what's interesting about this
scenario is it's not that nobody
received any it's that only some did so
this transaction receipt status doesn't
tell you everything there's this
possibility of like a full failure where
the transaction receipt is a failure but
there's this partial failure states as
well and these can get more complicated
than this and so in this example what we
really needed to do when we're looking
at these traces its turned it into a
tree so it's actually if we can see this
like hierarchy here we have this call at
the root and then we have you know Alice
receives one and then a few nested calls
and then one of them is a failure and
what this looks like in the trace is
there's this thing called there's an
error on it and if it has an error that
means it failed and so when you put it
into this tree format you can see that
the sender Bob is actually within that
part of the tree and when it's there
what that means is that that doesn't
actually happen and you shouldn't create
any credits or debits and so accounting
for that we give Alice the 1/8 and we're
good to go so the last example here
looks entirely the same as the former
one so there's even more here to kind of
a look at and so in this example if we
did the same thing we credit Alice and
then that's wrong and in this time
nobody should receive anything and so
there's another thing missing here so
when we look at these calls there's
different types of calls there's not
just one there's all sorts of different
ones but in particular in this example
I'm using one called a delegate call so
we need to pick out the specific types
of calls that can actually transfer
theorem around and sort of either ignore
the other ones or treat them differently
and so in this case a delegate call
without going to sort of details of what
exactly it does it looks identical to
just sending aetherium somewhere except
it doesn't actually do that and so in
this example when we account for that we
do see that nothing happens so that was
a little bit like how to handle these
and it's a tricky thing and it could get
more complicated in the future that's
like it's a day but a lot of really
clever things are happening a lot of
cool stuff people want to work on and
it's really hard to get this right and
these things aren't that documented
either
and so we got to figure out a way that
even if we don't know the answer how do
we sort of make sure we're not exposing
ourselves to these issues because if
you've been at many of the talks today
so many of them are based around
contracts right identity and all sorts
of things are just contracts ending
everywhere and so you have to be able to
support these but many exchanges are
many wall to don't because of the
complexity around this and because of
the risk in particular to exchanges of
getting like hacked and actually losing
money and so the kind of answer here is
this type of sort of detection and
response and the first step of that is
just acknowledging that you don't know
everything
things are gonna change and especially
if you're working with multiple block
chains and multiple currencies that kind
of stuff it's just some of its going to
slip by some little note and release
notes of some upgrade of your software
is going to change something and you may
not realize it and so you just want to
take a step back and say you know I
might not know everything if you don't
well like how do you do this like how do
you make an answer here and so one way
to do this is sort of cross-check your
data right there's a lot of people
building there's a lot of people you can
talk to you about this but really if you
can automate this that's sort of the
ideal here if you can cross-check your
data and say oh well I think this
happened and then this other thing says
it doesn't and it's a source you trust
then maybe you shouldn't do that and so
what you should do there is actually
like fail securely so rather than
failing like open and letting some sort
of payment go through and you know
credit an account and allow that to be
hacked just set it aside like put it in
a queue alert somebody on your team they
can investigate it and see what's going
on and then they can determine if it's
actually a bug or if it's not and so
this is actually this is the kind of
stuff we've done now and it's actually
really helpful even outside of this like
since we've implemented we actually
haven't seen anything like this and but
what we have seen is just little things
being off here and there you know some
calculation of a balance is slightly
wrong or some type of send we didn't or
some type of receive we didn't support
and it's just like oh it's off and it's
like cool it's like it's alert just that
something's wrong and we get to go in
and fix it and figure out why and
improve our systems without ever
affecting any of our customers which is
even even better that you get alerted of
things that are wrong and just like oh
cool
I can fix that and so we'll kind of put
things in a take aways here and sort of
sum all this up so the first step is to
check the receipt status it's
it's easy to check there's api's for
this it's a boolean field you know it's
true false basically it's numbers but so
just check that and if it says it failed
then none of the transfers happened the
nuance here is like you do still pay for
the gas here like failed transactions
are still included in blocks because
somebody had to executed all the miners
and nodes you need to execute the
transaction to the failure to validate
it so it still costs like resources so
even though it failed you still need to
check it and they still do actually pay
the gas for it but but none of the
transfers and the second one here is to
parse the trace as the tree it's there's
information in the way the trace is
formatted and the trace is I sort of
showed here that I'm describing are
parodies death has the tracing API exist
to now but it's it's they're not the
same it's not a standardized thing and
so you need a reference sort of guests
documentation for how it works there I
imagine it's similar but you need to
take this flat list they provide you it
sort of structure it into some sort of
tree and then once you do that you can
inspect these sort of errored sub trees
and you like filter them out or mark
them failed or you know whatever you
want to do there thirdly we want to
reject these like delegate and call code
calls these are two different types of
ones that kind of look like they
transferring things in but they actually
don't and then if you if you kind of
take the the earlier point about failing
safely here what you really should do
here is actually just select the ones
you know do it so this is similar if
there's an upgrade you don't know about
if there's some sort of change at least
you know these ones work I didn't
mention these other ones but these are
like creatives for creating contracts
self destruct for destroying one and
rewards for like block awards these are
the kind of things that can you know
credit Ethan like other ways or like
send it and so you just if you select
those and handle those cases
appropriately you know you're sort of at
least reasonably safe and then if you
implement this next point don't trust
until verify it right verify your data
check with other sources you don't have
to like trust it completely but at least
it's sort of a signal that something's
wrong right don't just take that and
write it to your database like that's
the truth but what you should do is at
least look at it and you're like all
right something's weird here and also if
you're getting a lot of false positives
you know maybe you pick some other
source and yeah that's it for today so I
hope you all stay safe out there and
hope everybody we
something here and we've got I think
some time for questions about four
minutes so if you have any
you