[Applause]
you may as well just dive in because
there's a lot to to get through here so
today we're gonna be talking about the
dark parts of contract run time new
ability more specifically defending
against that I'm 0h thank you guys for
being here alright so here's the gist of
it deployed contract code is not
immutable here's the link to the repo
that's got all of the code that we're
going to go through today so you can
kind of review async or follow along so
we won't get too bogged down in like
working through it and fly it by mind a
lot to digest but that this will have
everything all right so here's we're
going to talk about today first
contracts can be destroyed and then
redeployed zombie contracts is another
sort of term for this secondly depending
on the way that you deploy them these
contracts can actually be redeployed
brand new runtime code third we're going
to discuss some techniques that you can
use to protect yourself against these
mutable contracts finally we'll explore
any ways that this is actually you can
build cool new stuff doing this if
you're willing to sort of Trailways
okay so just so we're all on the same
page go over some of the four teens
basically understand here
first off contact creation code is the
byte code that you feed into your
creating a contract whereas the runtime
code is what gets returned from the
creation code and will actually run when
you call the contract secondly we've got
contract storage which is a storehouse
load standard storage but then you've
also got runtime code from before which
in addition to running logic all of that
is where you're gonna hold the actual
like constants and your contracts in
that matter okay so the og original
method here is create or actually
deploying contracts that's what happens
when you're actually deploying at a
contract via transaction to the Bill
aggress uses the employers address and
the nonce to determine the address the
new kid on the block create two instead
of using the nonce of the the deployer
it's basing that address and poised to
off of the deployment address the salt
and the initialization contract creation
code okay self-destructs I'm sure you
guys are all familiar with this to
actually feature in my original
aetherium foundation hello world that
this was like seen as you do
your civic duty on the block chaining
cleaning up back to yourself and then of
course the parody multi-state hack and a
whole bunch of very sharp edge cases of
that most developers - just saying avoid
this like the plague I'm not most
developers there are a couple of cool
things you can do with it if you're
willing to take along a wild side but
always tread with caution when you're
using self-destructed one of those
things that self destruct can enable or
exploit is reliance so the gist of a
contract redeployment let's go over how
this sort of comes down to be if I try
an employee to an accountant that's
already got a contract this is a
scenario that in a creative only world
isn't going to happen without a hash
collision because the non-singer minute
every time but pretty to world if you
try to feed in those exact same
arguments it's just gonna fail right
there's already a contract there whether
or not there's code this is invalid but
when you self-destruct a contract what's
actually happening it's more than the
runtime code getting in there now the
entire thing is white you've got no nuts
no residual balance no it stinks
everything is going as far as the
blockchain is concerning this contract
it's never intestine so then once it's
already been wiped what happens when I
haven't went to me again well in that
case refine the contract can be deployed
no problem but if I was relying on this
estate or the dogs of whatever property
you know that contract before this you
got white and then look back well now
you're in trouble right so let's look at
an example of how this might work
and bear in mind that the code won't
actually even be changing this is just
an example greatly simplified like a
more realistic world use case would be
like this add X or a swap contract or
something like that but this is a
contract that we approve to transfer our
ship coins okay and initially it's in
testing mode so don't approve and it's a
testing mode because anyone can move
your your funds around but then we turn
the testing mode off but then the
contract can be destroyed retired and
once you reapply it it's back in testing
mode and into the fund stolen okay so
this is a problem and really low hanging
fruit if my series be careful with your
giving me approvals out you guys already
know that but let's look at that so
remediation to this which here's our
same coin mover contract and we've
stripped out the testing mode so you're
good you can approve this contract
you're gonna be the only one that's able
to call the transfer from that bit we're
all set we've fixed this problem
everyone you can rest easy except you
can't because if it was deployed via
some of these tricky methods then you're
you're backing the same problem where
they could deploy a contract vendors can
move your funds again and the phenomenon
here is it the phrasing I started using
for this particular type of redeployment
where you've got brand new code coming
in it is metamorphism there's enough
this also goes by like malleable
contracts this there's a few different
ways of describing this a metamorphic
contract is one that has
non-deterministic creation code so you
feed it the same
Dick's creation code that you're
sourcing but how you're going to derive
the runtime code from something other
than that creation code payload so
here's the basic rules of how this
happens first off you have to destroy
the existing contract you have to call
self-destruct on second you have to use
create - and the interesting thing about
this is it doesn't have to be deployed
directly from creating - because and
anywhere along the chain some contract
uses created - and then all those
intermediate contracts get destroyed
that you can redeploy all the way up
third the deployment address the
creation code and the salt can't change
because otherwise you're going to have a
new address and lastly once those three
rules are are adhered to anything is
fair game and is good so let's talk
about some of the main ways that this
would work first off a straightforward
way to do this is to go slow man under
contract so what I could do is I can
store the address that I want to clone
in contract storage and then my creation
code is going to go get that address and
clone the contract now this has some
limitations you can't use a constructor
sort of like with common upgradability
patterns you have to call into an
initializer another way to do it is
using what I call a transient deploy and
the transit deployer is going to use
this trick where it's going to rather
than getting if an address it's gonna go
get the actual creation code that wants
to deploy that it's gonna deploy its own
contract via create using that creation
code and create doesn't have the same
limitations on being you can change the
creation code all you want but then if
if the transient contract immediately
destroys itself after it's done so then
if you want to go back and redeploy
remember the nonce of that contract is
reset so create is going to hit the same
ad that's again this has the limitation
you want to do this there's two contract
appoints so there's some overhead but
it's a way to do it and more flexible
fashion and support constructors finally
my personal favorite pattern for this I
call the metamorphic delegator pattern
I'm going to what you do here is you can
actually take your target creation code
and you put it into the runtime code of
another contract then when you deploy
this metamorphic contract it's going to
delegate call into that that creation
code in runtime code contract and it'll
set up all the initialization stuff in
the constructor and then return your
target code which had been rights to my
time so first let's look at what a
cloner might look like this is a
standard non metamorphic loner where the
creation code changes this is just going
to take our target and put it on the
stack and then copy the code and this is
what a factory that spits out that clone
might look like as you can see our
creation code is gonna change so if we
try to clone a new address it's not
going to work so here's a metamorphic
version of that clone army and what this
is going to do is we store the address
you want to clone on the factory and
then this calls into the fall back on
the contract it deploys it does a static
column gets that address and then uses
that to copy the code
contract and this is what that might
look like it does simply fall back that
is just going to grab the target address
and storage and give it back so then you
can see here your reasonable never
changes but every time you call this as
long as we can destroy it an existing
clone we can keep adding upgrading to
new cloned contracts let's look at the
transient deployment this is a little
more involved but what we're basically
going to do here is we're going to call
in to the fallback same thing but we're
not going to add this we're getting the
creation code then we take that we don't
know the size of it ahead of time so
we're gonna use return data size when
turning data copy to put it into memory
and then we create now if this if it
reverts your bill and grab that revert
the reason and return it otherwise we're
gonna self-destruct this contract so
that we can do it again and then all we
got to do is self destruct this up
contract and redeploy so this one it
looks pretty similar to the last example
of a factory rather than storing an
address restoring a binary and the other
the other stuff of this that's important
is we have to we know what the nonce is
gonna be one on the transient deployer
so we can use that our LT encoding to
figure out what the address is
and we're pointing to alright and then
the blesses metamorphic delegator this
one is basically two steps step one is
that you need to insert that creation
code into the runtime code of another
contract this is what I called preload
or block of code you can insert in front
of whatever arbitrary runtime you want
to be
deploying and it will play it for you
you can also use like libraries and the
cool thing about this is you can do this
ahead of time
you can even reuse the same creation
code in runtime code blocks then once
you've got that that contract deployed
then here's a metamorphic delegator
payload here we're just gonna put a
bunch of zeros on the stack to use later
then we go and get the address from the
fallback the creation and runtime
address then we're going to delegate
call in to that address and either
bubble up the revert reason or return
the runtime code because we're in a
constructor by returning that code we
write it to storage
or to run times so here's the factory
for this it's basically going to take
our creation code and deploy a creation
and code in run time storage contract
once again this is something you could
do ahead of time and reuse if you wanted
to really choose select the efficiency
out of it and then we're gonna take it
and deploy our fix non-deterministic
byte code that goes graphs that address
and delegate causing so this obviously
if you want to go down this rabbit all
there's a lot to it if these are kind of
minimal examples where you can supply
your own salts you can do all kinds of
tricks so I put together a sort of
utility contract of homework that is it
uses this a metamorphic delegator
pattern but what it does in CNF T's but
you Clark addresses ahead of time and
then deploy or redeploy contracts to
those addresses and also sort of makes
the
Plumtree you're welcome to check it out
and also have you answer any questions
about it now
a hope this film might make you a bit
squeamish I know most the people I
explained this to it really goes against
the standard immutable principles of
what we're doing so let's talk about how
you can protect against this because the
truth is it's impossible so there's
three big things first off the best
protection you can provide is to make
sure the contract cannot be destroyed
it's not quite as simple it's like no
self-destruct opcodes because you can
also if there's delegate calls with call
codes those could trigger a
self-destruct in the context of your
contract and in this world where it's
upgradeable everything and proxy
everything this is actually a harder
guarantee to provide in many cases than
many of us would like what you can do
though if you can provide this guarantee
if you give your contracts to this this
registry indestructible buddy it'll scan
them and stamp them it's like this is
indestructible you're good so that's one
way you can protect another thing you
can do is you can ensure that the
contracts are being deployed and mutable
it's not just quite as simple as create
has to create all the way down to like
something that has never touched create
two because you can bubble them all up
or you know it's created by something
that is itself indestructible finally
you can go through beautiful create two
factories there is a example of one that
you can use
they to factory Dottie and other
contracts that do similar stuff and then
you basically just track once you've
used a particular assault and an info or
whatever and don't let your be the third
thing here is that you can check the run
time the Xcode hash into the contracts
that you want to interact with them make
sure they haven't changed at the injury
now this isn't going to protect against
a standard read employs the zombie
deploys it's only gonna protect against
a metamorphic contract so you so be
careful about steak and might get wiped
in between if something is destructible
and you can register just ahead of time
and use a registry like this one code
cache cache as an example and now if you
combine two and three you've covered
most of your bases if one bit is not
available and the biggest thing here is
educate people about this slate this
should be in the checklist during an
audit to make sure that just like can't
you have the right trust assumptions or
dealing with ownership you have the
trade trust assumptions when you're
doing their deployment methods if
they're susceptible to this all right
all your white hats can take breath for
the rest of us let's talk about some of
the cool things that you can do with
this technology so first off contract
deployments it's actually really cool to
be able to park an address ahead of time
and to find an address that's efficient
without needing to tie that into the
creation code so you use an address that
has lots of zero lights you can save
quite a bit of gas of servicing areas
also we can know the deployment address
of any of our contracts ahead of time so
you can deploy a whole family of
contracts that refer to each other as
constants and are interrelated and save
gas that way or just have coordinated
plays about having two buses trackers
all of the nonces appear
an address isn't a really granular way
finally if this makes it easy to deploy
different contracts that are slightly
different to the same addresses on local
test meds main nets other chains as long
as you're coming out of the same factory
its deployed across chance second run
time storage so there's a lot of talk
with a new assemble artwork that the
price of s low is going to quadruple so
you can use run time storage and certain
breathe heavy applications to make
storage a lot cheaper and also more
accessible so usually when you go
through contract storage you have to go
through again right and the contract is
dictating how that's gonna be read back
to you but if you're using run time
storage you're just copy whatever
portion or section of the data that's
relevant to you and so you can access
storage on your own terms it's like true
public storage in that regard and it's
also cheaper to do you can also by
transferring ownership over to accounts
that you can deploy to you can give
ownership of a region of storage in a
way that's really future proof right
it's not tied into any particular
implementation on your contract
finally it's economical as we were sort
of discussing you can save a lot on not
only reads which is like big savings but
also on initial storage rates especially
for larger payloads because in effect
you pay twenty thousand gasp a word if
you're storing on contract storage or as
you're only paying 6,400 a word for
every read time storage order plus the
overhead of the contract and you can
still do updates by using some kind of
system third smart walnuts so the theory
moxie doesn't have native transactions
script support it's just calling into
the contracts but what you can if you
use one of these Clark addresses as your
smart wallet you can deploy contracts
that will do throw out an arbitrary bark
byte code and then blow up and then you
can do that at na z to sort so sort of
having the transaction scripts behavior
it's also really secure because there's
no code to hack in between these
transactions it's happy to code so there
is not the same like risk at rest for
your fights and this leads to being able
to support really user friendly stuff
where you can do these complex actions
in a way that includes conditionals and
atomic operations and all of that and is
only one transaction from the
perspective of the user forth
you can't organize accounts this way so
in effect as long as I own the rights to
deploy a little ticular address and I
give that to you
I can reassign controller this stuff and
you're not tied in to any particular
smart wallet implementation or whatever
you can put whatever code you want there
once you want it's your account as long
as it can be destroyed so this way you
can create portfolios baskets of assets
that are to go beyond just like a
particular in the year see 20 years of
7.1 whatever it may be the ownership
reputation all of that because the
accounts is the ultimate abstraction for
doing that and it's a like a reliable
way to do as a future perfect manners so
that if you do need to make changes down
why you
whatever your tokenize accountants yeah
this is outfit like the this sort of new
use cases for this they're weird
but if we weren't willing to get weird
like what are we doing here this this is
a theory anyway right so I'll leave you
with a quote on the dark arts and maybe
a slight modification then I think it's
more applicable to less here and this
moves the talk thank you guys very much
I'll put up one more time
[Applause]
[Music]
so when you're accessing contract
storage there is an extra you have to go
not only to the contractor then you send
it into that patrician 3 as well so
there is an overhead on the machine
level they're doing it that way now is
it does it make sense that's like a
preferred storage method I don't know I
think that it might be an indication
that there's more work that needs to be
done to out and maybe a gas correction
and I think that's also important to
bear in mind with if you decide to use
one like exotic storage method over
another that you should basically
anticipate that things might change in
terms of gas pricing online and you
might be stuck with something that's
really esoteric and out there but as
long as couple that with good upgrade
ability and then it's maybe not so much
an answer yeah
to use like this transaction script type
functionality so your your right out of
the gates you're dealing with 32,000
gasp overhead for deployment then you
can deduct out the twenty four thousand
rebate it starts to make a lot more
sense as you get into more complex
operations and especially stuff it like
you couldn't go through another
another helper or something that would
do that matching for you but the big
thing is most like batch transaction
type things removal tool calls that
don't really have a strong ability to
hook into conditionals alike both based
on this I'm going to go do this other
thing on this other back this way you
can like the sky's the limit and there's
also the security consideration of the
KOAT action
yes probably what did you into code so
you don't change the deployer the salt
or the creation code but the creation
code is non-deterministic meaning it's
fixed creation code but during that
creation step rather than a standard
like solidity and employment that's
going to basically have the runtime code
and just copy that over
you're going to say oh instead I'm gonna
go ask this other contract for their
code that they have right now or some
variation
okay last question is the hands of the
premise contracting to destroy those who
destroy all you have to kind of move it
out
yes so whenever you're self-destructing
contracts are to be very careful with
balances token balances aren't good
because they live on the tokens right
that's not so much of a concern but if
you have either at the contract when
it's destroyed that your ether is burned
and not like Sentinel address its
annihilated your body isn't gone
so obviously self-destruct you specify a
recipient and it will immediately
forward the funds to them but if any
funds make their way back within that
same transaction the contract hasn't
been deleted until the end of the
transaction at which point it's only
been scheduled for donations it's
another limitation to this is that
you're limited to one redeployed per
transaction that's a pretty extreme case
that you would be doing multiple redo
poisoning in a single transaction but
that's something to be aware of so
there's like a slight additional delight
with fairness okay I'm happy to chat
Laura take some questions after this but
thank you guys for being here and go
teach people about this
[Applause]
you