-
Notifications
You must be signed in to change notification settings - Fork 4
16. Preservation
This contract utilizes a library to store two different times for two different timezones. The constructor creates two instances of the library for each time to be stored. The goal of this level is for you to claim ownership of the instance you are given.
-
Preservation
uses Libraries: Libraries usedelegatecall
s. [Level 6 -Delegation] taught us that usingdelegatecall
is risky as it allows the called contract to modify the storage of the calling contract. - Storage layouts of
Preservation
andLibraryContract
don't match: Calling the library won't modifiy the expectedstoredTime
variable.
Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their code is reused using the DELEGATECALL (CALLCODE until Homestead) feature of the EVM. This means that if library functions are called, their code is executed in the context of the calling contract, i.e.
this
points to the calling contract, and especially the storage from the calling contract can be accessed.
So Libraries are a particular case where functions are on purpose called with delegatecall
because preserving context is desired.
As libraries use delegatecall
, they can modify the storage of Preservation
.
LibraryContract
can modify the first slot (index 0) of Preservation
, which is address public timeZone1Library
. So we can "set" timeZone1Library
by calling setFirstTime(_timeStamp)
. The uint _timeStamp
passed will converted to an address
type though. It means we can cause setFirstTime()
to execute a delegatecall
from a library address different from the one defined at initialization. We need to define this malicious library so that its setTime
function modifies the slot where owner
is stored: slot of index 2.
If you intend to modify storage of the caller by using a library contract, make the slots of the caller contract are aligned with those of the library.